mirror of
https://github.com/Maschell/hid_to_vpad.git
synced 2024-11-25 15:56:52 +01:00
Missing files
This commit is contained in:
parent
4893fc7c67
commit
e8bd4647eb
29
hidtopad.cbp
Normal file
29
hidtopad.cbp
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="hidtopad" />
|
||||
<Option pch_mode="2" />
|
||||
<Option compiler="ppc-gcc" />
|
||||
<Build>
|
||||
<Target title="build">
|
||||
<Option output="bin/Release/hidtopad" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output="obj/Release/" />
|
||||
<Option type="1" />
|
||||
<Option compiler="ppc-gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O2" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
</Compiler>
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
<envvars />
|
||||
<debugger />
|
||||
<lib_finder disable_auto="1" />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
71
src/common/common.h
Normal file
71
src/common/common.h
Normal file
@ -0,0 +1,71 @@
|
||||
#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"
|
||||
|
||||
/* Macros for libs */
|
||||
#define LIB_CORE_INIT 0
|
||||
#define LIB_NSYSNET 1
|
||||
#define LIB_GX2 2
|
||||
#define LIB_AOC 3
|
||||
#define LIB_AX 4
|
||||
#define LIB_FS 5
|
||||
#define LIB_OS 6
|
||||
#define LIB_PADSCORE 7
|
||||
#define LIB_SOCKET 8
|
||||
#define LIB_SYS 9
|
||||
#define LIB_VPAD 10
|
||||
#define LIB_NN_ACP 11
|
||||
#define LIB_SYSHID 12
|
||||
#define LIB_VPADBASE 13
|
||||
|
||||
// functions types
|
||||
#define STATIC_FUNCTION 0
|
||||
#define DYNAMIC_FUNCTION 1
|
||||
|
||||
// none dynamic libs
|
||||
#define LIB_LOADER 0x1001
|
||||
|
||||
#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
|
||||
|
||||
#define RESTORE_INSTR_MAGIC 0xC001C0DE
|
||||
#define RESTORE_INSTR_ADDR ((restore_instructions_t*)(MEM_BASE + 0x1600))
|
||||
|
||||
typedef struct _restore_instructions_t {
|
||||
unsigned int magic;
|
||||
unsigned int instr_count;
|
||||
struct {
|
||||
unsigned int addr;
|
||||
unsigned int instr;
|
||||
} data[0];
|
||||
} restore_instructions_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* COMMON_H */
|
||||
|
67
src/common/fs_defs.h
Normal file
67
src/common/fs_defs.h
Normal file
@ -0,0 +1,67 @@
|
||||
#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_STATUS_OK 0
|
||||
#define FS_STATUS_EXISTS -5
|
||||
#define FS_STATUS_STORAGE_FULL -12
|
||||
#define FS_STATUS_JOURNAL_FULL -13
|
||||
|
||||
#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 */
|
||||
|
135
src/common/kernel_defs.h
Normal file
135
src/common/kernel_defs.h
Normal file
@ -0,0 +1,135 @@
|
||||
#ifndef __KERNEL_DEFS_H_
|
||||
#define __KERNEL_DEFS_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "fs_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// original structure in the kernel that is originally 0x1270 long
|
||||
typedef struct
|
||||
{
|
||||
uint32_t version_cos_xml; // version tag from cos.xml
|
||||
uint64_t os_version; // os_version from app.xml
|
||||
uint64_t title_id; // title_id tag from app.xml
|
||||
uint32_t app_type; // app_type tag from app.xml
|
||||
uint32_t cmdFlags; // unknown tag as it is always 0 (might be cmdFlags from cos.xml but i am not sure)
|
||||
char rpx_name[0x1000]; // rpx name from cos.xml
|
||||
uint32_t unknown2; // 0x050B8304 in mii maker and system menu (looks a bit like permissions complex that got masked!?)
|
||||
uint32_t unknown3[63]; // those were all zeros, but its probably connected with unknown2
|
||||
uint32_t max_size; // max_size in cos.xml which defines the maximum amount of memory reserved for the app
|
||||
uint32_t avail_size; // avail_size or codegen_size in cos.xml (seems to mostly be 0?)
|
||||
uint32_t codegen_size; // codegen_size or avail_size in cos.xml (seems to mostly be 0?)
|
||||
uint32_t codegen_core; // codegen_core in cos.xml (seems to mostly be 1?)
|
||||
uint32_t max_codesize; // max_codesize in cos.xml
|
||||
uint32_t overlay_arena; // overlay_arena in cos.xml
|
||||
uint32_t unknown4[59]; // all zeros it seems
|
||||
uint32_t default_stack0_size; // not sure because always 0 but very likely
|
||||
uint32_t default_stack1_size; // not sure because always 0 but very likely
|
||||
uint32_t default_stack2_size; // not sure because always 0 but very likely
|
||||
uint32_t default_redzone0_size; // not sure because always 0 but very likely
|
||||
uint32_t default_redzone1_size; // not sure because always 0 but very likely
|
||||
uint32_t default_redzone2_size; // not sure because always 0 but very likely
|
||||
uint32_t exception_stack0_size; // from cos.xml, 0x1000 on mii maker
|
||||
uint32_t exception_stack1_size; // from cos.xml, 0x1000 on mii maker
|
||||
uint32_t exception_stack2_size; // from cos.xml, 0x1000 on mii maker
|
||||
uint32_t sdk_version; // from app.xml, 20909 (0x51AD) on mii maker
|
||||
uint32_t title_version; // from app.xml, 0x32 on mii maker
|
||||
/*
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// the next part might be changing from title to title?! I don't think its important but nice to know maybe....
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
char mlc[4]; // string "mlc" on mii maker and sysmenu
|
||||
uint32_t unknown5[7]; // all zeros on mii maker and sysmenu
|
||||
uint32_t unknown6_one; // 0x01 on mii maker and sysmenu
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
char ACP[4]; // string "ACP" on mii maker and sysmenu
|
||||
uint32_t unknown7[15]; // all zeros on mii maker and sysmenu
|
||||
uint32_t unknown8_5; // 0x05 on mii maker and sysmenu
|
||||
uint32_t unknown9_zero; // 0x00 on mii maker and sysmenu
|
||||
uint32_t unknown10_ptr; // 0xFF23DD0C pointer on mii maker and sysmenu
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
char UVD[4]; // string "UVD" on mii maker and sysmenu
|
||||
uint32_t unknown11[15]; // all zeros on mii maker and sysmenu
|
||||
uint32_t unknown12_5; // 0x05 on mii maker and sysmenu
|
||||
uint32_t unknown13_zero; // 0x00 on mii maker and sysmenu
|
||||
uint32_t unknown14_ptr; // 0xFF23EFC8 pointer on mii maker and sysmenu
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
char SND[4]; // string "SND" on mii maker and sysmenu
|
||||
uint32_t unknown15[15]; // all zeros on mii maker and sysmenu
|
||||
uint32_t unknown16_5; // 0x05 on mii maker and sysmenu
|
||||
uint32_t unknown17_zero; // 0x00 on mii maker and sysmenu
|
||||
uint32_t unknown18_ptr; // 0xFF23F014 pointer on mii maker and sysmenu
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
uint32_t unknown19; // 0x02 on miimaker, 0x0F on system menu
|
||||
*/
|
||||
// after that only zeros follow
|
||||
} __attribute__((packed)) CosAppXmlInfo;
|
||||
|
||||
|
||||
// original structure in the kernel that is originally 0x1270 long
|
||||
typedef struct
|
||||
{
|
||||
uint64_t title_id; // title_id tag from app.xml
|
||||
uint64_t unknown1;
|
||||
uint64_t osversion;
|
||||
uint64_t unknown2;
|
||||
uint64_t common_save_size;
|
||||
uint64_t account_save_size;
|
||||
uint64_t unknown4;
|
||||
uint64_t unknown5;
|
||||
uint64_t unknown6; // companycode?
|
||||
uint64_t unknown7;
|
||||
char unknown8[6];
|
||||
char product_code[22];
|
||||
char unknown9[44];
|
||||
char content_platform[3];
|
||||
} __attribute__((packed)) MetaXmlInfo;
|
||||
|
||||
// Our own cos/app.xml struct which uses only uses as much memory as really needed, since many things are just zeros in the above structure
|
||||
// This structure is only 0x64 bytes long + RPX name length (dynamic up to 0x1000 theoretically)
|
||||
typedef struct
|
||||
{
|
||||
uint32_t version_cos_xml; // version tag from cos.xml
|
||||
uint64_t os_version; // os_version from app.xml
|
||||
uint64_t title_id; // title_id tag from app.xml
|
||||
uint32_t app_type; // app_type tag from app.xml
|
||||
uint32_t cmdFlags; // unknown tag as it is always 0 (might be cmdFlags from cos.xml but i am not sure)
|
||||
uint32_t max_size; // max_size in cos.xml which defines the maximum amount of memory reserved for the app
|
||||
uint32_t avail_size; // avail_size or codegen_size in cos.xml (seems to mostly be 0?)
|
||||
uint32_t codegen_size; // codegen_size or avail_size in cos.xml (seems to mostly be 0?)
|
||||
uint32_t codegen_core; // codegen_core in cos.xml (seems to mostly be 1?)
|
||||
uint32_t max_codesize; // max_codesize in cos.xml
|
||||
uint32_t overlay_arena; // overlay_arena in cos.xml
|
||||
uint32_t default_stack0_size; // not sure because always 0 but very likely
|
||||
uint32_t default_stack1_size; // not sure because always 0 but very likely
|
||||
uint32_t default_stack2_size; // not sure because always 0 but very likely
|
||||
uint32_t default_redzone0_size; // not sure because always 0 but very likely
|
||||
uint32_t default_redzone1_size; // not sure because always 0 but very likely
|
||||
uint32_t default_redzone2_size; // not sure because always 0 but very likely
|
||||
uint32_t exception_stack0_size; // from cos.xml, 0x1000 on mii maker
|
||||
uint32_t exception_stack1_size; // from cos.xml, 0x1000 on mii maker
|
||||
uint32_t exception_stack2_size; // from cos.xml, 0x1000 on mii maker
|
||||
uint32_t sdk_version; // from app.xml, 20909 (0x51AD) on mii maker
|
||||
uint32_t title_version; // from app.xml, 0x32 on mii maker
|
||||
char rpx_name[FS_MAX_ENTNAME_SIZE]; // rpx name from cos.xml, length 256 as it can't get bigger from FS anyway
|
||||
} __attribute__((packed)) ReducedCosAppXmlInfo;
|
||||
|
||||
typedef struct _bat_t
|
||||
{
|
||||
u32 h;
|
||||
u32 l;
|
||||
} bat_t;
|
||||
|
||||
typedef struct _bat_table_t
|
||||
{
|
||||
bat_t bat[8];
|
||||
} bat_table_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __KERNEL_DEFS_H_
|
40
src/common/loader_defs.h
Normal file
40
src/common/loader_defs.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef __LOADER_DEFS_H_
|
||||
#define __LOADER_DEFS_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// struct holding the globals of the loader (there are actually more but we don't need others)
|
||||
typedef struct _loader_globals_t
|
||||
{
|
||||
int sgIsLoadingBuffer;
|
||||
int sgFileType;
|
||||
int sgProcId;
|
||||
int sgGotBytes;
|
||||
int sgFileOffset;
|
||||
int sgBufferNumber;
|
||||
int sgBounceError;
|
||||
char sgLoadName[0x1000];
|
||||
} __attribute__((packed)) loader_globals_t;
|
||||
|
||||
typedef struct _loader_globals_550_t
|
||||
{
|
||||
int sgFinishedLoadingBuffer;
|
||||
int sgFileType;
|
||||
int sgProcId;
|
||||
int sgGotBytes;
|
||||
int sgTotalBytes;
|
||||
int sgFileOffset;
|
||||
int sgBufferNumber;
|
||||
int sgBounceError;
|
||||
char sgLoadName[0x1000];
|
||||
} __attribute__((packed)) loader_globals_550_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LOADER_DEFS_H_
|
25
src/common/os_defs.h
Normal file
25
src/common/os_defs.h
Normal 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
7
src/common/types.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#include <gctypes.h>
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
1
src/controller_patcher
Submodule
1
src/controller_patcher
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c1a02aa7c7a3a9031f9170ac284e15c9dd8df603
|
1
src/dynamic_libs
Submodule
1
src/dynamic_libs
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 1fcfb43f395c248aa45bb909012fbecbbbb2df2a
|
14
src/entry.c
Normal file
14
src/entry.c
Normal 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
182
src/fs/fs_utils.c
Normal 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
23
src/fs/fs_utils.h
Normal 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
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
38
src/fs/sd_fat_devoptab.h
Normal 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_
|
1729
src/game/memory_area_table.c
Normal file
1729
src/game/memory_area_table.c
Normal file
File diff suppressed because it is too large
Load Diff
40
src/game/memory_area_table.h
Normal file
40
src/game/memory_area_table.h
Normal file
@ -0,0 +1,40 @@
|
||||
/****************************************************************************
|
||||
* 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_AREA_TABLE_H_
|
||||
#define _MEMORY_AREA_TABLE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Struct used to organize empty memory areas */
|
||||
typedef struct _s_mem_area
|
||||
{
|
||||
unsigned int address;
|
||||
unsigned int size;
|
||||
struct _s_mem_area* next;
|
||||
} s_mem_area;
|
||||
|
||||
void memoryInitAreaTable();
|
||||
s_mem_area * memoryGetAreaTable(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _MEMORY_AREA_TABLE_H_
|
210
src/game/rpx_rpl_table.c
Normal file
210
src/game/rpx_rpl_table.c
Normal file
@ -0,0 +1,210 @@
|
||||
#include <string.h>
|
||||
#include "rpx_rpl_table.h"
|
||||
#include "kernel/kernel_functions.h"
|
||||
#include "common/common.h"
|
||||
|
||||
//! static container holding our retain data
|
||||
static unsigned char ucRpxData[0xffff];
|
||||
static int iRpxRplCount = 0;
|
||||
|
||||
void rpxRplTableInit(void)
|
||||
{
|
||||
s_rpx_rpl *pRpxData = (s_rpx_rpl*)ucRpxData;
|
||||
//! initialize the RPL/RPX table first entry to zero + 1 byte for name zero termination
|
||||
//! just in case no RPL/RPX are found, though it wont boot then anyway
|
||||
memset(pRpxData, 0, sizeof(s_rpx_rpl) + 1);
|
||||
iRpxRplCount = 0;
|
||||
}
|
||||
|
||||
s_rpx_rpl * rpxRplTableAddEntry(const char *name, int offset, int size, int is_rpx, int entry_index, s_mem_area* area)
|
||||
{
|
||||
// fill rpx/rpl entry
|
||||
s_rpx_rpl * rpx_rpl_data = (s_rpx_rpl *)(ucRpxData);
|
||||
// get to last entry
|
||||
while(rpx_rpl_data->next) {
|
||||
rpx_rpl_data = rpx_rpl_data->next;
|
||||
}
|
||||
|
||||
// setup next entry on the previous one (only if it is not the first entry)
|
||||
if(entry_index > 0) {
|
||||
rpx_rpl_data->next = (s_rpx_rpl *)( ((u32)rpx_rpl_data) + sizeof(s_rpx_rpl) + strlen(rpx_rpl_data->name) + 1 );
|
||||
rpx_rpl_data = rpx_rpl_data->next;
|
||||
}
|
||||
|
||||
// setup current entry
|
||||
rpx_rpl_data->area = area;
|
||||
rpx_rpl_data->size = size;
|
||||
rpx_rpl_data->offset = offset;
|
||||
rpx_rpl_data->is_rpx = is_rpx;
|
||||
rpx_rpl_data->next = 0;
|
||||
strcpy(rpx_rpl_data->name, name);
|
||||
|
||||
iRpxRplCount++;
|
||||
|
||||
return rpx_rpl_data;
|
||||
}
|
||||
|
||||
s_rpx_rpl* rpxRplTableGet(void)
|
||||
{
|
||||
return (s_rpx_rpl*)ucRpxData;
|
||||
}
|
||||
|
||||
int rpxRplTableGetCount(void)
|
||||
{
|
||||
return iRpxRplCount;
|
||||
}
|
||||
|
||||
s_mem_area *rpxRplTableGetNextFreeMemArea(u32 * mem_area_addr_start, u32 * mem_area_addr_end, u32 * mem_area_offset)
|
||||
{
|
||||
s_mem_area * mem_area = memoryGetAreaTable();
|
||||
s_rpx_rpl *rpl_struct = rpxRplTableGet();
|
||||
while(rpl_struct != 0)
|
||||
{
|
||||
// check if this entry was loaded into memory
|
||||
if(rpl_struct->size == 0) {
|
||||
// see if we find entries behind this one that was pre-loaded
|
||||
rpl_struct = rpl_struct->next;
|
||||
// entry was not loaded into memory -> skip it
|
||||
continue;
|
||||
}
|
||||
|
||||
// this entry has been loaded to memory, remember it's area
|
||||
mem_area = rpl_struct->area;
|
||||
|
||||
int rpl_size = rpl_struct->size;
|
||||
int rpl_offset = rpl_struct->offset;
|
||||
// find the end of the entry and switch between areas if needed
|
||||
while(mem_area && (u32)(rpl_offset + rpl_size) >= mem_area->size)
|
||||
{
|
||||
rpl_size -= mem_area->size - rpl_offset;
|
||||
rpl_offset = 0;
|
||||
mem_area = mem_area->next;
|
||||
}
|
||||
|
||||
if(!mem_area)
|
||||
return NULL;
|
||||
|
||||
// set new start, end and memory area offset
|
||||
*mem_area_addr_start = mem_area->address;
|
||||
*mem_area_addr_end = mem_area->address + mem_area->size;
|
||||
*mem_area_offset = rpl_offset + rpl_size;
|
||||
|
||||
// see if we find entries behind this one that was pre-loaded
|
||||
rpl_struct = rpl_struct->next;
|
||||
}
|
||||
return mem_area;
|
||||
}
|
||||
|
||||
int rpxRplCopyDataToMem(s_rpx_rpl *rpx_rpl_struct, u32 fileOffset, const u8 *data, u32 dataSize)
|
||||
{
|
||||
s_mem_area *mem_area = rpx_rpl_struct->area;
|
||||
u32 mem_area_addr_start = mem_area->address;
|
||||
u32 mem_area_addr_end = mem_area_addr_start + mem_area->size;
|
||||
u32 mem_area_offset = rpx_rpl_struct->offset;
|
||||
|
||||
// add to offset
|
||||
mem_area_offset += fileOffset;
|
||||
|
||||
// skip position to the end of the fill
|
||||
while ((mem_area_addr_start + mem_area_offset) >= mem_area_addr_end) // TODO: maybe >, not >=
|
||||
{
|
||||
// subtract what was in the offset left from last memory block
|
||||
mem_area_offset = (mem_area_addr_start + mem_area_offset) - mem_area_addr_end;
|
||||
mem_area = mem_area->next;
|
||||
if(!mem_area)
|
||||
return 0;
|
||||
|
||||
mem_area_addr_start = mem_area->address;
|
||||
mem_area_addr_end = mem_area_addr_start + mem_area->size;
|
||||
}
|
||||
|
||||
// copy to memory
|
||||
u32 copiedBytes = 0;
|
||||
while(copiedBytes < dataSize)
|
||||
{
|
||||
u32 blockSize = dataSize - copiedBytes;
|
||||
u32 mem_area_addr_dest = mem_area_addr_start + mem_area_offset;
|
||||
|
||||
if((mem_area_addr_dest + blockSize) > mem_area_addr_end)
|
||||
blockSize = mem_area_addr_end - mem_area_addr_dest;
|
||||
|
||||
if(blockSize == 0)
|
||||
{
|
||||
// Set next memory area
|
||||
mem_area = mem_area->next;
|
||||
if(!mem_area)
|
||||
return 0;
|
||||
|
||||
mem_area_addr_start = mem_area->address;
|
||||
mem_area_addr_end = mem_area->address + mem_area->size;
|
||||
mem_area_offset = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
SC0x25_KernelCopyData(mem_area_addr_dest, (u32)&data[copiedBytes], blockSize);
|
||||
mem_area_offset += blockSize;
|
||||
copiedBytes += blockSize;
|
||||
}
|
||||
|
||||
return copiedBytes;
|
||||
}
|
||||
|
||||
int rpxRplCopyDataFromMem(s_rpx_rpl *rpx_rpl_struct, u32 fileOffset, u8 *data, u32 dataSize)
|
||||
{
|
||||
s_mem_area *mem_area = rpx_rpl_struct->area;
|
||||
u32 mem_area_addr_start = mem_area->address;
|
||||
u32 mem_area_addr_end = mem_area_addr_start + mem_area->size;
|
||||
u32 mem_area_offset = rpx_rpl_struct->offset;
|
||||
|
||||
if(fileOffset > rpx_rpl_struct->size)
|
||||
return 0;
|
||||
|
||||
if((fileOffset + dataSize) > rpx_rpl_struct->size)
|
||||
dataSize = rpx_rpl_struct->size - fileOffset;
|
||||
|
||||
// add to offset
|
||||
mem_area_offset += fileOffset;
|
||||
|
||||
// skip position to the end of the fill
|
||||
while ((mem_area_addr_start + mem_area_offset) >= mem_area_addr_end) // TODO: maybe >, not >=
|
||||
{
|
||||
// subtract what was in the offset left from last memory block
|
||||
mem_area_offset = (mem_area_addr_start + mem_area_offset) - mem_area_addr_end;
|
||||
mem_area = mem_area->next;
|
||||
if(!mem_area)
|
||||
return 0;
|
||||
|
||||
mem_area_addr_start = mem_area->address;
|
||||
mem_area_addr_end = mem_area_addr_start + mem_area->size;
|
||||
}
|
||||
|
||||
// copy to memory
|
||||
u32 copiedBytes = 0;
|
||||
while(copiedBytes < dataSize)
|
||||
{
|
||||
u32 blockSize = dataSize - copiedBytes;
|
||||
u32 mem_area_addr_dest = mem_area_addr_start + mem_area_offset;
|
||||
|
||||
if((mem_area_addr_dest + blockSize) > mem_area_addr_end)
|
||||
blockSize = mem_area_addr_end - mem_area_addr_dest;
|
||||
|
||||
if(blockSize == 0)
|
||||
{
|
||||
// Set next memory area
|
||||
mem_area = mem_area->next;
|
||||
if(!mem_area)
|
||||
return 0;
|
||||
|
||||
mem_area_addr_start = mem_area->address;
|
||||
mem_area_addr_end = mem_area->address + mem_area->size;
|
||||
mem_area_offset = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
SC0x25_KernelCopyData((u32)&data[copiedBytes], mem_area_addr_dest, blockSize);
|
||||
mem_area_offset += blockSize;
|
||||
copiedBytes += blockSize;
|
||||
}
|
||||
|
||||
return copiedBytes;
|
||||
}
|
37
src/game/rpx_rpl_table.h
Normal file
37
src/game/rpx_rpl_table.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef __RPX_ARRAY_H_
|
||||
#define __RPX_ARRAY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <gctypes.h>
|
||||
#include "common/common.h"
|
||||
#include "memory_area_table.h"
|
||||
|
||||
/* Struct used to organize rpx/rpl data in memory */
|
||||
typedef struct _s_rpx_rpl
|
||||
{
|
||||
struct _s_rpx_rpl* next;
|
||||
s_mem_area* area;
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
unsigned char is_rpx;
|
||||
char name[0];
|
||||
} s_rpx_rpl;
|
||||
|
||||
void rpxRplTableInit(void);
|
||||
s_rpx_rpl* rpxRplTableAddEntry(const char *name, int offset, int size, int is_rpx, int entry_index, s_mem_area* area);
|
||||
s_rpx_rpl* rpxRplTableGet(void);
|
||||
int rpxRplTableGetCount(void);
|
||||
|
||||
s_mem_area *rpxRplTableGetNextFreeMemArea(u32 * mem_area_addr_start, u32 * mem_area_addr_end, u32 * mem_area_offset);
|
||||
int rpxRplCopyDataToMem(s_rpx_rpl *rpx_rpl_struct, u32 fileOffset, const u8 *data, u32 dataSize);
|
||||
int rpxRplCopyDataFromMem(s_rpx_rpl *rpx_rpl_struct, u32 fileOffset, u8 *data, u32 dataSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
94
src/kernel/kernel_functions.c
Normal file
94
src/kernel/kernel_functions.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include <string.h>
|
||||
#include "common/common.h"
|
||||
#include "common/kernel_defs.h"
|
||||
#include "kernel/kernel_functions.h"
|
||||
#include "kernel/syscalls.h"
|
||||
#include "start.h"
|
||||
|
||||
/* our retain data */
|
||||
ReducedCosAppXmlInfo cosAppXmlInfoStruct __attribute__((section(".data")));
|
||||
/*
|
||||
* This function is a kernel hook function. It is called directly from kernel code at position 0xFFF18558.
|
||||
*/
|
||||
void my_PrepareTitle(CosAppXmlInfo *xmlKernelInfo)
|
||||
{
|
||||
/**
|
||||
* DBAT for access to our data region is setup at this point for the 0xC0000000 area.
|
||||
*/
|
||||
|
||||
//! Copy all data from the XML info
|
||||
strncpy(cosAppXmlInfoStruct.rpx_name, xmlKernelInfo->rpx_name, FS_MAX_ENTNAME_SIZE);
|
||||
|
||||
cosAppXmlInfoStruct.version_cos_xml = xmlKernelInfo->version_cos_xml;
|
||||
cosAppXmlInfoStruct.os_version = xmlKernelInfo->os_version;
|
||||
cosAppXmlInfoStruct.title_id = xmlKernelInfo->title_id;
|
||||
cosAppXmlInfoStruct.app_type = xmlKernelInfo->app_type;
|
||||
cosAppXmlInfoStruct.cmdFlags = xmlKernelInfo->cmdFlags;
|
||||
cosAppXmlInfoStruct.max_size = xmlKernelInfo->max_size;
|
||||
cosAppXmlInfoStruct.avail_size = xmlKernelInfo->avail_size;
|
||||
cosAppXmlInfoStruct.codegen_size = xmlKernelInfo->codegen_size;
|
||||
cosAppXmlInfoStruct.codegen_core = xmlKernelInfo->codegen_core;
|
||||
cosAppXmlInfoStruct.max_codesize = xmlKernelInfo->max_codesize;
|
||||
cosAppXmlInfoStruct.overlay_arena = xmlKernelInfo->overlay_arena;
|
||||
cosAppXmlInfoStruct.default_stack0_size = xmlKernelInfo->default_stack0_size;
|
||||
cosAppXmlInfoStruct.default_stack1_size = xmlKernelInfo->default_stack1_size;
|
||||
cosAppXmlInfoStruct.default_stack2_size = xmlKernelInfo->default_stack2_size;
|
||||
cosAppXmlInfoStruct.default_redzone0_size = xmlKernelInfo->default_redzone0_size;
|
||||
cosAppXmlInfoStruct.default_redzone1_size = xmlKernelInfo->default_redzone1_size;
|
||||
cosAppXmlInfoStruct.default_redzone2_size = xmlKernelInfo->default_redzone2_size;
|
||||
cosAppXmlInfoStruct.exception_stack0_size = xmlKernelInfo->exception_stack0_size;
|
||||
cosAppXmlInfoStruct.exception_stack1_size = xmlKernelInfo->exception_stack1_size;
|
||||
cosAppXmlInfoStruct.exception_stack2_size = xmlKernelInfo->exception_stack2_size;
|
||||
cosAppXmlInfoStruct.sdk_version = xmlKernelInfo->sdk_version;
|
||||
cosAppXmlInfoStruct.title_version = xmlKernelInfo->title_version;
|
||||
|
||||
// on title switch reset the dumper
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SetupKernelCallback(void)
|
||||
{
|
||||
KernelSetupSyscalls();
|
||||
}
|
||||
|
||||
void KernelSetDBATs(bat_table_t * table)
|
||||
{
|
||||
KernelSetDBATsInternal(table,0xC0001FFF,0x30000012);
|
||||
}
|
||||
|
||||
/* physical_address is the physical address*/
|
||||
void KernelSetDBATsForDynamicFuction(bat_table_t * table, unsigned int physical_address)
|
||||
{
|
||||
KernelSetDBATsInternal(table,(physical_address & 0xFFFC0000) | 0x0F,(physical_address & 0xFFFC0000) | 0x32);
|
||||
}
|
||||
|
||||
void KernelSetDBATsInternal(bat_table_t * table, unsigned int high_address, unsigned int low_address)
|
||||
{
|
||||
SC0x36_KernelReadDBATs(table);
|
||||
bat_table_t bat_table_copy = *table;
|
||||
|
||||
// try to use a free slot
|
||||
int iUse;
|
||||
for(iUse = 0; iUse < 7; iUse++)
|
||||
{
|
||||
// skip position 5 as it is our main DBAT for our code data
|
||||
if(iUse == 5)
|
||||
continue;
|
||||
|
||||
if(bat_table_copy.bat[iUse].h == 0 || bat_table_copy.bat[iUse].l == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bat_table_copy.bat[iUse].h = high_address;
|
||||
bat_table_copy.bat[iUse].l = low_address;
|
||||
|
||||
SC0x37_KernelWriteDBATs(&bat_table_copy);
|
||||
}
|
||||
|
||||
|
||||
void KernelRestoreDBATs(bat_table_t * table)
|
||||
{
|
||||
SC0x37_KernelWriteDBATs(table);
|
||||
}
|
24
src/kernel/kernel_functions.h
Normal file
24
src/kernel/kernel_functions.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef __KERNEL_FUNCTIONS_H_
|
||||
#define __KERNEL_FUNCTIONS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "common/kernel_defs.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
extern ReducedCosAppXmlInfo cosAppXmlInfoStruct;
|
||||
|
||||
void SetupKernelCallback(void);
|
||||
|
||||
void KernelRestoreDBATs(bat_table_t * table);
|
||||
void KernelSetDBATs(bat_table_t * table);
|
||||
void KernelSetDBATsForDynamicFuction(bat_table_t * table, unsigned int physical_address);
|
||||
void KernelSetDBATsInternal(bat_table_t * table, unsigned int high_address, unsigned int low_address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __KERNEL_FUNCTIONS_H_
|
135
src/kernel/kernel_hooks.S
Normal file
135
src/kernel/kernel_hooks.S
Normal file
@ -0,0 +1,135 @@
|
||||
# This stuff may need a change in different kernel versions
|
||||
# This is only needed when launched directly through browser and not SD card.
|
||||
|
||||
.section ".kernel_code"
|
||||
.globl SaveAndResetDataBATs_And_SRs_hook
|
||||
SaveAndResetDataBATs_And_SRs_hook:
|
||||
# setup CTR to the position we need to return to
|
||||
mflr r5
|
||||
mtctr r5
|
||||
# set link register to its original value
|
||||
mtlr r7
|
||||
# setup us a nice DBAT for our code data with same region as our code
|
||||
mfspr r5, 560
|
||||
mtspr 570, r5
|
||||
mfspr r5, 561
|
||||
mtspr 571, r5
|
||||
# restore the original kernel instructions that we replaced
|
||||
lwz r5, 0x34(r3)
|
||||
lwz r6, 0x38(r3)
|
||||
lwz r7, 0x3C(r3)
|
||||
lwz r8, 0x40(r3)
|
||||
lwz r9, 0x44(r3)
|
||||
lwz r10, 0x48(r3)
|
||||
lwz r11, 0x4C(r3)
|
||||
lwz r3, 0x50(r3)
|
||||
isync
|
||||
mtsr 7, r5
|
||||
# jump back to the position in kernel after our patch (from LR)
|
||||
bctr
|
||||
|
||||
.extern my_PrepareTitle
|
||||
.globl my_PrepareTitle_hook
|
||||
my_PrepareTitle_hook:
|
||||
# store all registers on stack to avoid issues with the call to C functions
|
||||
stwu r1, -0x90(r1)
|
||||
# registers for our own usage
|
||||
# only need r31 and rest is from tests before, just leaving it for later tests
|
||||
stw r28, 0x20(r1)
|
||||
stw r29, 0x24(r1)
|
||||
stw r30, 0x28(r1)
|
||||
stw r31, 0x2C(r1)
|
||||
|
||||
stw r3, 0x30(r1)
|
||||
stw r4, 0x34(r1)
|
||||
stw r5, 0x38(r1)
|
||||
stw r6, 0x3C(r1)
|
||||
stw r7, 0x40(r1)
|
||||
stw r8, 0x44(r1)
|
||||
stw r9, 0x48(r1)
|
||||
stw r10, 0x4C(r1)
|
||||
stw r11, 0x50(r1)
|
||||
stw r12, 0x54(r1)
|
||||
stw r13, 0x58(r1)
|
||||
stw r14, 0x5C(r1)
|
||||
stw r15, 0x60(r1)
|
||||
stw r16, 0x64(r1)
|
||||
stw r17, 0x68(r1)
|
||||
stw r18, 0x6C(r1)
|
||||
stw r19, 0x70(r1)
|
||||
stw r20, 0x74(r1)
|
||||
stw r21, 0x78(r1)
|
||||
stw r22, 0x7C(r1)
|
||||
|
||||
# save original DBAT registers
|
||||
mfdbatu r28, 0
|
||||
mfdbatl r29, 0
|
||||
|
||||
# setup access to our data memory range
|
||||
lis r3, 0xC000
|
||||
ori r3, r3, 0x1FFF
|
||||
mtdbatu 0, r3
|
||||
lis r3, 0x3000
|
||||
ori r3, r3, 0x0012
|
||||
mtdbatl 0, r3
|
||||
|
||||
# memory barrier
|
||||
eieio
|
||||
isync
|
||||
|
||||
# save the LR from where we came
|
||||
mflr r31
|
||||
|
||||
# the cos.xml/app.xml structure is at the location 0x68 of r11
|
||||
# there are actually many places that can be hooked for it
|
||||
# e.g. 0xFFF16130 and r27 points to this structure
|
||||
addi r3, r11, 0x68
|
||||
|
||||
bl my_PrepareTitle
|
||||
|
||||
# restore original DBAT registers
|
||||
mtdbatu 0, r28
|
||||
mtdbatl 0, r29
|
||||
|
||||
# memory barrier
|
||||
eieio
|
||||
isync
|
||||
|
||||
# setup LR to jump back to kernel code
|
||||
mtlr r31
|
||||
|
||||
# restore all original values of registers from stack
|
||||
lwz r28, 0x20(r1)
|
||||
lwz r29, 0x24(r1)
|
||||
lwz r30, 0x28(r1)
|
||||
lwz r31, 0x2C(r1)
|
||||
|
||||
lwz r3, 0x30(r1)
|
||||
lwz r4, 0x34(r1)
|
||||
lwz r5, 0x38(r1)
|
||||
lwz r6, 0x3C(r1)
|
||||
lwz r7, 0x40(r1)
|
||||
lwz r8, 0x44(r1)
|
||||
lwz r9, 0x48(r1)
|
||||
lwz r10, 0x4C(r1)
|
||||
lwz r11, 0x50(r1)
|
||||
lwz r12, 0x54(r1)
|
||||
lwz r13, 0x58(r1)
|
||||
lwz r14, 0x5C(r1)
|
||||
lwz r15, 0x60(r1)
|
||||
lwz r16, 0x64(r1)
|
||||
lwz r17, 0x68(r1)
|
||||
lwz r18, 0x6C(r1)
|
||||
lwz r19, 0x70(r1)
|
||||
lwz r20, 0x74(r1)
|
||||
lwz r21, 0x78(r1)
|
||||
lwz r22, 0x7C(r1)
|
||||
|
||||
# restore the stack
|
||||
addi r1, r1, 0x90
|
||||
|
||||
# restore original instruction that we replaced in the kernel
|
||||
clrlwi r7, r12, 0
|
||||
|
||||
# jump back
|
||||
blr
|
208
src/kernel/syscalls.c
Normal file
208
src/kernel/syscalls.c
Normal file
@ -0,0 +1,208 @@
|
||||
#include "common/os_defs.h"
|
||||
#include "common/kernel_defs.h"
|
||||
#include "common/common.h"
|
||||
#include "dynamic_libs/os_functions.h"
|
||||
#include "utils/utils.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
extern void my_PrepareTitle_hook(void);
|
||||
|
||||
static unsigned int origPrepareTitleInstr __attribute__((section(".data"))) = 0;
|
||||
|
||||
static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len)
|
||||
{
|
||||
/*
|
||||
* Setup a DBAT access for our 0xC0800000 area and our 0xBC000000 area which hold our variables like GAME_LAUNCHED and our BSS/rodata section
|
||||
*/
|
||||
register int dbatu0, dbatl0, dbatu1, dbatl1;
|
||||
// save the original DBAT value
|
||||
asm volatile("mfdbatu %0, 0" : "=r" (dbatu0));
|
||||
asm volatile("mfdbatl %0, 0" : "=r" (dbatl0));
|
||||
asm volatile("mfdbatu %0, 1" : "=r" (dbatu1));
|
||||
asm volatile("mfdbatl %0, 1" : "=r" (dbatl1));
|
||||
|
||||
// write our own DBATs into the array
|
||||
if( ((addr & 0xFFF00000) == 0xFFF00000) || ((src & 0xFFF00000) == 0xFFF00000) )
|
||||
{
|
||||
// setup kernel code access
|
||||
unsigned int dbatu = 0;
|
||||
unsigned int dbatl = 0;
|
||||
|
||||
if((src & 0xFFF00000) == 0xFFF00000) {
|
||||
dbatu = (src & 0xFFF00000) | 0x02;
|
||||
dbatl = (src & 0xFFF00000) | 0x32;
|
||||
}
|
||||
else {
|
||||
dbatu = (addr & 0xFFF00000) | 0x02;
|
||||
dbatl = (addr & 0xFFF00000) | 0x32;
|
||||
}
|
||||
|
||||
if( ((addr & 0xFFF00000) != (dbatu0 & 0xFFF00000)) && ((src & 0xFFF00000) != (dbatu0 & 0xFFF00000)) )
|
||||
{
|
||||
asm volatile("mtdbatu 0, %0" : : "r" (dbatu));
|
||||
asm volatile("mtdbatl 0, %0" : : "r" (dbatl));
|
||||
}
|
||||
else
|
||||
{
|
||||
asm volatile("mtdbatu 1, %0" : : "r" (dbatu));
|
||||
asm volatile("mtdbatl 1, %0" : : "r" (dbatl));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asm volatile("mtdbatu 0, %0" : : "r" (0xC0001FFF));
|
||||
asm volatile("mtdbatl 0, %0" : : "r" (0x30000012));
|
||||
asm volatile("mtdbatu 1, %0" : : "r" (0xB0801FFF));
|
||||
asm volatile("mtdbatl 1, %0" : : "r" (0x20800012));
|
||||
}
|
||||
asm volatile("eieio; isync");
|
||||
|
||||
|
||||
unsigned char *src_p = (unsigned char*)src;
|
||||
unsigned char *dst_p = (unsigned char*)addr;
|
||||
|
||||
unsigned int i;
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
dst_p[i] = src_p[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore original DBAT value
|
||||
*/
|
||||
asm volatile("mtdbatu 0, %0" : : "r" (dbatu0));
|
||||
asm volatile("mtdbatl 0, %0" : : "r" (dbatl0));
|
||||
asm volatile("mtdbatu 1, %0" : : "r" (dbatu1));
|
||||
asm volatile("mtdbatl 1, %0" : : "r" (dbatl1));
|
||||
asm volatile("eieio; isync");
|
||||
}
|
||||
|
||||
static void KernelReadDBATs(bat_table_t * table)
|
||||
{
|
||||
u32 i = 0;
|
||||
|
||||
asm volatile("eieio; isync");
|
||||
|
||||
asm volatile("mfspr %0, 536" : "=r" (table->bat[i].h));
|
||||
asm volatile("mfspr %0, 537" : "=r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mfspr %0, 538" : "=r" (table->bat[i].h));
|
||||
asm volatile("mfspr %0, 539" : "=r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mfspr %0, 540" : "=r" (table->bat[i].h));
|
||||
asm volatile("mfspr %0, 541" : "=r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mfspr %0, 542" : "=r" (table->bat[i].h));
|
||||
asm volatile("mfspr %0, 543" : "=r" (table->bat[i].l));
|
||||
i++;
|
||||
|
||||
asm volatile("mfspr %0, 568" : "=r" (table->bat[i].h));
|
||||
asm volatile("mfspr %0, 569" : "=r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mfspr %0, 570" : "=r" (table->bat[i].h));
|
||||
asm volatile("mfspr %0, 571" : "=r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mfspr %0, 572" : "=r" (table->bat[i].h));
|
||||
asm volatile("mfspr %0, 573" : "=r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mfspr %0, 574" : "=r" (table->bat[i].h));
|
||||
asm volatile("mfspr %0, 575" : "=r" (table->bat[i].l));
|
||||
}
|
||||
|
||||
static void KernelWriteDBATs(bat_table_t * table)
|
||||
{
|
||||
u32 i = 0;
|
||||
|
||||
asm volatile("eieio; isync");
|
||||
|
||||
asm volatile("mtspr 536, %0" : : "r" (table->bat[i].h));
|
||||
asm volatile("mtspr 537, %0" : : "r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mtspr 538, %0" : : "r" (table->bat[i].h));
|
||||
asm volatile("mtspr 539, %0" : : "r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mtspr 540, %0" : : "r" (table->bat[i].h));
|
||||
asm volatile("mtspr 541, %0" : : "r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mtspr 542, %0" : : "r" (table->bat[i].h));
|
||||
asm volatile("mtspr 543, %0" : : "r" (table->bat[i].l));
|
||||
i++;
|
||||
|
||||
asm volatile("mtspr 568, %0" : : "r" (table->bat[i].h));
|
||||
asm volatile("mtspr 569, %0" : : "r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mtspr 570, %0" : : "r" (table->bat[i].h));
|
||||
asm volatile("mtspr 571, %0" : : "r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mtspr 572, %0" : : "r" (table->bat[i].h));
|
||||
asm volatile("mtspr 573, %0" : : "r" (table->bat[i].l));
|
||||
i++;
|
||||
asm volatile("mtspr 574, %0" : : "r" (table->bat[i].h));
|
||||
asm volatile("mtspr 575, %0" : : "r" (table->bat[i].l));
|
||||
|
||||
asm volatile("eieio; isync");
|
||||
}
|
||||
|
||||
/* Write a 32-bit word with kernel permissions */
|
||||
static void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value)
|
||||
{
|
||||
asm volatile (
|
||||
"li 3,1\n"
|
||||
"li 4,0\n"
|
||||
"mr 5,%1\n"
|
||||
"li 6,0\n"
|
||||
"li 7,0\n"
|
||||
"lis 8,1\n"
|
||||
"mr 9,%0\n"
|
||||
"mr %1,1\n"
|
||||
"li 0,0x3500\n"
|
||||
"sc\n"
|
||||
"nop\n"
|
||||
"mr 1,%1\n"
|
||||
:
|
||||
: "r"(addr), "r"(value)
|
||||
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||
"11", "12"
|
||||
);
|
||||
}
|
||||
|
||||
void KernelSetupSyscalls(void)
|
||||
{
|
||||
//! assign 1 so that this variable gets into the retained .data section
|
||||
static uint8_t ucSyscallsSetupRequired = 1;
|
||||
if(!ucSyscallsSetupRequired)
|
||||
return;
|
||||
|
||||
ucSyscallsSetupRequired = 0;
|
||||
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl1 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl2 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl3 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl4 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl5 + (0x36 * 4)), (unsigned int)KernelReadDBATs);
|
||||
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl1 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl2 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl3 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl4 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl5 + (0x37 * 4)), (unsigned int)KernelWriteDBATs);
|
||||
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl1 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl2 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl3 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl4 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||
kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl5 + (0x25 * 4)), (unsigned int)KernelCopyData);
|
||||
|
||||
//! write our hook to the
|
||||
u32 addr_my_PrepareTitle_hook = ((u32)my_PrepareTitle_hook) | 0x48000003;
|
||||
|
||||
SC0x25_KernelCopyData((u32)&origPrepareTitleInstr, (u32)addr_PrepareTitle_hook, 4);
|
||||
SC0x25_KernelCopyData((u32)addr_PrepareTitle_hook, (u32)&addr_my_PrepareTitle_hook, 4);
|
||||
}
|
||||
|
||||
|
||||
void KernelRestoreInstructions(void)
|
||||
{
|
||||
if(origPrepareTitleInstr != 0)
|
||||
SC0x25_KernelCopyData((u32)addr_PrepareTitle_hook, (u32)&origPrepareTitleInstr, 4);
|
||||
}
|
23
src/kernel/syscalls.h
Normal file
23
src/kernel/syscalls.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef __SYSCALLS_H_
|
||||
#define __SYSCALLS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <gctypes.h>
|
||||
#include "common/kernel_defs.h"
|
||||
|
||||
void KernelSetupSyscalls(void);
|
||||
void KernelRestoreInstructions(void);
|
||||
|
||||
void SC0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
|
||||
void SC0x36_KernelReadDBATs(bat_table_t * table);
|
||||
void SC0x37_KernelWriteDBATs(bat_table_t * table);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __KERNEL_FUNCTIONS_H_
|
19
src/kernel/syscalls_asm.S
Normal file
19
src/kernel/syscalls_asm.S
Normal file
@ -0,0 +1,19 @@
|
||||
# Syscalls for kernel that we use
|
||||
|
||||
.globl SC0x36_KernelReadDBATs
|
||||
SC0x36_KernelReadDBATs:
|
||||
li r0, 0x3600
|
||||
sc
|
||||
blr
|
||||
|
||||
.globl SC0x37_KernelWriteDBATs
|
||||
SC0x37_KernelWriteDBATs:
|
||||
li r0, 0x3700
|
||||
sc
|
||||
blr
|
||||
|
||||
.globl SC0x25_KernelCopyData
|
||||
SC0x25_KernelCopyData:
|
||||
li r0, 0x2500
|
||||
sc
|
||||
blr
|
43
src/link.ld
Normal file
43
src/link.ld
Normal file
@ -0,0 +1,43 @@
|
||||
OUTPUT(ddd.elf);
|
||||
|
||||
/* Tell linker where our application entry is so the garbage collect can work correct */
|
||||
ENTRY(__entry_menu);
|
||||
|
||||
SECTIONS {
|
||||
. = 0x00802000;
|
||||
.text : {
|
||||
*(.kernel_code*);
|
||||
*(.text*);
|
||||
/* Tell linker to not garbage collect this section as it is not referenced anywhere */
|
||||
KEEP(*(.kernel_code*));
|
||||
}
|
||||
.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 */
|
76
src/main.c
Normal file
76
src/main.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include "dynamic_libs/os_functions.h"
|
||||
#include "dynamic_libs/gx2_functions.h"
|
||||
#include "dynamic_libs/syshid_functions.h"
|
||||
#include "dynamic_libs/vpad_functions.h"
|
||||
#include "dynamic_libs/socket_functions.h"
|
||||
#include "dynamic_libs/sys_functions.h"
|
||||
#include "system/memory.h"
|
||||
#include "utils/logger.h"
|
||||
#include "common/common.h"
|
||||
#include "game/rpx_rpl_table.h"
|
||||
#include "game/memory_area_table.h"
|
||||
#include "start.h"
|
||||
#include "patcher/function_hooks.h"
|
||||
#include "kernel/kernel_functions.h"
|
||||
#include "system/exception_handler.h"
|
||||
#include "fs/fs_utils.h"
|
||||
#include "fs/sd_fat_devoptab.h"
|
||||
#include "controller_patcher/controller_patcher.h"
|
||||
|
||||
typedef union u_serv_ip
|
||||
{
|
||||
uint8_t digit[4];
|
||||
uint32_t full;
|
||||
} u_serv_ip;
|
||||
|
||||
#define PRINT_TEXT2(x, y, ...) { snprintf(msg, 80, __VA_ARGS__); OSScreenPutFontEx(0, x, y, msg); OSScreenPutFontEx(1, x, y, msg); }
|
||||
|
||||
/* Entry point */
|
||||
int Menu_Main(void)
|
||||
{
|
||||
//!*******************************************************************
|
||||
//! Initialize function pointers *
|
||||
//!*******************************************************************
|
||||
//! do OS (for acquire) and sockets first so we got logging
|
||||
InitOSFunctionPointers();
|
||||
InitSocketFunctionPointers();
|
||||
InitGX2FunctionPointers();
|
||||
InitSysFunctionPointers();
|
||||
|
||||
log_init("192.168.0.181");
|
||||
|
||||
SetupKernelCallback();
|
||||
log_printf("Started %s\n", cosAppXmlInfoStruct.rpx_name);
|
||||
|
||||
//!*******************************************************************
|
||||
//! Initialize HID Config *
|
||||
//!*******************************************************************
|
||||
init_config_controller();
|
||||
|
||||
PatchMethodHooks();
|
||||
if(strlen(cosAppXmlInfoStruct.rpx_name) > 0 && strcasecmp("ffl_app.rpx", cosAppXmlInfoStruct.rpx_name) != 0)
|
||||
{
|
||||
return EXIT_RELAUNCH_ON_LOAD;
|
||||
}
|
||||
|
||||
if(strlen(cosAppXmlInfoStruct.rpx_name) <= 0){ // First boot back to SysMenu
|
||||
log_printf("Startssed %s\n", cosAppXmlInfoStruct.rpx_name);
|
||||
SYSLaunchMenu();
|
||||
return EXIT_RELAUNCH_ON_LOAD;
|
||||
}
|
||||
log_printf("Stafdsf %s\n", cosAppXmlInfoStruct.rpx_name);
|
||||
RestoreInstructions();
|
||||
|
||||
deinit_config_controller();
|
||||
|
||||
log_deinit();
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
19
src/main.h
Normal file
19
src/main.h
Normal 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
|
45
src/patcher/cpp_to_c_util.cpp
Normal file
45
src/patcher/cpp_to_c_util.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "cpp_to_c_util.h"
|
||||
#include <string.h>
|
||||
#include "common/common.h"
|
||||
#include "video/shaders/ColorShader.h"
|
||||
|
||||
// TODO: not creating these stuff at every frame
|
||||
void draw_Cursor_at(f32 x, f32 y) {
|
||||
f32 widthScaleFactor = 1.0f / (f32)1280;
|
||||
f32 heightScaleFactor = 1.0f / (f32)720;
|
||||
|
||||
int width = 20;
|
||||
|
||||
glm::vec3 positionOffsets = glm::vec3(0.0f);
|
||||
|
||||
positionOffsets[0] = (x-((1280)/2)+(width/2)) * widthScaleFactor * 2.0f;
|
||||
positionOffsets[1] = -(y-((720)/2)+(width/2)) * heightScaleFactor * 2.0f;
|
||||
|
||||
u8 colorVtxs[16];
|
||||
memset(colorVtxs,0xFF,16*sizeof(u8));
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, colorVtxs, 16 * sizeof(u8));
|
||||
|
||||
glm::vec4 colorIntensity = glm::vec4(1.0f);
|
||||
colorIntensity[3] = 255;
|
||||
|
||||
glm::vec3 scale(width*widthScaleFactor,width*heightScaleFactor,1.0f);
|
||||
|
||||
ColorShader::instance()->setShaders();
|
||||
ColorShader::instance()->setAttributeBuffer(colorVtxs, NULL, 4);
|
||||
ColorShader::instance()->setAngle(0);
|
||||
ColorShader::instance()->setOffset(positionOffsets);
|
||||
ColorShader::instance()->setScale(scale);
|
||||
ColorShader::instance()->setColorIntensity(colorIntensity);
|
||||
ColorShader::instance()->draw(GX2_PRIMITIVE_QUADS, 4);
|
||||
}
|
||||
|
||||
|
||||
void draw_Cursor_destroy() {
|
||||
//! destroy shaders
|
||||
ColorShader::destroyInstance();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
12
src/patcher/cpp_to_c_util.h
Normal file
12
src/patcher/cpp_to_c_util.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifdef __cplusplus
|
||||
#define EXTERNC extern "C"
|
||||
#else
|
||||
#define EXTERNC
|
||||
#endif
|
||||
|
||||
#include "../dynamic_libs/gx2_types.h"
|
||||
|
||||
EXTERNC void draw_Cursor_at(f32 x, f32 y);
|
||||
EXTERNC void draw_Cursor_destroy();
|
||||
|
||||
#undef EXTERNC
|
348
src/patcher/function_hooks.c
Normal file
348
src/patcher/function_hooks.c
Normal file
@ -0,0 +1,348 @@
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include "common/common.h"
|
||||
#include "common/fs_defs.h"
|
||||
#include "common/loader_defs.h"
|
||||
#include "controller_patcher/cp_retain_vars.h"
|
||||
#include "game/rpx_rpl_table.h"
|
||||
#include "dynamic_libs/aoc_functions.h"
|
||||
#include "dynamic_libs/ax_functions.h"
|
||||
#include "dynamic_libs/fs_functions.h"
|
||||
#include "dynamic_libs/gx2_functions.h"
|
||||
#include "dynamic_libs/os_functions.h"
|
||||
#include "dynamic_libs/padscore_functions.h"
|
||||
#include "dynamic_libs/socket_functions.h"
|
||||
#include "dynamic_libs/sys_functions.h"
|
||||
#include "dynamic_libs/vpad_functions.h"
|
||||
#include "dynamic_libs/acp_functions.h"
|
||||
#include "dynamic_libs/syshid_functions.h"
|
||||
#include "kernel/kernel_functions.h"
|
||||
#include "system/exception_handler.h"
|
||||
#include "function_hooks.h"
|
||||
#include "fs/fs_utils.h"
|
||||
#include "utils/logger.h"
|
||||
#include "system/memory.h"
|
||||
|
||||
#include "cpp_to_c_util.h"
|
||||
|
||||
#define LIB_CODE_RW_BASE_OFFSET 0xC1000000
|
||||
#define CODE_RW_BASE_OFFSET 0x00000000
|
||||
#define DEBUG_LOG_DYN 0
|
||||
|
||||
#define USE_EXTRA_LOG_FUNCTIONS 0
|
||||
|
||||
#define DECL(res, name, ...) \
|
||||
res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".data"))); \
|
||||
res my_ ## name(__VA_ARGS__)
|
||||
|
||||
DECL(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, s32 scan_target){
|
||||
|
||||
if(gHIDCurrentDevice & HID_LIST_MOUSE && gHID_Mouse_Mode == HID_MOUSE_MODE_TOUCH) {
|
||||
draw_Cursor_at(gHID_Mouse.pad_data[0].data[0].X, gHID_Mouse.pad_data[0].data[0].Y);
|
||||
}
|
||||
real_GX2CopyColorBufferToScanBuffer(colorBuffer,scan_target);
|
||||
}
|
||||
|
||||
DECL(void, _Exit, void){
|
||||
draw_Cursor_destroy();
|
||||
real__Exit();
|
||||
}
|
||||
|
||||
DECL(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error) {
|
||||
|
||||
int result = real_VPADRead(chan, buffer, buffer_size, error);
|
||||
|
||||
if(gHIDAttached){
|
||||
setControllerDataFromHID(buffer,gHIDCurrentDevice);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* *****************************************************************************
|
||||
* Creates function pointer array
|
||||
* ****************************************************************************/
|
||||
#define MAKE_MAGIC(x, lib,functionType) { (unsigned int) my_ ## x, (unsigned int) &real_ ## x, lib, # x,0,0,functionType,0}
|
||||
|
||||
static struct hooks_magic_t {
|
||||
const unsigned int replaceAddr;
|
||||
const unsigned int replaceCall;
|
||||
const unsigned int library;
|
||||
const char functionName[50];
|
||||
unsigned int realAddr;
|
||||
unsigned int restoreInstruction;
|
||||
unsigned char functionType;
|
||||
unsigned char alreadyPatched;
|
||||
} method_hooks[] = {
|
||||
// Common FS functions
|
||||
MAKE_MAGIC(VPADRead, LIB_VPAD,STATIC_FUNCTION),
|
||||
MAKE_MAGIC(GX2CopyColorBufferToScanBuffer, LIB_GX2,STATIC_FUNCTION),
|
||||
MAKE_MAGIC(_Exit, LIB_CORE_INIT,STATIC_FUNCTION),
|
||||
};
|
||||
|
||||
//! buffer to store our 7 instructions needed for our replacements
|
||||
//! the code will be placed in the address of that buffer - CODE_RW_BASE_OFFSET
|
||||
//! avoid this buffer to be placed in BSS and reset on start up
|
||||
volatile unsigned int dynamic_method_calls[sizeof(method_hooks) / sizeof(struct hooks_magic_t) * 7] __attribute__((section(".data")));
|
||||
|
||||
/*
|
||||
*Patches a function that is loaded at the start of each application. Its not required to restore, at least when they are really dynamic.
|
||||
* "normal" functions should be patch with the normal patcher.
|
||||
*/
|
||||
void PatchMethodHooks(void)
|
||||
{
|
||||
/* Patch branches to it. */
|
||||
volatile unsigned int *space = &dynamic_method_calls[0];
|
||||
|
||||
int method_hooks_count = sizeof(method_hooks) / sizeof(struct hooks_magic_t);
|
||||
|
||||
u32 skip_instr = 1;
|
||||
u32 my_instr_len = 6;
|
||||
u32 instr_len = my_instr_len + skip_instr;
|
||||
u32 flush_len = 4*instr_len;
|
||||
for(int i = 0; i < method_hooks_count; i++)
|
||||
{
|
||||
if(method_hooks[i].functionType == STATIC_FUNCTION && method_hooks[i].alreadyPatched == 1){
|
||||
if(isDynamicFunction((u32)OSEffectiveToPhysical((void*)method_hooks[i].realAddr))){
|
||||
log_printf("The function %s is a dynamic function. Please fix that <3\n", method_hooks[i].functionName);
|
||||
method_hooks[i].functionType = DYNAMIC_FUNCTION;
|
||||
}else{
|
||||
log_printf("Skipping %s, its already patched\n", method_hooks[i].functionName);
|
||||
space += instr_len;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
u32 physical = 0;
|
||||
unsigned int repl_addr = (unsigned int)method_hooks[i].replaceAddr;
|
||||
unsigned int call_addr = (unsigned int)method_hooks[i].replaceCall;
|
||||
|
||||
unsigned int real_addr = GetAddressOfFunction(method_hooks[i].functionName,method_hooks[i].library);
|
||||
|
||||
if(!real_addr){
|
||||
log_printf("OSDynLoad_FindExport failed for %s\n", method_hooks[i].functionName);
|
||||
space += instr_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(DEBUG_LOG_DYN)log_printf("%s is located at %08X!\n", method_hooks[i].functionName,real_addr);
|
||||
|
||||
physical = (u32)OSEffectiveToPhysical((void*)real_addr);
|
||||
if(!physical){
|
||||
log_printf("Something is wrong with the physical address\n");
|
||||
space += instr_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(DEBUG_LOG_DYN)log_printf("%s physical is located at %08X!\n", method_hooks[i].functionName,physical);
|
||||
|
||||
bat_table_t my_dbat_table;
|
||||
if(DEBUG_LOG_DYN)log_printf("Setting up DBAT\n");
|
||||
KernelSetDBATsForDynamicFuction(&my_dbat_table,physical);
|
||||
|
||||
//log_printf("Setting call_addr to %08X\n",(unsigned int)(space) - CODE_RW_BASE_OFFSET);
|
||||
*(volatile unsigned int *)(call_addr) = (unsigned int)(space) - CODE_RW_BASE_OFFSET;
|
||||
|
||||
// copy instructions from real function.
|
||||
u32 offset_ptr = 0;
|
||||
for(offset_ptr = 0;offset_ptr<skip_instr*4;offset_ptr +=4){
|
||||
if(DEBUG_LOG_DYN)log_printf("(real_)%08X = %08X\n",space,*(volatile unsigned int*)(physical+offset_ptr));
|
||||
*space = *(volatile unsigned int*)(physical+offset_ptr);
|
||||
space++;
|
||||
}
|
||||
|
||||
//Only works if skip_instr == 1
|
||||
if(skip_instr == 1){
|
||||
// fill the restore instruction section
|
||||
method_hooks[i].realAddr = real_addr;
|
||||
method_hooks[i].restoreInstruction = *(volatile unsigned int*)(physical);
|
||||
}else{
|
||||
log_printf("Can't save %s for restoring!\n", method_hooks[i].functionName);
|
||||
}
|
||||
|
||||
//adding jump to real function
|
||||
/*
|
||||
90 61 ff e0 stw r3,-32(r1)
|
||||
3c 60 12 34 lis r3,4660
|
||||
60 63 56 78 ori r3,r3,22136
|
||||
7c 69 03 a6 mtctr r3
|
||||
80 61 ff e0 lwz r3,-32(r1)
|
||||
4e 80 04 20 bctr*/
|
||||
*space = 0x9061FFE0;
|
||||
space++;
|
||||
*space = 0x3C600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); // lis r3, real_addr@h
|
||||
space++;
|
||||
*space = 0x60630000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); // ori r3, r3, real_addr@l
|
||||
space++;
|
||||
*space = 0x7C6903A6; // mtctr r3
|
||||
space++;
|
||||
*space = 0x8061FFE0; // lwz r3,-32(r1)
|
||||
space++;
|
||||
*space = 0x4E800420; // bctr
|
||||
space++;
|
||||
DCFlushRange((void*)(space - instr_len), flush_len);
|
||||
ICInvalidateRange((unsigned char*)(space - instr_len), flush_len);
|
||||
|
||||
//setting jump back
|
||||
unsigned int replace_instr = 0x48000002 | (repl_addr & 0x03fffffc);
|
||||
*(volatile unsigned int *)(physical) = replace_instr;
|
||||
ICInvalidateRange((void*)(real_addr), 4);
|
||||
|
||||
//restore my dbat stuff
|
||||
KernelRestoreDBATs(&my_dbat_table);
|
||||
|
||||
method_hooks[i].alreadyPatched = 1;
|
||||
}
|
||||
log_print("Done with patching all functions!\n");
|
||||
}
|
||||
|
||||
/* ****************************************************************** */
|
||||
/* RESTORE ORIGINAL INSTRUCTIONS */
|
||||
/* ****************************************************************** */
|
||||
void RestoreInstructions(void)
|
||||
{
|
||||
bat_table_t table;
|
||||
KernelSetDBATs(&table);
|
||||
log_printf("Restore functions!\n");
|
||||
int method_hooks_count = sizeof(method_hooks) / sizeof(struct hooks_magic_t);
|
||||
for(int i = 0; i < method_hooks_count; i++)
|
||||
{
|
||||
if(method_hooks[i].restoreInstruction == 0 || method_hooks[i].realAddr == 0){
|
||||
log_printf("I dont have the information for the restore =( skip\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned int real_addr = GetAddressOfFunction(method_hooks[i].functionName,method_hooks[i].library);
|
||||
|
||||
if(!real_addr){
|
||||
log_printf("OSDynLoad_FindExport failed for %s\n", method_hooks[i].functionName);
|
||||
continue;
|
||||
}
|
||||
|
||||
u32 physical = (u32)OSEffectiveToPhysical((void*)real_addr);
|
||||
if(!physical){
|
||||
log_printf("Something is wrong with the physical address\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isDynamicFunction(physical)){
|
||||
log_printf("Its a dynamic function. We don't need to restore it! %s\n",method_hooks[i].functionName);
|
||||
}else{
|
||||
KernelSetDBATs(&table);
|
||||
|
||||
*(volatile unsigned int *)(LIB_CODE_RW_BASE_OFFSET + method_hooks[i].realAddr) = method_hooks[i].restoreInstruction;
|
||||
DCFlushRange((void*)(LIB_CODE_RW_BASE_OFFSET + method_hooks[i].realAddr), 4);
|
||||
ICInvalidateRange((void*)method_hooks[i].realAddr, 4);
|
||||
log_printf("Restored %s\n",method_hooks[i].functionName);
|
||||
KernelRestoreDBATs(&table);
|
||||
}
|
||||
method_hooks[i].alreadyPatched = 0; // In case a
|
||||
}
|
||||
KernelRestoreInstructions();
|
||||
log_print("Done with restoring all functions!\n");
|
||||
}
|
||||
|
||||
int isDynamicFunction(unsigned int physicalAddress){
|
||||
if((physicalAddress & 0x80000000) == 0x80000000){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int GetAddressOfFunction(const char * functionName,unsigned int library){
|
||||
unsigned int real_addr = 0;
|
||||
|
||||
unsigned int rpl_handle = 0;
|
||||
if(library == LIB_CORE_INIT){
|
||||
log_printf("FindExport of %s! From LIB_CORE_INIT\n", functionName);
|
||||
if(coreinit_handle == 0){log_print("LIB_CORE_INIT not aquired\n"); return 0;}
|
||||
rpl_handle = coreinit_handle;
|
||||
}
|
||||
else if(library == LIB_NSYSNET){
|
||||
log_printf("FindExport of %s! From LIB_NSYSNET\n", functionName);
|
||||
if(nsysnet_handle == 0){log_print("LIB_NSYSNET not aquired\n"); return 0;}
|
||||
rpl_handle = nsysnet_handle;
|
||||
}
|
||||
else if(library == LIB_GX2){
|
||||
log_printf("FindExport of %s! From LIB_GX2\n", functionName);
|
||||
if(gx2_handle == 0){log_print("LIB_GX2 not aquired\n"); return 0;}
|
||||
rpl_handle = gx2_handle;
|
||||
}
|
||||
else if(library == LIB_AOC){
|
||||
log_printf("FindExport of %s! From LIB_AOC\n", functionName);
|
||||
if(aoc_handle == 0){log_print("LIB_AOC not aquired\n"); return 0;}
|
||||
rpl_handle = aoc_handle;
|
||||
}
|
||||
else if(library == LIB_AX){
|
||||
log_printf("FindExport of %s! From LIB_AX\n", functionName);
|
||||
if(sound_handle == 0){log_print("LIB_AX not aquired\n"); return 0;}
|
||||
rpl_handle = sound_handle;
|
||||
}
|
||||
else if(library == LIB_FS){
|
||||
log_printf("FindExport of %s! From LIB_FS\n", functionName);
|
||||
if(coreinit_handle == 0){log_print("LIB_FS not aquired\n"); return 0;}
|
||||
rpl_handle = coreinit_handle;
|
||||
}
|
||||
else if(library == LIB_OS){
|
||||
log_printf("FindExport of %s! From LIB_OS\n", functionName);
|
||||
if(coreinit_handle == 0){log_print("LIB_OS not aquired\n"); return 0;}
|
||||
rpl_handle = coreinit_handle;
|
||||
}
|
||||
else if(library == LIB_PADSCORE){
|
||||
log_printf("FindExport of %s! From LIB_PADSCORE\n", functionName);
|
||||
if(padscore_handle == 0){log_print("LIB_PADSCORE not aquired\n"); return 0;}
|
||||
rpl_handle = padscore_handle;
|
||||
}
|
||||
else if(library == LIB_SOCKET){
|
||||
log_printf("FindExport of %s! From LIB_SOCKET\n", functionName);
|
||||
if(nsysnet_handle == 0){log_print("LIB_SOCKET not aquired\n"); return 0;}
|
||||
rpl_handle = nsysnet_handle;
|
||||
}
|
||||
else if(library == LIB_SYS){
|
||||
log_printf("FindExport of %s! From LIB_SYS\n", functionName);
|
||||
if(sysapp_handle == 0){log_print("LIB_SYS not aquired\n"); return 0;}
|
||||
rpl_handle = sysapp_handle;
|
||||
}
|
||||
else if(library == LIB_VPAD){
|
||||
log_printf("FindExport of %s! From LIB_VPAD\n", functionName);
|
||||
if(vpad_handle == 0){log_print("LIB_VPAD not aquired\n"); return 0;}
|
||||
rpl_handle = vpad_handle;
|
||||
}
|
||||
else if(library == LIB_NN_ACP){
|
||||
log_printf("FindExport of %s! From LIB_NN_ACP\n", functionName);
|
||||
if(acp_handle == 0){log_print("LIB_NN_ACP not aquired\n"); return 0;}
|
||||
rpl_handle = acp_handle;
|
||||
}
|
||||
else if(library == LIB_SYSHID){
|
||||
log_printf("FindExport of %s! From LIB_SYSHID\n", functionName);
|
||||
if(syshid_handle == 0){log_print("LIB_SYSHID not aquired\n"); return 0;}
|
||||
rpl_handle = syshid_handle;
|
||||
}
|
||||
else if(library == LIB_VPADBASE){
|
||||
log_printf("FindExport of %s! From LIB_VPADBASE\n", functionName);
|
||||
if(vpadbase_handle == 0){log_print("LIB_VPADBASE not aquired\n"); return 0;}
|
||||
rpl_handle = vpadbase_handle;
|
||||
}
|
||||
|
||||
if(!rpl_handle){
|
||||
log_printf("Failed to find the RPL handle for %s\n", functionName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
OSDynLoad_FindExport(rpl_handle, 0, functionName, &real_addr);
|
||||
|
||||
if(!real_addr){
|
||||
log_printf("OSDynLoad_FindExport failed for %s\n", functionName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((u32)(*(volatile unsigned int*)(real_addr) & 0xFF000000) == 0x48000000){
|
||||
real_addr += (u32)(*(volatile unsigned int*)(real_addr) & 0x0000FFFF);
|
||||
if((u32)(*(volatile unsigned int*)(real_addr) & 0xFF000000) == 0x48000000){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return real_addr;
|
||||
}
|
41
src/patcher/function_hooks.h
Normal file
41
src/patcher/function_hooks.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef _FUNCTION_HOOKS_H_
|
||||
#define _FUNCTION_HOOKS_H_
|
||||
|
||||
#include "dynamic_libs/syshid_functions.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
#define MAX_CLIENT 32
|
||||
|
||||
struct bss_t {
|
||||
int global_sock;
|
||||
int socket_fs[MAX_CLIENT];
|
||||
void *pClient_fs[MAX_CLIENT];
|
||||
volatile int lock;
|
||||
char mount_base[255];
|
||||
char save_base[255];
|
||||
void* file_replacer;
|
||||
char update_path[50];
|
||||
char save_dir_common[7];
|
||||
char save_dir_user[9];
|
||||
};
|
||||
|
||||
#define bss_ptr (*(struct bss_t **)0x100000e4)
|
||||
#define bss (*bss_ptr)
|
||||
|
||||
void PatchMethodHooks(void);
|
||||
void RestoreInstructions(void);
|
||||
unsigned int GetAddressOfFunction(const char * functionName,unsigned int library);
|
||||
int isDynamicFunction(unsigned int physicalAddress);
|
||||
void PatchSDK(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FS_H */
|
24
src/start.c
Normal file
24
src/start.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "common/kernel_defs.h"
|
||||
#include "dynamic_libs/os_functions.h"
|
||||
#include "dynamic_libs/fs_functions.h"
|
||||
#include "dynamic_libs/aoc_functions.h"
|
||||
#include "dynamic_libs/socket_functions.h"
|
||||
#include "dynamic_libs/sys_functions.h"
|
||||
#include "game/rpx_rpl_table.h"
|
||||
#include "game/memory_area_table.h"
|
||||
#include "utils/net.h"
|
||||
#include "start.h"
|
||||
|
||||
void StartFunction()
|
||||
{
|
||||
}
|
||||
|
||||
void Reset(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
18
src/start.h
Normal file
18
src/start.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _DISCDUMPER_H_
|
||||
#define _DISCDUMPER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void StartFunction(void);
|
||||
void Reset(void);
|
||||
|
||||
void SetServerIp(u32 ip);
|
||||
u32 GetServerIp(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
169
src/system/exception_handler.c
Normal file
169
src/system/exception_handler.c
Normal file
@ -0,0 +1,169 @@
|
||||
#include <stdio.h>
|
||||
#include "dynamic_libs/os_functions.h"
|
||||
#include "utils/logger.h"
|
||||
#include "exception_handler.h"
|
||||
|
||||
#define OS_EXCEPTION_MODE_GLOBAL_ALL_CORES 4
|
||||
|
||||
#define OS_EXCEPTION_DSI 2
|
||||
#define OS_EXCEPTION_ISI 3
|
||||
#define OS_EXCEPTION_PROGRAM 6
|
||||
|
||||
/* Exceptions */
|
||||
typedef struct OSContext
|
||||
{
|
||||
/* OSContext identifier */
|
||||
uint32_t tag1;
|
||||
uint32_t tag2;
|
||||
|
||||
/* GPRs */
|
||||
uint32_t gpr[32];
|
||||
|
||||
/* Special registers */
|
||||
uint32_t cr;
|
||||
uint32_t lr;
|
||||
uint32_t ctr;
|
||||
uint32_t xer;
|
||||
|
||||
/* Initial PC and MSR */
|
||||
uint32_t srr0;
|
||||
uint32_t srr1;
|
||||
|
||||
/* Only valid during DSI exception */
|
||||
uint32_t exception_specific0;
|
||||
uint32_t exception_specific1;
|
||||
|
||||
/* There is actually a lot more here but we don't need the rest*/
|
||||
} OSContext;
|
||||
|
||||
#define CPU_STACK_TRACE_DEPTH 10
|
||||
#define __stringify(rn) #rn
|
||||
|
||||
#define mfspr(_rn) \
|
||||
({ register uint32_t _rval = 0; \
|
||||
asm volatile("mfspr %0," __stringify(_rn) \
|
||||
: "=r" (_rval));\
|
||||
_rval; \
|
||||
})
|
||||
|
||||
typedef struct _framerec {
|
||||
struct _framerec *up;
|
||||
void *lr;
|
||||
} frame_rec, *frame_rec_t;
|
||||
|
||||
static const char *exception_names[] = {
|
||||
"DSI",
|
||||
"ISI",
|
||||
"PROGRAM"
|
||||
};
|
||||
|
||||
static const char exception_print_formats[18][45] = {
|
||||
"Exception type %s occurred!\n", // 0
|
||||
"GPR00 %08X GPR08 %08X GPR16 %08X GPR24 %08X\n", // 1
|
||||
"GPR01 %08X GPR09 %08X GPR17 %08X GPR25 %08X\n", // 2
|
||||
"GPR02 %08X GPR10 %08X GPR18 %08X GPR26 %08X\n", // 3
|
||||
"GPR03 %08X GPR11 %08X GPR19 %08X GPR27 %08X\n", // 4
|
||||
"GPR04 %08X GPR12 %08X GPR20 %08X GPR28 %08X\n", // 5
|
||||
"GPR05 %08X GPR13 %08X GPR21 %08X GPR29 %08X\n", // 6
|
||||
"GPR06 %08X GPR14 %08X GPR22 %08X GPR30 %08X\n", // 7
|
||||
"GPR07 %08X GPR15 %08X GPR23 %08X GPR31 %08X\n", // 8
|
||||
"LR %08X SRR0 %08x SRR1 %08x\n", // 9
|
||||
"DAR %08X DSISR %08X\n", // 10
|
||||
"\nSTACK DUMP:", // 11
|
||||
" --> ", // 12
|
||||
" -->\n", // 13
|
||||
"\n", // 14
|
||||
"%p", // 15
|
||||
"\nCODE DUMP:\n", // 16
|
||||
"%p: %08X %08X %08X %08X\n", // 17
|
||||
};
|
||||
|
||||
static unsigned char exception_cb(void * c, unsigned char exception_type) {
|
||||
char buf[850];
|
||||
int pos = 0;
|
||||
|
||||
OSContext *context = (OSContext *) c;
|
||||
/*
|
||||
* This part is mostly from libogc. Thanks to the devs over there.
|
||||
*/
|
||||
pos += sprintf(buf + pos, exception_print_formats[0], exception_names[exception_type]);
|
||||
pos += sprintf(buf + pos, exception_print_formats[1], context->gpr[0], context->gpr[8], context->gpr[16], context->gpr[24]);
|
||||
pos += sprintf(buf + pos, exception_print_formats[2], context->gpr[1], context->gpr[9], context->gpr[17], context->gpr[25]);
|
||||
pos += sprintf(buf + pos, exception_print_formats[3], context->gpr[2], context->gpr[10], context->gpr[18], context->gpr[26]);
|
||||
pos += sprintf(buf + pos, exception_print_formats[4], context->gpr[3], context->gpr[11], context->gpr[19], context->gpr[27]);
|
||||
pos += sprintf(buf + pos, exception_print_formats[5], context->gpr[4], context->gpr[12], context->gpr[20], context->gpr[28]);
|
||||
pos += sprintf(buf + pos, exception_print_formats[6], context->gpr[5], context->gpr[13], context->gpr[21], context->gpr[29]);
|
||||
pos += sprintf(buf + pos, exception_print_formats[7], context->gpr[6], context->gpr[14], context->gpr[22], context->gpr[30]);
|
||||
pos += sprintf(buf + pos, exception_print_formats[8], context->gpr[7], context->gpr[15], context->gpr[23], context->gpr[31]);
|
||||
pos += sprintf(buf + pos, exception_print_formats[9], context->lr, context->srr0, context->srr1);
|
||||
|
||||
//if(exception_type == OS_EXCEPTION_DSI) {
|
||||
pos += sprintf(buf + pos, exception_print_formats[10], context->exception_specific1, context->exception_specific0); // this freezes
|
||||
//}
|
||||
|
||||
void *pc = (void*)context->srr0;
|
||||
void *lr = (void*)context->lr;
|
||||
void *r1 = (void*)context->gpr[1];
|
||||
register uint32_t i = 0;
|
||||
register frame_rec_t l,p = (frame_rec_t)lr;
|
||||
|
||||
l = p;
|
||||
p = r1;
|
||||
if(!p)
|
||||
asm volatile("mr %0,%%r1" : "=r"(p));
|
||||
|
||||
pos += sprintf(buf + pos, exception_print_formats[11]);
|
||||
|
||||
for(i = 0; i < CPU_STACK_TRACE_DEPTH-1 && p->up; p = p->up, i++) {
|
||||
if(i % 4)
|
||||
pos += sprintf(buf + pos, exception_print_formats[12]);
|
||||
else {
|
||||
if(i > 0)
|
||||
pos += sprintf(buf + pos, exception_print_formats[13]);
|
||||
else
|
||||
pos += sprintf(buf + pos, exception_print_formats[14]);
|
||||
}
|
||||
|
||||
switch(i) {
|
||||
case 0:
|
||||
if(pc)
|
||||
pos += sprintf(buf + pos, exception_print_formats[15],pc);
|
||||
break;
|
||||
case 1:
|
||||
if(!l)
|
||||
l = (frame_rec_t)mfspr(8);
|
||||
pos += sprintf(buf + pos, exception_print_formats[15],(void*)l);
|
||||
break;
|
||||
default:
|
||||
pos += sprintf(buf + pos, exception_print_formats[15],(void*)(p->up->lr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if(exception_type == OS_EXCEPTION_DSI) {
|
||||
uint32_t *pAdd = (uint32_t*)context->srr0;
|
||||
pos += sprintf(buf + pos, exception_print_formats[16]);
|
||||
// TODO by Dimok: this was actually be 3 instead of 2 lines in libogc .... but there is just no more space anymore on the screen
|
||||
for (i = 0; i < 8; i += 4)
|
||||
pos += sprintf(buf + pos, exception_print_formats[17], &(pAdd[i]),pAdd[i], pAdd[i+1], pAdd[i+2], pAdd[i+3]);
|
||||
//}
|
||||
log_print(buf);
|
||||
OSFatal(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned char dsi_exception_cb(void * context) {
|
||||
return exception_cb(context, 0);
|
||||
}
|
||||
static unsigned char isi_exception_cb(void * context) {
|
||||
return exception_cb(context, 1);
|
||||
}
|
||||
static unsigned char program_exception_cb(void * context) {
|
||||
return exception_cb(context, 2);
|
||||
}
|
||||
|
||||
void setup_os_exceptions(void) {
|
||||
OSSetExceptionCallback(OS_EXCEPTION_DSI, &dsi_exception_cb);
|
||||
OSSetExceptionCallback(OS_EXCEPTION_ISI, &isi_exception_cb);
|
||||
OSSetExceptionCallback(OS_EXCEPTION_PROGRAM, &program_exception_cb);
|
||||
}
|
14
src/system/exception_handler.h
Normal file
14
src/system/exception_handler.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __EXCEPTION_HANDLER_H_
|
||||
#define __EXCEPTION_HANDLER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void setup_os_exceptions(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
198
src/system/memory.c
Normal file
198
src/system/memory.c
Normal 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
42
src/system/memory.h
Normal 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
89
src/utils/logger.c
Normal 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
26
src/utils/logger.h
Normal 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
|
636
src/utils/net.c
Normal file
636
src/utils/net.c
Normal file
@ -0,0 +1,636 @@
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "common/common.h"
|
||||
#include "dynamic_libs/os_functions.h"
|
||||
#include "dynamic_libs/socket_functions.h"
|
||||
#include "net.h"
|
||||
|
||||
#define CHECK_ERROR(cond) if (cond) { goto error; }
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "common/common.h"
|
||||
#include "dynamic_libs/os_functions.h"
|
||||
#include "dynamic_libs/socket_functions.h"
|
||||
#include "net.h"
|
||||
|
||||
static volatile int iLock = 0;
|
||||
|
||||
#define CHECK_ERROR(cond) if (cond) { goto error; }
|
||||
|
||||
void cafiine_connect(int *psock,u32 server_ip) {
|
||||
struct sockaddr_in addr;
|
||||
int sock, ret;
|
||||
|
||||
socket_lib_init();
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 7332;
|
||||
addr.sin_addr.s_addr = server_ip;
|
||||
|
||||
ret = connect(sock, (void *)&addr, sizeof(addr));
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = cafiine_handshake(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
|
||||
*psock = sock;
|
||||
return;
|
||||
error:
|
||||
if (sock != -1)
|
||||
socketclose(sock);
|
||||
*psock = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
void cafiine_disconnect(int sock) {
|
||||
CHECK_ERROR(sock == -1);
|
||||
socketclose(sock);
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
int cafiine_handshake(int sock) {
|
||||
int ret;
|
||||
|
||||
unsigned char buffer[16];
|
||||
|
||||
u64 title_id = OSGetTitleID();
|
||||
memcpy(buffer, &title_id, 16);
|
||||
|
||||
ret = sendwait(sock, buffer, sizeof(buffer));
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
return ret;
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int getMode(int sock,int * result)
|
||||
{
|
||||
int ret = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
// create and send buffer with : [cmd id][fd][size][buffer data ...]
|
||||
{
|
||||
ret = sendbyte(sock, BYTE_G_MODE);
|
||||
|
||||
// wait reply
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
if(ret == BYTE_MODE_D) *result = BYTE_MODE_D;
|
||||
if(ret == BYTE_MODE_I) *result = BYTE_MODE_I;
|
||||
ret = 1;
|
||||
}
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cafiine_fsetpos(int sock, int *result, int fd, int set) {
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
int ret;
|
||||
char buffer[1 + 8];
|
||||
buffer[0] = BYTE_SETPOS;
|
||||
*(int *)(buffer + 1) = fd;
|
||||
*(int *)(buffer + 5) = set;
|
||||
ret = sendwait(sock, buffer, 1 + 8);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
ret = recvwait(sock, result, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cafiine_send_handle(int sock, const char *path, int handle)
|
||||
{
|
||||
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
// create and send buffer with : [cmd id][handle][path length][path data ...]
|
||||
{
|
||||
int ret;
|
||||
int len_path = 0;
|
||||
while (path[len_path++]);
|
||||
char buffer[1 + 4 + 4 + len_path];
|
||||
|
||||
buffer[0] = BYTE_HANDLE;
|
||||
*(int *)(buffer + 1) = handle;
|
||||
*(int *)(buffer + 5) = len_path;
|
||||
for (ret = 0; ret < len_path; ret++)
|
||||
buffer[9 + ret] = path[ret];
|
||||
|
||||
// send buffer, wait for reply
|
||||
ret = sendwait(sock, buffer, 1 + 4 + 4 + len_path);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
// wait reply
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret == BYTE_SPECIAL);
|
||||
if(ret == BYTE_REQUEST){
|
||||
ret = 1;
|
||||
}else{
|
||||
ret = 2;
|
||||
}
|
||||
// wait reply
|
||||
int special_ret = recvbyte(sock);
|
||||
CHECK_ERROR(special_ret < 0);
|
||||
CHECK_ERROR(special_ret != BYTE_SPECIAL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
error:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cafiine_fopen(int sock, int *result, const char *path, const char *mode, int *handle) {
|
||||
|
||||
|
||||
int final_result = -1;
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
int ret;
|
||||
int len_path = 0;
|
||||
while (path[len_path++]);
|
||||
int len_mode = 0;
|
||||
while (mode[len_mode++]);
|
||||
|
||||
//
|
||||
{
|
||||
char buffer[1 + 8 + len_path + len_mode];
|
||||
buffer[0] = BYTE_OPEN;
|
||||
*(int *)(buffer + 1) = len_path;
|
||||
*(int *)(buffer + 5) = len_mode;
|
||||
for (ret = 0; ret < len_path; ret++)
|
||||
buffer[9 + ret] = path[ret];
|
||||
for (ret = 0; ret < len_mode; ret++)
|
||||
buffer[9 + len_path + ret] = mode[ret];
|
||||
|
||||
ret = sendwait(sock, buffer, 1 + 8 + len_path + len_mode);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
|
||||
ret = recvwait(sock, result, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvwait(sock, handle, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
}
|
||||
final_result = 0;
|
||||
|
||||
|
||||
error:
|
||||
|
||||
return final_result;
|
||||
}
|
||||
|
||||
void cafiine_send_file(int sock, char *file, int size, int fd) {
|
||||
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
int ret;
|
||||
|
||||
// create and send buffer with : [cmd id][fd][size][buffer data ...]
|
||||
{
|
||||
char buffer[1 + 4 + 4 + size];
|
||||
|
||||
buffer[0] = BYTE_DUMP;
|
||||
*(int *)(buffer + 1) = fd;
|
||||
*(int *)(buffer + 5) = size;
|
||||
for (ret = 0; ret < size; ret++)
|
||||
buffer[9 + ret] = file[ret];
|
||||
|
||||
// send buffer, wait for reply
|
||||
ret = sendwait(sock, buffer, 1 + 4 + 4 + size);
|
||||
CHECK_ERROR(ret < 0);
|
||||
// wait reply
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
}
|
||||
|
||||
error:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int cafiine_fread(int sock, int *result, void *ptr, int size, int fd) {
|
||||
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
int ret;
|
||||
char buffer[1 + 8];
|
||||
buffer[0] = BYTE_READ;
|
||||
*(int *)(buffer + 1) = size;
|
||||
*(int *)(buffer + 5) = fd;
|
||||
ret = sendwait(sock, buffer, 1 + 8);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
int sz;
|
||||
ret = recvwait(sock, &sz, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvwaitlen(sock, ptr, sz);
|
||||
*result = sz - ret;
|
||||
ret = sendbyte(sock, BYTE_OK);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
|
||||
return 0;
|
||||
error:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cafiine_fclose(int sock, int *result, int fd,int dumpclose) {
|
||||
|
||||
|
||||
CHECK_ERROR(sock == -1);
|
||||
|
||||
int ret;
|
||||
char buffer[1 + 4];
|
||||
buffer[0] = BYTE_CLOSE;
|
||||
if(dumpclose)buffer[0] = BYTE_CLOSE_DUMP;
|
||||
*(int *)(buffer + 1) = fd;
|
||||
ret = sendwait(sock, buffer, 1 + 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret == BYTE_NORMAL);
|
||||
ret = recvwait(sock, result, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
|
||||
return 0;
|
||||
error:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int saviine_start_injection(int sock, long persistentID,int * mask){
|
||||
|
||||
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
{
|
||||
char buffer[1+4];
|
||||
|
||||
buffer[0] = BYTE_INJECTSTART;
|
||||
*(long *)(buffer + 1) = persistentID;
|
||||
ret = sendwait(sock, buffer, 1 + 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
|
||||
ret = recvwait(sock, mask, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR((*mask & MASK_NORMAL) != MASK_NORMAL);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
result = 1;
|
||||
}
|
||||
error:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int saviine_end_injection(int sock){
|
||||
|
||||
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
{
|
||||
ret = sendbyte(sock, BYTE_INJECTEND);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_OK);
|
||||
result = 1;
|
||||
}
|
||||
error:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int saviine_start_dump(int sock, long persistentID,int * mask){
|
||||
|
||||
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
{
|
||||
char buffer[1+4];
|
||||
|
||||
buffer[0] = BYTE_DUMPSTART;
|
||||
*(long *)(buffer + 1) = persistentID;
|
||||
ret = sendwait(sock, buffer, 1 + 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
|
||||
ret = recvwait(sock, mask, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR((*mask & MASK_NORMAL) != MASK_NORMAL);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
result = 1;
|
||||
}
|
||||
error:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int saviine_end_dump(int sock){
|
||||
|
||||
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
{
|
||||
ret = sendbyte(sock, BYTE_DUMPEND);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_OK);
|
||||
result = 1;
|
||||
}
|
||||
error:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int saviine_readdir(int sock, char * path,char * resultname, int * resulttype, int * filesize){
|
||||
int result = 0;
|
||||
CHECK_ERROR(sock == -1);
|
||||
int ret;
|
||||
// create and send buffer with : [cmd id][len_path][path][filesize]
|
||||
{
|
||||
int size = 0;
|
||||
while (path[size++]);
|
||||
char buffer[1+4+size];
|
||||
|
||||
buffer[0] = BYTE_READ_DIR;
|
||||
*(int *)(buffer + 1) = size;
|
||||
for (ret = 0; ret < size; ret++)
|
||||
buffer[5 + ret] = path[ret];
|
||||
|
||||
// send buffer, wait for reply
|
||||
ret = sendwait(sock, buffer, 1+4+size);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
// wait reply
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret != BYTE_OK);
|
||||
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret != BYTE_FILE && ret != BYTE_FOLDER);
|
||||
*resulttype = ret;
|
||||
size = 0;
|
||||
ret = recvwait(sock, &size, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
ret = recvwait(sock, resultname, size+1);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
size = 0;
|
||||
ret = recvwait(sock, &size, 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
*filesize = size;
|
||||
ret = recvbyte(sock);
|
||||
CHECK_ERROR(ret < 0);
|
||||
CHECK_ERROR(ret != BYTE_SPECIAL);
|
||||
result = 1;
|
||||
|
||||
}
|
||||
error:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void cafiine_send_ping(int sock, int val1, int val2) {
|
||||
|
||||
int ret;
|
||||
char buffer[1 + 4 + 4];
|
||||
buffer[0] = BYTE_PING;
|
||||
*(int *)(buffer + 1) = val1;
|
||||
*(int *)(buffer + 5) = val2;
|
||||
|
||||
ret = sendwait(sock, buffer, 1 + 4 + 4);
|
||||
CHECK_ERROR(ret < 0);
|
||||
|
||||
error:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int recvwaitlen(int sock, void *buffer, int len) {
|
||||
int ret;
|
||||
while (len > 0) {
|
||||
ret = recv(sock, buffer, len, 0);
|
||||
CHECK_ERROR(ret < 0);
|
||||
len -= ret;
|
||||
buffer += ret;
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
int recvbyte(int sock) {
|
||||
unsigned char buffer[1];
|
||||
int ret;
|
||||
|
||||
ret = recvwait(sock, buffer, 1);
|
||||
if (ret < 0) return ret;
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
void log_string(int sock, const char* str, char flag_byte) {
|
||||
if(sock == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int i;
|
||||
int len_str = 0;
|
||||
while (str[len_str++]);
|
||||
|
||||
//
|
||||
{
|
||||
char buffer[1 + 4 + len_str];
|
||||
buffer[0] = flag_byte;
|
||||
*(int *)(buffer + 1) = len_str;
|
||||
for (i = 0; i < len_str; i++)
|
||||
buffer[5 + i] = str[i];
|
||||
|
||||
buffer[5 + i] = 0;
|
||||
|
||||
sendwait(sock, buffer, 1 + 4 + len_str);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int sendbyte(int sock, unsigned char byte) {
|
||||
unsigned char buffer[1];
|
||||
|
||||
buffer[0] = byte;
|
||||
return sendwait(sock, buffer, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int sendwait(int sock, const void *buffer, int len)
|
||||
{
|
||||
while (iLock)
|
||||
usleep(5000);
|
||||
iLock = 1;
|
||||
|
||||
int ret;
|
||||
while (len > 0) {
|
||||
ret = send(sock, buffer, len, 0);
|
||||
CHECK_ERROR(ret <= 0);
|
||||
len -= ret;
|
||||
buffer += ret;
|
||||
}
|
||||
iLock = 0;
|
||||
return 0;
|
||||
error:
|
||||
iLock = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int recvwait(int sock, void *buffer, int len)
|
||||
{
|
||||
while (iLock)
|
||||
usleep(5000);
|
||||
iLock = 1;
|
||||
|
||||
int ret;
|
||||
int received = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
ret = recv(sock, buffer, len, 0);
|
||||
if(ret > 0)
|
||||
{
|
||||
len -= ret;
|
||||
buffer += ret;
|
||||
received += ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
received = ret < 0 ? ret : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iLock = 0;
|
||||
return received;
|
||||
}
|
||||
/*
|
||||
s32 create_server(void) {
|
||||
socket_lib_init();
|
||||
|
||||
s32 server = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (server < 0)
|
||||
return -1;
|
||||
|
||||
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 = 7333;
|
||||
bindAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
s32 ret;
|
||||
if ((ret = bind(server, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) {
|
||||
socketclose(server);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = listen(server, 3)) < 0) {
|
||||
socketclose(server);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
s32 accept_client(s32 server)
|
||||
{
|
||||
struct sockaddr addr;
|
||||
s32 addrlen = sizeof(addr);
|
||||
|
||||
return accept(server, &addr, &addrlen);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
int server_connect(int *psock, unsigned int server_ip)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int sock, ret;
|
||||
|
||||
// No ip means that we don't have any server running, so no logs
|
||||
if (server_ip == 0) {
|
||||
*psock = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
socket_lib_init();
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(sock < 0)
|
||||
return sock;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 7333;
|
||||
addr.sin_addr.s_addr = server_ip;
|
||||
|
||||
ret = connect(sock, (void *)&addr, sizeof(addr));
|
||||
if(ret < 0)
|
||||
{
|
||||
socketclose(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int enable = 1;
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&enable, sizeof(enable));
|
||||
|
||||
*psock = sock;
|
||||
iLock = 0;
|
||||
return 0;
|
||||
}
|
64
src/utils/net.h
Normal file
64
src/utils/net.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef NETWORK_H_
|
||||
#define NETWORK_H_
|
||||
|
||||
#define BYTE_NORMAL 0xff
|
||||
#define BYTE_SPECIAL 0xfe
|
||||
#define BYTE_OPEN 0x00
|
||||
#define BYTE_READ 0x01
|
||||
#define BYTE_CLOSE 0x02
|
||||
#define BYTE_OK 0x03
|
||||
#define BYTE_SETPOS 0x04
|
||||
#define BYTE_STATFILE 0x05
|
||||
#define BYTE_EOF 0x06
|
||||
#define BYTE_GETPOS 0x07
|
||||
#define BYTE_REQUEST 0x08
|
||||
#define BYTE_REQUEST_SLOW 0x09
|
||||
#define BYTE_HANDLE 0x0A
|
||||
#define BYTE_DUMP 0x0B
|
||||
#define BYTE_PING 0x0C
|
||||
#define BYTE_G_MODE 0x0D
|
||||
#define BYTE_MODE_D 0x0E
|
||||
#define BYTE_MODE_I 0x0F
|
||||
#define BYTE_CLOSE_DUMP 0x10
|
||||
#define BYTE_LOG_STR 0xfb
|
||||
#define BYTE_FILE 0xC0
|
||||
#define BYTE_FOLDER 0xC1
|
||||
#define BYTE_READ_DIR 0xCC
|
||||
#define BYTE_INJECTSTART 0x40
|
||||
#define BYTE_INJECTEND 0x41
|
||||
#define BYTE_DUMPSTART 0x42
|
||||
#define BYTE_DUMPEND 0x43
|
||||
#define BYTE_END 0xfd
|
||||
|
||||
#define MASK_NORMAL 0x8000
|
||||
#define MASK_USER 0x0100
|
||||
#define MASK_COMMON 0x0200
|
||||
#define MASK_COMMON_CLEAN 0x0400
|
||||
|
||||
void cafiine_connect(int *psock,u32 ip);
|
||||
void cafiine_disconnect(int sock);
|
||||
int cafiine_handshake(int sock);
|
||||
int getMode(int sock,int * result);
|
||||
int cafiine_fsetpos(int sock, int *result, int fd, int set);
|
||||
int cafiine_send_handle(int sock, const char *path, int handle);
|
||||
int cafiine_fopen(int sock, int *result, const char *path, const char *mode, int *handle);
|
||||
void cafiine_send_file(int sock, char *file, int size, int fd);
|
||||
int cafiine_fread(int sock, int *result, void *ptr, int size, int fd);
|
||||
int cafiine_fclose(int sock, int *result, int fd,int dumpclose);
|
||||
int saviine_start_injection(int sock, long persistentID,int * mask);
|
||||
int saviine_end_injection(int sock);
|
||||
int saviine_start_dump(int sock, long persistentID,int * mask);
|
||||
int saviine_end_dump(int sock);
|
||||
int saviine_readdir(int sock, char * path,char * resultname, int * resulttype, int * filesize);
|
||||
void cafiine_send_ping(int sock, int val1, int val2);
|
||||
|
||||
int recvwaitlen(int sock, void *buffer, int len);
|
||||
int recvbyte(int sock);
|
||||
void log_string(int sock, const char* str, char flag_byte);
|
||||
int sendbyte(int sock, unsigned char byte);
|
||||
|
||||
int server_connect(int *psock, unsigned int server_ip);
|
||||
int recvwait(int sock, void *buffer, int len);
|
||||
int sendwait(int sock, const void *buffer, int len);
|
||||
|
||||
#endif
|
47
src/utils/utils.h
Normal file
47
src/utils/utils.h
Normal 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_
|
167
src/video/shaders/ColorShader.cpp
Normal file
167
src/video/shaders/ColorShader.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
* 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 "ColorShader.h"
|
||||
|
||||
static const u32 cpVertexShaderProgram[] =
|
||||
{
|
||||
0x00000000,0x00008009,0x20000000,0x000078a0,
|
||||
0x3c200000,0x88060094,0x00c00000,0x88062014,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00a11f00,0xfc00620f,0x02490001,0x80000040,
|
||||
0xfd041f80,0x900c0060,0x83f9223e,0x0000803f,
|
||||
0xfe282001,0x10000040,0xfe001f80,0x00080060,
|
||||
0xfeac9f80,0xfd00624f,0xdb0f49c0,0xdb0fc940,
|
||||
0xfea81f80,0x9000e02f,0x83f9223e,0x00000000,
|
||||
0xfe041f80,0x00370000,0xffa01f00,0x80000000,
|
||||
0xff101f00,0x800c0020,0x7f041f80,0x80370000,
|
||||
0x0000103f,0x00000000,0x02c51f00,0x80000000,
|
||||
0xfea41f00,0x80000020,0xffa09f00,0x80000040,
|
||||
0xff001f80,0x800c0060,0x398ee33f,0x0000103f,
|
||||
0x02c41f00,0x9000e00f,0x02c59f01,0x80000020,
|
||||
0xfea81f00,0x80000040,0x02c19f80,0x9000e06f,
|
||||
0x398ee33f,0x00000000,0x02c11f01,0x80000000,
|
||||
0x02c49f80,0x80000060,0x02e08f01,0xfe0c620f,
|
||||
0x02c01f80,0x7f00622f,0xfe242000,0x10000000,
|
||||
0xfe20a080,0x10000020,0xf2178647,0x49c0e9fb,
|
||||
0xfbbdb2ab,0x768ac733
|
||||
};
|
||||
|
||||
static const u32 cpVertexShaderRegs[] = {
|
||||
0x00000103,0x00000000,0x00000000,0x00000001,
|
||||
0xffffff00,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0x00000000,0xfffffffc,
|
||||
0x00000002,0x00000001,0x00000000,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x00000000,0x0000000e,0x00000010
|
||||
};
|
||||
|
||||
static const u32 cpPixelShaderProgram[] =
|
||||
{
|
||||
0x20000000,0x00000ca0,0x00000000,0x88062094,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00002000,0x90000000,0x0004a000,0x90000020,
|
||||
0x00082001,0x90000040,0x000ca081,0x90000060,
|
||||
0xbb7dd898,0x9746c59c,0xc69b00e7,0x03c36218
|
||||
};
|
||||
static const u32 cpPixelShaderRegs[] = {
|
||||
0x00000001,0x00000002,0x14000001,0x00000000,
|
||||
0x00000001,0x00000100,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x0000000f,0x00000001,0x00000010,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
ColorShader * ColorShader::shaderInstance = NULL;
|
||||
|
||||
ColorShader::ColorShader()
|
||||
: vertexShader(cuAttributeCount)
|
||||
{
|
||||
//! create pixel shader
|
||||
pixelShader.setProgram(cpPixelShaderProgram, sizeof(cpPixelShaderProgram), cpPixelShaderRegs, sizeof(cpPixelShaderRegs));
|
||||
|
||||
colorIntensityLocation = 0;
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_color_intensity", GX2_VAR_TYPE_VEC4, 1, colorIntensityLocation, 0xffffffff });
|
||||
|
||||
//! create vertex shader
|
||||
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
|
||||
|
||||
angleLocation = 0;
|
||||
offsetLocation = 4;
|
||||
scaleLocation = 8;
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "unf_angle", GX2_VAR_TYPE_FLOAT, 1, angleLocation, 0xffffffff });
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "unf_offset", GX2_VAR_TYPE_VEC3, 1, offsetLocation, 0xffffffff });
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "unf_scale", GX2_VAR_TYPE_VEC3, 1, scaleLocation, 0xffffffff });
|
||||
|
||||
colorLocation = 1;
|
||||
positionLocation = 0;
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_color", GX2_VAR_TYPE_VEC4, 0, colorLocation });
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
|
||||
|
||||
//! setup attribute streams
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), colorLocation, 1, 0, GX2_ATTRIB_FORMAT_8_8_8_8_UNORM);
|
||||
|
||||
//! create fetch shader
|
||||
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
|
||||
|
||||
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
|
||||
positionVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, cuPositionVtxsSize);
|
||||
if(positionVtxs)
|
||||
{
|
||||
//! position vertex structure
|
||||
int i = 0;
|
||||
positionVtxs[i++] = -1.0f; positionVtxs[i++] = -1.0f; positionVtxs[i++] = 0.0f;
|
||||
positionVtxs[i++] = 1.0f; positionVtxs[i++] = -1.0f; positionVtxs[i++] = 0.0f;
|
||||
positionVtxs[i++] = 1.0f; positionVtxs[i++] = 1.0f; positionVtxs[i++] = 0.0f;
|
||||
positionVtxs[i++] = -1.0f; positionVtxs[i++] = 1.0f; positionVtxs[i++] = 0.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, positionVtxs, cuPositionVtxsSize);
|
||||
}
|
||||
}
|
||||
|
||||
ColorShader::~ColorShader()
|
||||
{
|
||||
if(positionVtxs)
|
||||
{
|
||||
free(positionVtxs);
|
||||
positionVtxs = NULL;
|
||||
}
|
||||
|
||||
delete fetchShader;
|
||||
fetchShader = NULL;
|
||||
}
|
100
src/video/shaders/ColorShader.h
Normal file
100
src/video/shaders/ColorShader.h
Normal file
@ -0,0 +1,100 @@
|
||||
/****************************************************************************
|
||||
* 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 __COLOR_SHADER_H_
|
||||
#define __COLOR_SHADER_H_
|
||||
|
||||
#include "VertexShader.h"
|
||||
#include "PixelShader.h"
|
||||
#include "FetchShader.h"
|
||||
|
||||
class ColorShader : public Shader
|
||||
{
|
||||
private:
|
||||
ColorShader();
|
||||
virtual ~ColorShader();
|
||||
|
||||
static const u32 cuAttributeCount = 2;
|
||||
static const u32 cuPositionVtxsSize = 4 * cuVertexAttrSize;
|
||||
|
||||
static ColorShader *shaderInstance;
|
||||
|
||||
FetchShader *fetchShader;
|
||||
VertexShader vertexShader;
|
||||
PixelShader pixelShader;
|
||||
|
||||
f32 *positionVtxs;
|
||||
|
||||
u32 angleLocation;
|
||||
u32 offsetLocation;
|
||||
u32 scaleLocation;
|
||||
u32 colorLocation;
|
||||
u32 colorIntensityLocation;
|
||||
u32 positionLocation;
|
||||
public:
|
||||
static const u32 cuColorVtxsSize = 4 * cuColorAttrSize;
|
||||
|
||||
static ColorShader *instance() {
|
||||
if(!shaderInstance) {
|
||||
shaderInstance = new ColorShader();
|
||||
}
|
||||
return shaderInstance;
|
||||
}
|
||||
static void destroyInstance() {
|
||||
if(shaderInstance) {
|
||||
delete shaderInstance;
|
||||
shaderInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void setShaders(void) const
|
||||
{
|
||||
fetchShader->setShader();
|
||||
vertexShader.setShader();
|
||||
pixelShader.setShader();
|
||||
}
|
||||
|
||||
void setAttributeBuffer(const u8 * colorAttr, const f32 * posVtxs_in = NULL, const u32 & vtxCount = 0) const
|
||||
{
|
||||
if(posVtxs_in && vtxCount) {
|
||||
VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in);
|
||||
VertexShader::setAttributeBuffer(1, vtxCount * cuColorAttrSize, cuColorAttrSize, colorAttr);
|
||||
}
|
||||
else {
|
||||
VertexShader::setAttributeBuffer(0, cuPositionVtxsSize, cuVertexAttrSize, positionVtxs);
|
||||
VertexShader::setAttributeBuffer(1, cuColorVtxsSize, cuColorAttrSize, colorAttr);
|
||||
}
|
||||
}
|
||||
|
||||
void setAngle(const float & val)
|
||||
{
|
||||
VertexShader::setUniformReg(angleLocation, 4, &val);
|
||||
}
|
||||
void setOffset(const glm::vec3 & vec)
|
||||
{
|
||||
VertexShader::setUniformReg(offsetLocation, 4, &vec[0]);
|
||||
}
|
||||
void setScale(const glm::vec3 & vec)
|
||||
{
|
||||
VertexShader::setUniformReg(scaleLocation, 4, &vec[0]);
|
||||
}
|
||||
void setColorIntensity(const glm::vec4 & vec)
|
||||
{
|
||||
PixelShader::setUniformReg(colorIntensityLocation, 4, &vec[0]);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __COLOR_SHADER_H_
|
230
src/video/shaders/FXAAShader.cpp
Normal file
230
src/video/shaders/FXAAShader.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
/****************************************************************************
|
||||
* 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 "FXAAShader.h"
|
||||
|
||||
static const u32 cpVertexShaderProgram[] =
|
||||
{
|
||||
0x00000000,0x00008009,0x20000000,0x000004a0,
|
||||
0x3ca00000,0x88060094,0x00400000,0xff0f2094,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0xfd001f80,0x900c2060,0x0000803f,0x00000000,
|
||||
0xc1a229f5,0xd0eddc33,0x426618fd,0x8509cfe7
|
||||
};
|
||||
|
||||
static const u32 cpVertexShaderRegs[] = {
|
||||
0x00000102,0x00000000,0x00000000,0x00000001,
|
||||
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0x00000000,0xfffffffe,
|
||||
0x00000001,0x00000000,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x00000000,0x0000000e,0x00000010
|
||||
};
|
||||
|
||||
static const u32 cpPixelShaderProgram[] =
|
||||
{
|
||||
0x20000000,0x00003ca0,0xa0000000,0x000c8080,
|
||||
0x30000000,0x000010a1,0xa8000000,0x0010c080,
|
||||
0x75000000,0x000088a0,0x00800100,0x88062094,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00241f02,0x1000e00f,0x00241f00,0x1000e02f,
|
||||
0x00201f02,0x00000040,0x00201f00,0x00000060,
|
||||
0x00011f80,0x10332060,0xff000000,0xff102200,
|
||||
0xfd001f00,0x900cc020,0xffc09f01,0x90004040,
|
||||
0xffc01f01,0x90000060,0x00051f80,0x1033a040,
|
||||
0x0000803f,0x00000000,0xffe00f00,0x90004000,
|
||||
0xff008000,0xff102220,0xffe08f00,0x90000440,
|
||||
0x010c0000,0x010c4660,0xff008080,0xff004220,
|
||||
0x01a01f00,0x00280000,0x01a49f00,0x00280020,
|
||||
0x01a81f01,0x00280040,0xfd0c1f00,0x1028e06f,
|
||||
0x00208081,0x90002000,0x8716993e,0xa245163f,
|
||||
0xd578e93d,0x00000080,0x03a01f00,0x00280000,
|
||||
0x03a49f00,0x00280020,0x03a81f01,0x1028e04f,
|
||||
0xfd0c1f00,0x00280060,0x00a40081,0x90002020,
|
||||
0x8716993e,0xa245163f,0xd578e93d,0x00000080,
|
||||
0x04a01f00,0x00280000,0x04a49f00,0x1028a02f,
|
||||
0x04a81f01,0x00280040,0xfd0c1f00,0x00280060,
|
||||
0x7fcc1f80,0x1000c02f,0x8716993e,0xa245163f,
|
||||
0xd578e93d,0x00000080,0x02a01f00,0x1028e00f,
|
||||
0x02a49f00,0x00280020,0x02a81f01,0x00280040,
|
||||
0xfd0c1f00,0x00280060,0x7fcc1f80,0x1000e02f,
|
||||
0x8716993e,0xa245163f,0xd578e93d,0x00000080,
|
||||
0x7dc41f00,0x00020000,0x7fec0f01,0x00020020,
|
||||
0x7fc81f00,0x00000040,0x7dc41f00,0x00000060,
|
||||
0x7fec0f81,0x9001802f,0xfef88f00,0x1000e00f,
|
||||
0xfedc8f00,0x00000420,0x7de40f00,0x80010040,
|
||||
0x7ec49f01,0x00001060,0xfec41f80,0x10024060,
|
||||
0xfed49f00,0x80020000,0xfe141f00,0x900c802f,
|
||||
0xfeac1f00,0x80000040,0xfec01f02,0x80020060,
|
||||
0x7cc41f81,0x90010060,0x0000003d,0x00000000,
|
||||
0xfd001f00,0x900c6000,0xfea89f00,0x80010020,
|
||||
0xfec09f81,0x00020040,0x0000803f,0x0000003e,
|
||||
0xfec41f81,0x00000020,0xfe041f80,0x00330000,
|
||||
0x7fe01f00,0x80000040,0x7ce41f80,0x80000060,
|
||||
0xfea81f00,0x80010000,0xfeac1f80,0x80010020,
|
||||
0x000000c1,0x00000000,0xfea01f00,0x00020040,
|
||||
0xfea41f80,0x00020060,0x00000041,0x00000000,
|
||||
0x05c81f01,0x9000e00f,0x01cc9f81,0x9000e06f,
|
||||
0xfeac1f00,0x01004200,0xfea01f00,0x01044220,
|
||||
0xfeac9f00,0x01002240,0xfea09f00,0x01042260,
|
||||
0xfe8c1f80,0x01008600,0xacaa2a3e,0xaaaa2abe,
|
||||
0x7f9c1f00,0x0100a200,0x7f801f00,0x01048220,
|
||||
0x7f901f80,0x0104a240,0x02080001,0x7000a00f,
|
||||
0x02000000,0x7000c04f,0x02048000,0x7000e06f,
|
||||
0x01a81f80,0x9000e00f,0xd578e93d,0x00000000,
|
||||
0x04a80001,0x1000c00f,0x04a48000,0x00000020,
|
||||
0x04a00000,0x00000040,0xfe081f00,0xe00c0060,
|
||||
0xfe0c1f80,0xe00c0000,0x01a41f00,0x7f00620f,
|
||||
0xfea89f00,0xfe0c822f,0xfea49f00,0xff00a24f,
|
||||
0x7d001f80,0xe00c0060,0xa245163f,0x0000803e,
|
||||
0x7ea01f00,0xfe0ce20f,0x01a09f80,0xfe006a4f,
|
||||
0x0000803e,0x8716993e,0xfe088001,0x9001c00f,
|
||||
0xfe488001,0x1002e44f,0xfea01f80,0x80000000,
|
||||
0xd578e93d,0x00000000,0x7ca41f00,0x00280000,
|
||||
0x7da89f00,0x00280020,0xff201f00,0x00280040,
|
||||
0xfd081f80,0x00280060,0x8716993e,0xa245163f,
|
||||
0x00000080,0x00000000,0x7fc81f00,0x80060000,
|
||||
0xfec00f80,0x80060060,0xfec09f81,0xfb80634f,
|
||||
0xfe888f00,0x7e886300,0xfea80f01,0x7f8c6320,
|
||||
0xfee80f00,0x7d806340,0xfe680080,0x06846f60,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x10000100,0x01101df0,0x00008010,0xecdfea0d,
|
||||
0x10000200,0x03101df0,0x00002050,0xecdfea0d,
|
||||
0x10000000,0x04101df0,0x00003071,0xecdfea0d,
|
||||
0x10000200,0x02101df0,0x0000b070,0xecdfea0d,
|
||||
0x10000200,0x02101df0,0x00008010,0xecdfea0d,
|
||||
0x10000100,0x00101df0,0x0000a051,0xecdfea0d,
|
||||
0x10000400,0x04101df0,0x00008010,0xecdfea0d,
|
||||
0x10000500,0x05101df0,0x00000011,0xecdfea0d,
|
||||
0x10000100,0x01101df0,0x00008010,0xecdfea0d,
|
||||
0xfe2e963a,0x0269a9a3,0x38f88096,0x400cf48b
|
||||
};
|
||||
static const u32 cpPixelShaderRegs[] = {
|
||||
0x00000007,0x00000002,0x04000101,0x00000000,
|
||||
0x00000001,0x00000100,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x0000000f,0x00000001,0x00000010,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
FXAAShader * FXAAShader::shaderInstance = NULL;
|
||||
|
||||
FXAAShader::FXAAShader()
|
||||
: vertexShader(cuAttributeCount)
|
||||
{
|
||||
//! create pixel shader
|
||||
pixelShader.setProgram(cpPixelShaderProgram, sizeof(cpPixelShaderProgram), cpPixelShaderRegs, sizeof(cpPixelShaderRegs));
|
||||
|
||||
resolutionLocation = 0;
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_resolution", GX2_VAR_TYPE_VEC2, 1, resolutionLocation, 0xffffffff });
|
||||
|
||||
samplerLocation = 0;
|
||||
pixelShader.addSamplerVar((GX2SamplerVar){ "sampl_texture", GX2_SAMPLER_TYPE_2D, samplerLocation });
|
||||
|
||||
//! create vertex shader
|
||||
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
|
||||
|
||||
positionLocation = 0;
|
||||
texCoordLocation = 1;
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });
|
||||
|
||||
//! setup attribute streams
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);
|
||||
|
||||
//! create fetch shader
|
||||
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
|
||||
|
||||
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
|
||||
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
|
||||
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
|
||||
|
||||
//! position vertex structure and texture coordinate vertex structure
|
||||
int i = 0;
|
||||
posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = 1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = 1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = -1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);
|
||||
|
||||
i = 0;
|
||||
texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
|
||||
texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
|
||||
texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
|
||||
texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
|
||||
}
|
||||
|
||||
FXAAShader::~FXAAShader()
|
||||
{
|
||||
if(posVtxs)
|
||||
{
|
||||
free(posVtxs);
|
||||
posVtxs = NULL;
|
||||
}
|
||||
if(texCoords)
|
||||
{
|
||||
free(texCoords);
|
||||
texCoords = NULL;
|
||||
}
|
||||
|
||||
delete fetchShader;
|
||||
fetchShader = NULL;
|
||||
}
|
86
src/video/shaders/FXAAShader.h
Normal file
86
src/video/shaders/FXAAShader.h
Normal file
@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
* 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 __FXAA_SHADER_H_
|
||||
#define __FXAA_SHADER_H_
|
||||
|
||||
#include "VertexShader.h"
|
||||
#include "PixelShader.h"
|
||||
#include "FetchShader.h"
|
||||
|
||||
class FXAAShader : public Shader
|
||||
{
|
||||
public:
|
||||
static FXAAShader *instance() {
|
||||
if(!shaderInstance) {
|
||||
shaderInstance = new FXAAShader();
|
||||
}
|
||||
return shaderInstance;
|
||||
}
|
||||
static void destroyInstance() {
|
||||
if(shaderInstance) {
|
||||
delete shaderInstance;
|
||||
shaderInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void setShaders(void) const
|
||||
{
|
||||
fetchShader->setShader();
|
||||
vertexShader.setShader();
|
||||
pixelShader.setShader();
|
||||
}
|
||||
|
||||
void setAttributeBuffer() const
|
||||
{
|
||||
VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
|
||||
VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
|
||||
}
|
||||
|
||||
void setResolution(const glm::vec2 & vec)
|
||||
{
|
||||
PixelShader::setUniformReg(resolutionLocation, 4, &vec[0]);
|
||||
}
|
||||
|
||||
void setTextureAndSampler(const GX2Texture *texture, const GX2Sampler *sampler) const {
|
||||
GX2SetPixelTexture(texture, samplerLocation);
|
||||
GX2SetPixelSampler(sampler, samplerLocation);
|
||||
}
|
||||
|
||||
private:
|
||||
FXAAShader();
|
||||
virtual ~FXAAShader();
|
||||
|
||||
static const u32 cuAttributeCount = 2;
|
||||
static const u32 ciPositionVtxsSize = 4 * cuVertexAttrSize;
|
||||
static const u32 ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
|
||||
|
||||
static FXAAShader *shaderInstance;
|
||||
|
||||
FetchShader *fetchShader;
|
||||
VertexShader vertexShader;
|
||||
PixelShader pixelShader;
|
||||
|
||||
f32 *posVtxs;
|
||||
f32 *texCoords;
|
||||
|
||||
u32 samplerLocation;
|
||||
u32 positionLocation;
|
||||
u32 texCoordLocation;
|
||||
u32 resolutionLocation;
|
||||
};
|
||||
|
||||
#endif // __FXAA_SHADER_H_
|
58
src/video/shaders/FetchShader.h
Normal file
58
src/video/shaders/FetchShader.h
Normal file
@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
* 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 FETCH_SHADER_H
|
||||
#define FETCH_SHADER_H
|
||||
|
||||
#include "Shader.h"
|
||||
|
||||
class FetchShader : public Shader
|
||||
{
|
||||
public:
|
||||
FetchShader(GX2AttribStream * attributes, u32 attrCount, s32 type = GX2_FETCH_SHADER_TESSELATION_NONE, s32 tess = GX2_TESSELLATION_MODE_DISCRETE)
|
||||
: fetchShader(NULL)
|
||||
, fetchShaderProgramm(NULL)
|
||||
{
|
||||
u32 shaderSize = GX2CalcFetchShaderSizeEx(attrCount, type, tess);
|
||||
fetchShaderProgramm = memalign(GX2_SHADER_ALIGNMENT, shaderSize);
|
||||
if(fetchShaderProgramm)
|
||||
{
|
||||
fetchShader = new GX2FetchShader;
|
||||
GX2InitFetchShaderEx(fetchShader, fetchShaderProgramm, attrCount, attributes, type, tess);
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_SHADER, fetchShaderProgramm, shaderSize);
|
||||
}
|
||||
}
|
||||
virtual ~FetchShader() {
|
||||
if(fetchShaderProgramm)
|
||||
free(fetchShaderProgramm);
|
||||
if(fetchShader)
|
||||
delete fetchShader;
|
||||
}
|
||||
|
||||
GX2FetchShader *getFetchShader() const {
|
||||
return fetchShader;
|
||||
}
|
||||
|
||||
void setShader(void) const {
|
||||
GX2SetFetchShader(fetchShader);
|
||||
}
|
||||
|
||||
protected:
|
||||
GX2FetchShader *fetchShader;
|
||||
void *fetchShaderProgramm;
|
||||
};
|
||||
|
||||
#endif // FETCH_SHADER_H
|
150
src/video/shaders/PixelShader.h
Normal file
150
src/video/shaders/PixelShader.h
Normal file
@ -0,0 +1,150 @@
|
||||
/****************************************************************************
|
||||
* 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 PIXEL_SHADER_H
|
||||
#define PIXEL_SHADER_H
|
||||
|
||||
#include "Shader.h"
|
||||
|
||||
class PixelShader : public Shader
|
||||
{
|
||||
public:
|
||||
PixelShader()
|
||||
: pixelShader((GX2PixelShader*) memalign(0x40, sizeof(GX2PixelShader)))
|
||||
{
|
||||
if(pixelShader)
|
||||
{
|
||||
memset(pixelShader, 0, sizeof(GX2PixelShader));
|
||||
pixelShader->shader_mode = GX2_SHADER_MODE_UNIFORM_REGISTER;
|
||||
}
|
||||
}
|
||||
virtual ~PixelShader()
|
||||
{
|
||||
if(pixelShader)
|
||||
{
|
||||
if(pixelShader->shader_data)
|
||||
free(pixelShader->shader_data);
|
||||
|
||||
for(u32 i = 0; i < pixelShader->uniform_blocks_count; i++)
|
||||
free((void*)pixelShader->uniform_block[i].name);
|
||||
|
||||
if(pixelShader->uniform_block)
|
||||
free((void*)pixelShader->uniform_block);
|
||||
|
||||
for(u32 i = 0; i < pixelShader->uniform_vars_count; i++)
|
||||
free((void*)pixelShader->uniform_var[i].name);
|
||||
|
||||
if(pixelShader->uniform_var)
|
||||
free((void*)pixelShader->uniform_var);
|
||||
|
||||
if(pixelShader->initial_value)
|
||||
free((void*)pixelShader->initial_value);
|
||||
|
||||
for(u32 i = 0; i < pixelShader->sampler_vars_count; i++)
|
||||
free((void*)pixelShader->sampler_var[i].name);
|
||||
|
||||
if(pixelShader->sampler_var)
|
||||
free((void*)pixelShader->sampler_var);
|
||||
|
||||
if(pixelShader->loops_data)
|
||||
free((void*)pixelShader->loops_data);
|
||||
|
||||
free(pixelShader);
|
||||
}
|
||||
}
|
||||
|
||||
void setProgram(const u32 * program, const u32 & programSize, const u32 * regs, const u32 & regsSize)
|
||||
{
|
||||
if(!pixelShader)
|
||||
return;
|
||||
|
||||
//! this must be moved into an area where the graphic engine has access to and must be aligned to 0x100
|
||||
pixelShader->shader_size = programSize;
|
||||
pixelShader->shader_data = memalign(GX2_SHADER_ALIGNMENT, pixelShader->shader_size);
|
||||
if(pixelShader->shader_data)
|
||||
{
|
||||
memcpy(pixelShader->shader_data, program, pixelShader->shader_size);
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_SHADER, pixelShader->shader_data, pixelShader->shader_size);
|
||||
}
|
||||
|
||||
memcpy(pixelShader->regs, regs, regsSize);
|
||||
}
|
||||
|
||||
void addUniformVar(const GX2UniformVar & var)
|
||||
{
|
||||
if(!pixelShader)
|
||||
return;
|
||||
|
||||
u32 idx = pixelShader->uniform_vars_count;
|
||||
|
||||
GX2UniformVar* newVar = (GX2UniformVar*) malloc((pixelShader->uniform_vars_count + 1) * sizeof(GX2UniformVar));
|
||||
if(newVar)
|
||||
{
|
||||
if(pixelShader->uniform_var)
|
||||
{
|
||||
memcpy(newVar, pixelShader->uniform_var, pixelShader->uniform_vars_count * sizeof(GX2UniformVar));
|
||||
free(pixelShader->uniform_var);
|
||||
}
|
||||
pixelShader->uniform_var = newVar;
|
||||
|
||||
memcpy(pixelShader->uniform_var + idx, &var, sizeof(GX2UniformVar));
|
||||
pixelShader->uniform_var[idx].name = (char*) malloc(strlen(var.name) + 1);
|
||||
strcpy((char*)pixelShader->uniform_var[idx].name, var.name);
|
||||
|
||||
pixelShader->uniform_vars_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void addSamplerVar(const GX2SamplerVar & var)
|
||||
{
|
||||
if(!pixelShader)
|
||||
return;
|
||||
|
||||
u32 idx = pixelShader->sampler_vars_count;
|
||||
|
||||
GX2SamplerVar* newVar = (GX2SamplerVar*) malloc((pixelShader->sampler_vars_count + 1) * sizeof(GX2SamplerVar));
|
||||
if(newVar)
|
||||
{
|
||||
if(pixelShader->sampler_var)
|
||||
{
|
||||
memcpy(newVar, pixelShader->sampler_var, pixelShader->sampler_vars_count * sizeof(GX2SamplerVar));
|
||||
free(pixelShader->sampler_var);
|
||||
}
|
||||
pixelShader->sampler_var = newVar;
|
||||
|
||||
memcpy(pixelShader->sampler_var + idx, &var, sizeof(GX2SamplerVar));
|
||||
pixelShader->sampler_var[idx].name = (char*) malloc(strlen(var.name) + 1);
|
||||
strcpy((char*)pixelShader->sampler_var[idx].name, var.name);
|
||||
|
||||
pixelShader->sampler_vars_count++;
|
||||
}
|
||||
}
|
||||
GX2PixelShader * getPixelShader() const {
|
||||
return pixelShader;
|
||||
}
|
||||
|
||||
void setShader(void) const {
|
||||
GX2SetPixelShader(pixelShader);
|
||||
}
|
||||
|
||||
static inline void setUniformReg(u32 location, u32 size, const void * reg) {
|
||||
GX2SetPixelUniformReg(location, size, reg);
|
||||
}
|
||||
protected:
|
||||
GX2PixelShader *pixelShader;
|
||||
};
|
||||
|
||||
#endif // PIXEL_SHADER_H
|
74
src/video/shaders/Shader.h
Normal file
74
src/video/shaders/Shader.h
Normal file
@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
* 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 SHADER_H_
|
||||
#define SHADER_H_
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/gtc/matrix_transform.hpp"
|
||||
#include "dynamic_libs/gx2_functions.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
class Shader
|
||||
{
|
||||
protected:
|
||||
Shader() {}
|
||||
virtual ~Shader() {}
|
||||
public:
|
||||
static const u16 cuVertexAttrSize = sizeof(f32) * 3;
|
||||
static const u16 cuTexCoordAttrSize = sizeof(f32) * 2;
|
||||
static const u16 cuColorAttrSize = sizeof(u8) * 4;
|
||||
|
||||
static void setLineWidth(const f32 & width) {
|
||||
GX2SetLineWidth(width);
|
||||
}
|
||||
|
||||
static void draw(s32 primitive = GX2_PRIMITIVE_QUADS, u32 vtxCount = 4)
|
||||
{
|
||||
switch(primitive)
|
||||
{
|
||||
default:
|
||||
case GX2_PRIMITIVE_QUADS:
|
||||
{
|
||||
GX2DrawEx(GX2_PRIMITIVE_QUADS, vtxCount, 0, 1);
|
||||
break;
|
||||
}
|
||||
case GX2_PRIMITIVE_TRIANGLES:
|
||||
{
|
||||
GX2DrawEx(GX2_PRIMITIVE_TRIANGLES, vtxCount, 0, 1);
|
||||
break;
|
||||
}
|
||||
case GX2_PRIMITIVE_TRIANGLE_FAN:
|
||||
{
|
||||
GX2DrawEx(GX2_PRIMITIVE_TRIANGLE_FAN, vtxCount, 0, 1);
|
||||
break;
|
||||
}
|
||||
case GX2_PRIMITIVE_LINES:
|
||||
{
|
||||
GX2DrawEx(GX2_PRIMITIVE_LINES, vtxCount, 0, 1);
|
||||
break;
|
||||
}
|
||||
case GX2_PRIMITIVE_LINE_STRIP:
|
||||
{
|
||||
GX2DrawEx(GX2_PRIMITIVE_LINE_STRIP, vtxCount, 0, 1);
|
||||
break;
|
||||
}
|
||||
//! TODO: add other primitives later
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHADER_H_
|
266
src/video/shaders/Shader3D.cpp
Normal file
266
src/video/shaders/Shader3D.cpp
Normal file
@ -0,0 +1,266 @@
|
||||
/****************************************************************************
|
||||
* 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 "Shader3D.h"
|
||||
|
||||
static const u32 cpVertexShaderProgram[] =
|
||||
{
|
||||
0x00000000,0x00008009,0x20000000,0x0000e4a1,
|
||||
0x00c00100,0x88048093,0x01c00300,0x98060014,
|
||||
0x9a000000,0x000058a0,0x3c200200,0x88062094,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x0765a101,0x9000e00f,0x0761a101,0x9000e02f,
|
||||
0x01081f00,0x900ce040,0x01041f00,0x900ce060,
|
||||
0x01001f80,0x900ce000,0x02001f00,0x900c6000,
|
||||
0x02041f00,0x900c6020,0x076da101,0x9000e04f,
|
||||
0x0769a181,0x9000e06f,0x0745a101,0x9000c00f,
|
||||
0x0741a181,0x9000c02f,0x074da101,0x9000c04f,
|
||||
0x0749a181,0x9000c06f,0x0bc9a000,0x7f00e20f,
|
||||
0x0bc92080,0x7f04e22f,0x0bc9a001,0x7f08e24f,
|
||||
0x0bc92081,0x7f0ce26f,0x0725a101,0x9000a00f,
|
||||
0x0721a181,0x9000a02f,0x072da101,0x9000a04f,
|
||||
0x0729a181,0x9000a06f,0x0ac9a000,0x7e00c20f,
|
||||
0x0ac92080,0x7e04c22f,0x0ac9a001,0x7e08c24f,
|
||||
0x0ac92081,0x7e0cc26f,0x0ba5a000,0x7f00e20f,
|
||||
0x0ba52080,0x7f04e22f,0x0ba5a001,0x7f08e24f,
|
||||
0x0ba52081,0x7f0ce26f,0x08eda000,0x9000800f,
|
||||
0x08ed2080,0x9000802f,0x08eda001,0x9000804f,
|
||||
0x08ed2081,0x9000806f,0x09c9a000,0x7d00a20f,
|
||||
0x09c92080,0x7d04a22f,0x09c9a001,0x7d08a24f,
|
||||
0x09c92081,0x7d0ca26f,0x0aa5a000,0x7e00c20f,
|
||||
0x0aa52080,0x7e04c22f,0x0aa5a001,0x7e08c24f,
|
||||
0x0aa52081,0x7e0cc26f,0x0b81a000,0x7f004200,
|
||||
0x0b812080,0x7f044220,0x0b81a001,0x7f082240,
|
||||
0x0b812081,0x7f0c0260,0x08c9a000,0x7c00820f,
|
||||
0x08c92080,0x7c04822f,0x08c9a001,0x7c08824f,
|
||||
0x08c92081,0x7c0c826f,0x09a5a000,0x7d00a20f,
|
||||
0x09a52080,0x7d04a22f,0x09a5a001,0x7d08a24f,
|
||||
0x09a52081,0x7d0ca26f,0x0a81a000,0x7e000200,
|
||||
0x0a812080,0x7e040220,0x0a81a001,0x7e080240,
|
||||
0x0a812081,0x7e0c2260,0x0240a001,0x9000c00f,
|
||||
0x0244a001,0x9000c02f,0x0148a001,0x9000c04f,
|
||||
0x004ca001,0x9000c06f,0x0264a081,0x9000e02f,
|
||||
0x0260a001,0x9000e00f,0x0224a001,0x90002020,
|
||||
0x0168a001,0x9000e04f,0x006ca001,0x9000e06f,
|
||||
0x0220a081,0x90002000,0x08a5a000,0x7c00820f,
|
||||
0x08a52080,0x7c04822f,0x08a5a001,0x7c08824f,
|
||||
0x08a52081,0x7c0c826f,0x0981a000,0x7d008200,
|
||||
0x09812080,0x7d048220,0x0981a001,0x7d084240,
|
||||
0x09812081,0x7d0c4260,0x02090000,0x7e00c20f,
|
||||
0x02098000,0x7e04c22f,0x0128a001,0x9000a04f,
|
||||
0x002ca001,0x9000c06f,0x02298081,0x7e0caa6f,
|
||||
0x03090000,0x7f00e20f,0x03098000,0x7f04e22f,
|
||||
0x02090001,0x7e08f64f,0x03298001,0x7f0ce26f,
|
||||
0x03090081,0x7f08ca4f,0x0881a000,0x7c00c200,
|
||||
0x08812080,0x7c04e220,0x0881a001,0x7c08a240,
|
||||
0x08812081,0x7c0c8260,0x0200a001,0x9000800f,
|
||||
0x0204a001,0x9000802f,0x0108a001,0x9000804f,
|
||||
0x000ca001,0x9000806f,0x01098080,0x0104aa2f,
|
||||
0x01090000,0x0100a20f,0x02858000,0x7e04c22f,
|
||||
0x01090001,0x7d08a24f,0x01298081,0x7e0cc26f,
|
||||
0x02850000,0x7e00f60f,0x03858000,0x7f04622f,
|
||||
0x02450001,0x7f08e24f,0x02458001,0x7d0ca26f,
|
||||
0x03850080,0x7f00ca0f,0x00090000,0x7c004200,
|
||||
0x00098000,0x7c04b220,0x03450001,0x7e08c24f,
|
||||
0x03458001,0x7f0ce26f,0x03e18080,0xfe042620,
|
||||
0x01850000,0x7d00a200,0x01858000,0x7d04622f,
|
||||
0x00090001,0x7c086240,0x00298081,0x7c0c0260,
|
||||
0x02c10000,0x7f000200,0x02e18000,0x7e040620,
|
||||
0x01450001,0x7d088240,0x01458001,0x7e0c6260,
|
||||
0x01e18080,0xfe04c620,0x03c10000,0x7e002200,
|
||||
0x03818001,0x7f0c4220,0x02a10001,0x7f081640,
|
||||
0x02818001,0x7d0c3660,0x03a10081,0x7e082a40,
|
||||
0x07080000,0x0100c20f,0x07088000,0x0104622f,
|
||||
0x00458001,0x000cea4f,0x07288081,0x0204f66f,
|
||||
0x00850000,0x0200620f,0x00858000,0x05046a2f,
|
||||
0x07080001,0x0108c24f,0x01818001,0x030c726f,
|
||||
0x07cc8080,0xfe04c22f,0x01c10000,0x0500660f,
|
||||
0x00e18000,0xfe04622f,0x00450001,0x0308624f,
|
||||
0x07cc9f01,0x7f0ce26f,0x00c10080,0xfe00e60f,
|
||||
0x07cc1f00,0x7e00660f,0x00a10001,0xfe08c22f,
|
||||
0x01a10001,0x0408624f,0x00818001,0x7f086a6f,
|
||||
0x07c09f80,0x7e048200,0x07e00f00,0xfe008220,
|
||||
0x07cc1f01,0x7e086a4f,0x07c09f81,0x7f0c8240,
|
||||
0x07c08f80,0xfe088260,0x2c34800d,0xe3b4f15e,
|
||||
0x7642ed30,0x7408600d
|
||||
};
|
||||
|
||||
static const u32 cpVertexShaderRegs[] = {
|
||||
0x00000108,0x00000000,0x00000002,0x00000001,
|
||||
0xffff0001,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0x00000000,0xfffffffc,
|
||||
0x00000002,0x00000000,0x00000001,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x00000000,0x0000000e,0x00000010
|
||||
};
|
||||
|
||||
static const u32 cPixelShaderProgram[] =
|
||||
{
|
||||
0x20000000,0x000008a4,0x03000000,0x01004085,
|
||||
0x23000000,0x000044a8,0x35000000,0x000000a4,
|
||||
0x06000000,0x01004085,0x36000000,0x00002ca8,
|
||||
0x50000000,0x0000c080,0x42000000,0x00001ca0,
|
||||
0x00800000,0x88062094,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0xfd001f80,0x900c0060,0x0000803f,0x00000000,
|
||||
0x02011f80,0x8c110000,0xf8402000,0x9006a00f,
|
||||
0x02552001,0x00000020,0x01248082,0x80020060,
|
||||
0xfe3c1f00,0x1000e04f,0xfe041f80,0x1033c00f,
|
||||
0xfe482081,0x80060020,0xfee40f81,0x0289e30f,
|
||||
0x02c51f80,0x80060060,0xfeec0f80,0x0285634f,
|
||||
0xfec80f80,0x80000060,0xfe4ca081,0x9000e04f,
|
||||
0xfe281f00,0x80060000,0xf8c01f81,0x9006e02f,
|
||||
0xfee00f81,0xfd80636f,0x0000803f,0x00000000,
|
||||
0x7fc49f81,0xf880e34f,0xfe381f80,0x00000000,
|
||||
0x7de00f81,0xfe800360,0x01011f80,0x8c100000,
|
||||
0x00a81f00,0x9000e02f,0x00000082,0x80020060,
|
||||
0x00002040,0x00000000,0xfeac9f80,0xfd00624f,
|
||||
0x3333333f,0x00002040,0xfee88f80,0x0101620f,
|
||||
0x00cc1f80,0x9000e06f,0xf8c09f01,0x80060020,
|
||||
0xfe2c1f80,0x9006e04f,0xfee48f81,0xf880630f,
|
||||
0x7fc81f80,0xfd800360,0x0000803f,0x00000000,
|
||||
0x000ca001,0x80000000,0x00091f00,0x800c0020,
|
||||
0x00051f00,0x800c0040,0x00011f80,0x800c0060,
|
||||
0xfe2c0000,0x90002000,0xfe288000,0x90002020,
|
||||
0xfe240001,0x90002040,0xfe208081,0x90002060,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x10000100,0x01100df0,0x00008010,0xecdfea0d,
|
||||
0x99720984,0x041cab0d,0xa28a9ccd,0x95d199a5
|
||||
};
|
||||
static const u32 cPixelShaderRegs[] = {
|
||||
0x00000102,0x00000002,0x14000002,0x00000000,
|
||||
0x00000002,0x00000100,0x00000101,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x0000000f,0x00000001,0x00000010,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
Shader3D * Shader3D::shaderInstance = NULL;
|
||||
|
||||
Shader3D::Shader3D()
|
||||
: vertexShader(cuAttributeCount)
|
||||
{
|
||||
//! create pixel shader
|
||||
pixelShader.setProgram(cPixelShaderProgram, sizeof(cPixelShaderProgram), cPixelShaderRegs, sizeof(cPixelShaderRegs));
|
||||
|
||||
colorIntensityLocation = 0;
|
||||
fadeDistanceLocation = 4;
|
||||
fadeOutLocation = 8;
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_color_intensity", GX2_VAR_TYPE_VEC4, 1, colorIntensityLocation, 0xffffffff });
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_fade_distance", GX2_VAR_TYPE_FLOAT, 1, fadeDistanceLocation, 0xffffffff });
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_fade_out_alpha", GX2_VAR_TYPE_VEC4, 1, fadeOutLocation, 0xffffffff });
|
||||
|
||||
samplerLocation = 0;
|
||||
pixelShader.addSamplerVar((GX2SamplerVar){ "sampl_texture", GX2_SAMPLER_TYPE_2D, samplerLocation });
|
||||
|
||||
//! create vertex shader
|
||||
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
|
||||
|
||||
modelMatrixLocation = 0;
|
||||
projectionMatrixLocation = 16;
|
||||
viewMatrixLocation = 32;
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "modelMatrix", GX2_VAR_TYPE_MAT4, 1, modelMatrixLocation, 0xffffffff });
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "viewMatrix", GX2_VAR_TYPE_MAT4, 1, projectionMatrixLocation, 0xffffffff });
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "projectionMatrix", GX2_VAR_TYPE_MAT4, 1, viewMatrixLocation, 0xffffffff });
|
||||
|
||||
positionLocation = 0;
|
||||
texCoordLocation = 1;
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });
|
||||
|
||||
//! setup attribute streams
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);
|
||||
|
||||
//! create fetch shader
|
||||
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
|
||||
|
||||
//! initialize default quad texture vertexes as those are very commonly used
|
||||
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
|
||||
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
|
||||
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
|
||||
|
||||
//! position vertex structure and texture coordinate vertex structure
|
||||
int i = 0;
|
||||
posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = 1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = 1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = -1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);
|
||||
|
||||
i = 0;
|
||||
texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
|
||||
texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
|
||||
texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
|
||||
texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
|
||||
}
|
||||
|
||||
Shader3D::~Shader3D()
|
||||
{
|
||||
if(posVtxs)
|
||||
{
|
||||
free(posVtxs);
|
||||
posVtxs = NULL;
|
||||
}
|
||||
if(texCoords)
|
||||
{
|
||||
free(texCoords);
|
||||
texCoords = NULL;
|
||||
}
|
||||
|
||||
delete fetchShader;
|
||||
fetchShader = NULL;
|
||||
}
|
119
src/video/shaders/Shader3D.h
Normal file
119
src/video/shaders/Shader3D.h
Normal file
@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
* 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 SHADER_3D_H_
|
||||
#define SHADER_3D_H_
|
||||
|
||||
#include "VertexShader.h"
|
||||
#include "PixelShader.h"
|
||||
#include "FetchShader.h"
|
||||
|
||||
class Shader3D : public Shader
|
||||
{
|
||||
private:
|
||||
Shader3D();
|
||||
virtual ~Shader3D();
|
||||
|
||||
static Shader3D * shaderInstance;
|
||||
|
||||
static const unsigned char cuAttributeCount = 2;
|
||||
static const u32 ciPositionVtxsSize = 4 * cuVertexAttrSize;
|
||||
static const u32 ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
|
||||
|
||||
FetchShader *fetchShader;
|
||||
VertexShader vertexShader;
|
||||
PixelShader pixelShader;
|
||||
|
||||
f32 *posVtxs;
|
||||
f32 *texCoords;
|
||||
|
||||
u32 modelMatrixLocation;
|
||||
u32 viewMatrixLocation;
|
||||
u32 projectionMatrixLocation;
|
||||
u32 positionLocation;
|
||||
u32 texCoordLocation;
|
||||
|
||||
u32 colorIntensityLocation;
|
||||
u32 fadeDistanceLocation;
|
||||
u32 fadeOutLocation;
|
||||
u32 samplerLocation;
|
||||
public:
|
||||
static Shader3D *instance() {
|
||||
if(!shaderInstance) {
|
||||
shaderInstance = new Shader3D();
|
||||
}
|
||||
return shaderInstance;
|
||||
}
|
||||
static void destroyInstance() {
|
||||
if(shaderInstance) {
|
||||
delete shaderInstance;
|
||||
shaderInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void setShaders(void) const
|
||||
{
|
||||
fetchShader->setShader();
|
||||
vertexShader.setShader();
|
||||
pixelShader.setShader();
|
||||
}
|
||||
|
||||
void setAttributeBuffer(const u32 & vtxCount = 0, const f32 * posVtxs_in = NULL, const f32 * texCoords_in = NULL) const
|
||||
{
|
||||
if(posVtxs_in && texCoords_in && vtxCount)
|
||||
{
|
||||
VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in);
|
||||
VertexShader::setAttributeBuffer(1, vtxCount * cuTexCoordAttrSize, cuTexCoordAttrSize, texCoords_in);
|
||||
}
|
||||
else {
|
||||
//! use default quad vertex and texture coordinates if nothing is passed
|
||||
VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
|
||||
VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
|
||||
}
|
||||
}
|
||||
|
||||
void setProjectionMtx(const glm::mat4 & mtx)
|
||||
{
|
||||
VertexShader::setUniformReg(projectionMatrixLocation, 16, &mtx[0][0]);
|
||||
}
|
||||
void setViewMtx(const glm::mat4 & mtx)
|
||||
{
|
||||
VertexShader::setUniformReg(viewMatrixLocation, 16, &mtx[0][0]);
|
||||
}
|
||||
void setModelViewMtx(const glm::mat4 & mtx)
|
||||
{
|
||||
VertexShader::setUniformReg(modelMatrixLocation, 16, &mtx[0][0]);
|
||||
}
|
||||
void setColorIntensity(const glm::vec4 & vec)
|
||||
{
|
||||
PixelShader::setUniformReg(colorIntensityLocation, 4, &vec[0]);
|
||||
}
|
||||
void setAlphaFadeOut(const glm::vec4 & vec)
|
||||
{
|
||||
PixelShader::setUniformReg(fadeOutLocation, 4, &vec[0]);
|
||||
}
|
||||
void setDistanceFadeOut(const float & value)
|
||||
{
|
||||
PixelShader::setUniformReg(fadeDistanceLocation, 4, &value);
|
||||
}
|
||||
|
||||
void setTextureAndSampler(const GX2Texture *texture, const GX2Sampler *sampler) const {
|
||||
GX2SetPixelTexture(texture, samplerLocation);
|
||||
GX2SetPixelSampler(sampler, samplerLocation);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHADER_3D_H_
|
373
src/video/shaders/ShaderFractalColor.cpp
Normal file
373
src/video/shaders/ShaderFractalColor.cpp
Normal file
@ -0,0 +1,373 @@
|
||||
/****************************************************************************
|
||||
* 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 "ShaderFractalColor.h"
|
||||
|
||||
static const u32 cpVertexShaderProgram[] =
|
||||
{
|
||||
0x00000000,0x00008009,0x20000000,0x0000eca1,
|
||||
0x00c00000,0x88068093,0x01400200,0x9a048013,
|
||||
0x9c000000,0x000044a0,0x3c200000,0x88060094,
|
||||
0x02400000,0x88062014,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x0765a101,0x9000e00f,0x0761a101,0x9000e02f,
|
||||
0x03001f00,0x900c8040,0x03041f80,0x900c8060,
|
||||
0x076da101,0x9000e04f,0x0769a181,0x9000e06f,
|
||||
0x0745a101,0x9000c00f,0x0741a181,0x9000c02f,
|
||||
0x074da101,0x9000c04f,0x0749a181,0x9000c06f,
|
||||
0x0bc9a000,0x7f00e20f,0x0bc92080,0x7f04e22f,
|
||||
0x0bc9a001,0x7f08e24f,0x0bc92081,0x7f0ce26f,
|
||||
0x0725a101,0x9000a00f,0x0721a181,0x9000a02f,
|
||||
0x072da101,0x9000a04f,0x0729a181,0x9000a06f,
|
||||
0x0ac9a000,0x7e00c20f,0x0ac92080,0x7e04c22f,
|
||||
0x0ac9a001,0x7e08c24f,0x0ac92081,0x7e0cc26f,
|
||||
0x0ba5a000,0x7f00e20f,0x0ba52080,0x7f04e22f,
|
||||
0x0ba5a001,0x7f08e24f,0x0ba52081,0x7f0ce26f,
|
||||
0x08eda000,0x9000800f,0x08ed2080,0x9000802f,
|
||||
0x08eda001,0x9000804f,0x08ed2081,0x9000806f,
|
||||
0x09c9a000,0x7d00a20f,0x09c92080,0x7d04a22f,
|
||||
0x09c9a001,0x7d08a24f,0x09c92081,0x7d0ca26f,
|
||||
0x0aa5a000,0x7e00c20f,0x0aa52080,0x7e04c22f,
|
||||
0x0aa5a001,0x7e08c24f,0x0aa52081,0x7e0cc26f,
|
||||
0x0b81a000,0x7f006200,0x0b812080,0x7f046220,
|
||||
0x0b81a001,0x7f080240,0x0b812081,0x7f0c0260,
|
||||
0x08c9a000,0x7c00820f,0x08c92080,0x7c04822f,
|
||||
0x08c9a001,0x7c08824f,0x08c92081,0x7c0c826f,
|
||||
0x09a5a000,0x7d00a20f,0x09a52080,0x7d04a22f,
|
||||
0x09a5a001,0x7d08a24f,0x09a52081,0x7d0ca26f,
|
||||
0x0a81a000,0x7e008200,0x0a812080,0x7e048220,
|
||||
0x0a81a001,0x7e086240,0x0a812081,0x7e0c4260,
|
||||
0x0340a001,0x9000c00f,0x0344a001,0x9000c02f,
|
||||
0x0048a001,0x9000c04f,0x004ca001,0x9000c06f,
|
||||
0x0364a081,0x9000e02f,0x0360a001,0x9000e00f,
|
||||
0x0324a001,0x90000020,0x0068a001,0x9000e04f,
|
||||
0x006ca001,0x9000e06f,0x0320a081,0x90000000,
|
||||
0x08a5a000,0x7c00820f,0x08a52080,0x7c04822f,
|
||||
0x08a5a001,0x7c08824f,0x08a52081,0x7c0c826f,
|
||||
0x0981a000,0x7d00a200,0x09812080,0x7d04a220,
|
||||
0x0981a001,0x7d08a240,0x09812081,0x7d0c6260,
|
||||
0x02890000,0x7e00c20f,0x02898000,0x7e04c22f,
|
||||
0x0028a001,0x9000a04f,0x002ca001,0x9000c06f,
|
||||
0x02498081,0x7e0caa6f,0x03890000,0x7f00e20f,
|
||||
0x03898000,0x7f04e22f,0x02690001,0x7e08f64f,
|
||||
0x03498001,0x7f0ce26f,0x03690081,0x7f08ca4f,
|
||||
0x0881a000,0x7c00c200,0x08812080,0x7c04c220,
|
||||
0x0881a001,0x7c08e240,0x08812081,0x7c0ca260,
|
||||
0x0300a001,0x9000800f,0x0304a001,0x9000802f,
|
||||
0x0008a001,0x9000804f,0x000ca001,0x9000806f,
|
||||
0x01898080,0x0004aa2f,0x01890000,0x0000a20f,
|
||||
0x02a58000,0x7e04c22f,0x01690001,0x7d08a24f,
|
||||
0x01498081,0x7e0cc26f,0x02a50000,0x7e00f60f,
|
||||
0x03a58000,0x7f04622f,0x02a50001,0x7f08e24f,
|
||||
0x02658001,0x7d0ca26f,0x03a50080,0x7f00ca0f,
|
||||
0x00890000,0x7c00820f,0x00898000,0x7c049220,
|
||||
0x03a50001,0x7e08c24f,0x03658001,0x7f0ce26f,
|
||||
0x03c18080,0xfe04862f,0x01a50000,0x7d008200,
|
||||
0x01a58000,0x7d04622f,0x00690001,0x7c086240,
|
||||
0x00498081,0x7c0c4260,0x02c10000,0x7f00e20f,
|
||||
0x02c18000,0x7e04c62f,0x01a50001,0x7d080240,
|
||||
0x01658001,0x7e0c0260,0x01c18080,0xfe040620,
|
||||
0x03c10000,0x7e00620f,0x03a18001,0x7f0c622f,
|
||||
0x02e10001,0x7f08764f,0x02a18001,0x7d0c766f,
|
||||
0x03e10081,0x7e084a0f,0x02e80f00,0xfe000e00,
|
||||
0x02c88f00,0x7c046220,0x02c81f01,0xff00c240,
|
||||
0x02c89f01,0xfe04c260,0x00a50080,0x7c00aa00,
|
||||
0x01c10000,0x0400760f,0x00a58000,0x0404622f,
|
||||
0x00a50001,0x0308e24f,0x00658001,0x020c626f,
|
||||
0x00c10080,0x0500ea0f,0x02c41f00,0x0000620f,
|
||||
0x00c18000,0xfe04c22f,0x01e10001,0x0008624f,
|
||||
0x01a18001,0x000c666f,0x00a18081,0xfe0ce66f,
|
||||
0x00e10001,0x7f08620f,0x02048000,0x03046a2f,
|
||||
0x02c41f01,0x06086a4f,0x02c49f01,0x060c6a6f,
|
||||
0x02e00f80,0xfe000220,0x02c08f00,0xfe040200,
|
||||
0x02e08f01,0xfe0c0240,0x02c01f80,0xfe080260,
|
||||
0x8aa480ad,0x2bfc5ca6,0xb5e05b5b,0xd48dc71c
|
||||
};
|
||||
|
||||
static const u32 cpVertexShaderRegs[] = {
|
||||
0x00000108,0x00000000,0x00000004,0x00000001,
|
||||
0xff000201,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0x00000000,0xfffffff8,
|
||||
0x00000003,0x00000001,0x00000000,0x00000002,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x00000000,0x0000000e,0x00000010
|
||||
};
|
||||
|
||||
static const u32 cpPixelShaderProgram[] =
|
||||
{
|
||||
0x20000000,0x000008a4,0x04000000,0x01004085,
|
||||
0x23000000,0x0000eca1,0x9f000000,0x0000e0a8,
|
||||
0xd8000000,0x000000a4,0x07000000,0x01004085,
|
||||
0xd9000000,0x000048a8,0xec000000,0x000000a4,
|
||||
0x0a000000,0x01004085,0xed000000,0x000050a8,
|
||||
0x02010000,0x000030a0,0x00000000,0x88062094,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0xfd001f80,0x900c0060,0x0000803f,0x00000000,
|
||||
0x03011f80,0x8c210000,0xfd001f00,0x900c0000,
|
||||
0xfd001f00,0x900ca02f,0x00000002,0x80020040,
|
||||
0x00048002,0x80020060,0xf8001f80,0x900cc04f,
|
||||
0x0000803f,0x00000000,0xfea81f00,0x9000e00f,
|
||||
0xfeac1f00,0x9000e02f,0xf8001f00,0x900c804f,
|
||||
0xf8001f80,0x900ca06f,0x00000040,0x00000000,
|
||||
0xfea01f00,0x00280000,0xfea41f00,0x00280020,
|
||||
0xfe041f00,0x00280040,0xfd041f80,0x00280060,
|
||||
0xaf67bb3e,0x00000080,0x7fc41f00,0x00000000,
|
||||
0x7fc01f80,0x00000020,0xfe041f00,0x100ac00f,
|
||||
0xfe001f80,0x100ac02f,0xfea01f00,0x00280000,
|
||||
0xfea41f00,0x00280020,0xfe041f00,0x00280040,
|
||||
0xfd041f00,0x1028e06f,0x7fc01f82,0x00000000,
|
||||
0x8c65583e,0x00000080,0x7ea41f00,0x80000000,
|
||||
0x7ea01f00,0x80000020,0xfee01f00,0x10006040,
|
||||
0x7fc48f82,0x00000860,0xa7c4623b,0x00000000,
|
||||
0xfea81f00,0x1000e00f,0x7fcc9f01,0x10006020,
|
||||
0xfe001f00,0x000a0040,0xfe041f00,0x000a0060,
|
||||
0xfea89f80,0x10008040,0x8c65583e,0x3acd13bf,
|
||||
0xfeb81f00,0x7e04c20f,0xfebc1f00,0x7e00822f,
|
||||
0x03c89f00,0x80060040,0xfea49f00,0x1000e06f,
|
||||
0xfea41f81,0x10006060,0x00809043,0x8c65583e,
|
||||
0x3acd13bf,0x00000000,0xfea81f00,0xf880a30f,
|
||||
0xfe001f00,0x900ca02f,0x7dc41f00,0x1000e04f,
|
||||
0xfe081f00,0xfd80636f,0x04081f80,0x900c800f,
|
||||
0x0000803f,0x00000000,0xfea81f00,0xf900620f,
|
||||
0xfea41f00,0xf900622f,0xfe0c1f00,0x900ca04f,
|
||||
0xfec00f00,0x1000c46f,0xfefc0f80,0x10006000,
|
||||
0x00000842,0x00000000,0xfeac1f00,0xf900620f,
|
||||
0x7fc81f00,0x9000c02f,0x7dc49f00,0x9000e04f,
|
||||
0x7df08f01,0x10008060,0x030c1f80,0x900ca02f,
|
||||
0x00000842,0x00000000,0xfea41f00,0x80000000,
|
||||
0x7ecc1f00,0x9000e02f,0x7e688000,0x80000040,
|
||||
0xfea81f00,0x80000060,0x7d6c8081,0x80000000,
|
||||
0xa7c4623b,0x00000000,0xfe001f00,0x000a0000,
|
||||
0xfe0c1f00,0x000a0020,0xfea41f00,0x80000040,
|
||||
0x03648000,0xfe08626f,0x7d648081,0xff00420f,
|
||||
0xa7c4623b,0x00000000,0xfeb01f00,0x7e04620f,
|
||||
0xfeb41f00,0x7f08662f,0x7c800001,0xff006e4f,
|
||||
0xfe081f00,0x000a0060,0x03680081,0xfe0c4e0f,
|
||||
0x00809043,0x00000000,0xfebc1f00,0x7f04620f,
|
||||
0x7cc41f00,0x00000020,0x7cc49f00,0x1000e04f,
|
||||
0xff901f00,0x00000060,0xfe981f80,0x00000000,
|
||||
0x00809043,0x00000000,0xfea81f00,0xf900620f,
|
||||
0x7cc41f00,0x00000020,0x00c09f00,0x1000c04f,
|
||||
0xfe0c1f00,0x80010060,0xff001f80,0x80010000,
|
||||
0x00000842,0x00000000,0xfea81f00,0xf900620f,
|
||||
0xfecc9f01,0x80000020,0x7fc81f00,0x9000e04f,
|
||||
0x7dc89f00,0x1000c86f,0xffe01f80,0x80000000,
|
||||
0x00000842,0x00000000,0xfeac1f00,0xf900620f,
|
||||
0x7ec81f00,0x9000802f,0xfec49f00,0x9000a040,
|
||||
0xfea89f00,0x80000060,0xffe01f80,0x9000a060,
|
||||
0x00000842,0xa7c4623b,0xfea41f00,0x80000000,
|
||||
0x7ecc1f00,0x9000e02f,0xfe0c1f00,0x000a0040,
|
||||
0x7c888081,0x80000000,0xa7c4623b,0x00000000,
|
||||
0xfe001f00,0x000a0000,0xfeb81f00,0x7f08622f,
|
||||
0xfea49f00,0x80000040,0x048c8081,0xff00420f,
|
||||
0x00809043,0xa7c4623b,0xfeb01f00,0x7c04620f,
|
||||
0x03600000,0xff00622f,0xfea49f00,0x80000040,
|
||||
0xfe081f80,0x000a0060,0x00809043,0x0ccec73c,
|
||||
0xfebc1f00,0x7f040200,0xfea09f00,0x90000020,
|
||||
0xfe941f00,0x10000040,0xfe081f80,0x30080060,
|
||||
0x00809043,0x0ccec73c,0x00041f00,0x20080000,
|
||||
0x00a01f00,0x80000020,0x002c1f02,0x1000e04f,
|
||||
0x00081f80,0x80010060,0x0ccec73c,0x00000000,
|
||||
0xfe201f02,0x1000800f,0xfec81f03,0x80020020,
|
||||
0xfe041f00,0x20080040,0xfe881f00,0x00000060,
|
||||
0xfecc9f81,0x9000a06f,0xfe0c1f00,0x000a0000,
|
||||
0xfe801f00,0x00000020,0xfec01f02,0x80020040,
|
||||
0xfe281f02,0x1000c06f,0xfe841f82,0x1000804f,
|
||||
0xfe041f00,0x000a0000,0x7fc81f02,0x00000020,
|
||||
0xfe8c1f00,0x00000040,0xfecc9f03,0x80020060,
|
||||
0xfe881f82,0x1000a00f,0x7cc01f02,0x00000000,
|
||||
0xfe8c1f02,0x1000e02f,0xfec49f00,0x80000040,
|
||||
0xfe081f00,0x000a0060,0x03c89f80,0x9000e04f,
|
||||
0x7ecc9f03,0x00000000,0xfec01f00,0x80000020,
|
||||
0x04c81f00,0x80000040,0x7c880f01,0xfe086a6f,
|
||||
0x7dac8f81,0x9000800f,0x7da00f00,0xfe04620f,
|
||||
0xfec01f00,0x80000020,0x03c01f00,0x80000840,
|
||||
0x03ac0f00,0xfe08c66f,0xfebc9f80,0xfd00420f,
|
||||
0xe07be53f,0x5c8e5a3f,0xfeb09f00,0xfd00620f,
|
||||
0x05e81f00,0x9000f02f,0x7fe48f00,0xfe04624f,
|
||||
0x04ec8f00,0xfe08626f,0x03840f81,0x7f08a20f,
|
||||
0xe07be53f,0x5c8e5a3f,0x7e0c1f00,0x900ce00f,
|
||||
0xfe0c1f00,0x900c802f,0x05cc1f00,0x9000e84f,
|
||||
0xfeb89f80,0xfd00626f,0xe07be53f,0x5c8e5a3f,
|
||||
0x7cc09f81,0x80000020,0x7fa40f00,0x00280000,
|
||||
0xfe848f00,0x00280020,0x7fe80f00,0x00280440,
|
||||
0xfd001f80,0x00280060,0x00000080,0x00000000,
|
||||
0xfdc01f80,0xf800620f,0x00000243,0x00000000,
|
||||
0xfea01f80,0x90000060,0x5555d53f,0x00000000,
|
||||
0x02011f80,0x8c110000,0x02448002,0x80020000,
|
||||
0xf8402000,0x9006a02f,0x02552081,0x00000040,
|
||||
0xfe301f00,0x1000e06f,0xfe081f80,0x1033c02f,
|
||||
0xfe4c2081,0x80060040,0xfee88f81,0x0289e32f,
|
||||
0x02c59f80,0x80060000,0xfee08f80,0x0285636f,
|
||||
0xfecc8f80,0x80000000,0xfe40a081,0x80000060,
|
||||
0x00cc9f81,0x9000e04f,0xfe281f00,0x80060000,
|
||||
0xf8c01f81,0x9006c02f,0xfee00f81,0xfd80636f,
|
||||
0x0000803f,0x00000000,0x7ec49f81,0xf880e34f,
|
||||
0xfe381f80,0x00000000,0x7de40f81,0xfe800360,
|
||||
0x00011f80,0x8c100000,0xf8001f00,0x900ce00f,
|
||||
0x00311f00,0x1000e02f,0x02a41f00,0xf910624f,
|
||||
0x02a01f00,0xf910626f,0x00011f80,0x1033e04f,
|
||||
0x00000040,0x00000000,0xfecc9f03,0x80020000,
|
||||
0xfec81f83,0x80020060,0x7fd49f01,0x00000020,
|
||||
0x7fd41f80,0x00000040,0xfe081f00,0x80010000,
|
||||
0xfe041f80,0x80010060,0xfee00f01,0x80000000,
|
||||
0xfeec0f81,0x80000020,0xfec01f00,0x00280000,
|
||||
0xfec49f00,0x00280020,0x7fe00f00,0x00280040,
|
||||
0xfd001f80,0x00280060,0x00000080,0x00000000,
|
||||
0xfe001f80,0x00350000,0x00ec1f82,0x000c0260,
|
||||
0x01011f00,0x800c0000,0x01051f00,0x800c0020,
|
||||
0x002c1f00,0x80060040,0xf8008001,0x9006e06f,
|
||||
0x01091f80,0x800c0000,0x01c01f00,0x90000000,
|
||||
0xfe088001,0xfd80632f,0x01e81f00,0x90000040,
|
||||
0x01c49f80,0x90000020,0x0000803f,0x00000000,
|
||||
0x7fcc9f80,0xf880630f,0xfe20a081,0x80000000,
|
||||
0x01cc1f80,0x90000060,0xc21e82a7,0x62ccc547,
|
||||
0x1708607c,0x73ea57a6
|
||||
};
|
||||
static const u32 cpPixelShaderRegs[] = {
|
||||
0x00000106,0x00000002,0x14000003,0x00000000,
|
||||
0x00000003,0x00000100,0x00000101,0x00000102,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x0000000f,0x00000001,0x00000010,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
ShaderFractalColor * ShaderFractalColor::shaderInstance = NULL;
|
||||
|
||||
ShaderFractalColor::ShaderFractalColor()
|
||||
: vertexShader(cuAttributeCount)
|
||||
{
|
||||
//! create pixel shader
|
||||
pixelShader.setProgram(cpPixelShaderProgram, sizeof(cpPixelShaderProgram), cpPixelShaderRegs, sizeof(cpPixelShaderRegs));
|
||||
|
||||
blurLocation = 0;
|
||||
colorIntensityLocation = 4;
|
||||
fadeOutLocation = 8;
|
||||
fractalLocation = 12;
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_blur_border", GX2_VAR_TYPE_FLOAT, 1, blurLocation, 0xffffffff });
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_color_intensity", GX2_VAR_TYPE_VEC4, 1, colorIntensityLocation, 0xffffffff });
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_fade_out_alpha", GX2_VAR_TYPE_VEC4, 1, fadeOutLocation, 0xffffffff });
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_fract_alpha", GX2_VAR_TYPE_INT, 1, fractalLocation, 0xffffffff });
|
||||
|
||||
//! create vertex shader
|
||||
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
|
||||
|
||||
modelMatrixLocation = 0;
|
||||
projectionMatrixLocation = 16;
|
||||
viewMatrixLocation = 32;
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "modelMatrix", GX2_VAR_TYPE_MAT4, 1, modelMatrixLocation, 0xffffffff });
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "projectionMatrix", GX2_VAR_TYPE_MAT4, 1, projectionMatrixLocation, 0xffffffff });
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "viewMatrix", GX2_VAR_TYPE_MAT4, 1, viewMatrixLocation, 0xffffffff });
|
||||
|
||||
positionLocation = 0;
|
||||
colorLocation = 1;
|
||||
texCoordLocation = 2;
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_colors", GX2_VAR_TYPE_VEC4, 0, colorLocation });
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });
|
||||
|
||||
//! setup attribute streams
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(2), colorLocation, 2, 0, GX2_ATTRIB_FORMAT_8_8_8_8_UNORM);
|
||||
|
||||
//! create fetch shader
|
||||
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
|
||||
|
||||
//! initialize default quad texture vertexes as those are very commonly used
|
||||
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
|
||||
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
|
||||
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
|
||||
colorVtxs = (u8*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciColorVtxsSize);
|
||||
|
||||
//! position vertex structure and texture coordinate vertex structure
|
||||
int i = 0;
|
||||
posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = 1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = 1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = -1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);
|
||||
|
||||
i = 0;
|
||||
texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
|
||||
texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
|
||||
texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
|
||||
texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
|
||||
|
||||
|
||||
for(i = 0; i < (int)ciColorVtxsSize; i++)
|
||||
colorVtxs[i] = 0xff;
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, colorVtxs, ciColorVtxsSize);
|
||||
}
|
||||
|
||||
ShaderFractalColor::~ShaderFractalColor()
|
||||
{
|
||||
if(posVtxs)
|
||||
{
|
||||
free(posVtxs);
|
||||
posVtxs = NULL;
|
||||
}
|
||||
if(texCoords)
|
||||
{
|
||||
free(texCoords);
|
||||
texCoords = NULL;
|
||||
}
|
||||
if(colorVtxs)
|
||||
{
|
||||
free(colorVtxs);
|
||||
colorVtxs = NULL;
|
||||
}
|
||||
|
||||
delete fetchShader;
|
||||
fetchShader = NULL;
|
||||
}
|
124
src/video/shaders/ShaderFractalColor.h
Normal file
124
src/video/shaders/ShaderFractalColor.h
Normal file
@ -0,0 +1,124 @@
|
||||
/****************************************************************************
|
||||
* 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 SHADER_FRACTAL_COLOR_H_
|
||||
#define SHADER_FRACTAL_COLOR_H_
|
||||
|
||||
#include "VertexShader.h"
|
||||
#include "PixelShader.h"
|
||||
#include "FetchShader.h"
|
||||
|
||||
class ShaderFractalColor : public Shader
|
||||
{
|
||||
private:
|
||||
ShaderFractalColor();
|
||||
virtual ~ShaderFractalColor();
|
||||
|
||||
static ShaderFractalColor * shaderInstance;
|
||||
|
||||
static const unsigned char cuAttributeCount = 3;
|
||||
static const u32 ciPositionVtxsSize = 4 * cuVertexAttrSize;
|
||||
static const u32 ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
|
||||
static const u32 ciColorVtxsSize = 4 * cuColorAttrSize;
|
||||
|
||||
FetchShader *fetchShader;
|
||||
VertexShader vertexShader;
|
||||
PixelShader pixelShader;
|
||||
|
||||
f32 *posVtxs;
|
||||
f32 *texCoords;
|
||||
u8 *colorVtxs;
|
||||
|
||||
u32 modelMatrixLocation;
|
||||
u32 viewMatrixLocation;
|
||||
u32 projectionMatrixLocation;
|
||||
u32 positionLocation;
|
||||
u32 colorLocation;
|
||||
u32 texCoordLocation;
|
||||
|
||||
u32 blurLocation;
|
||||
u32 colorIntensityLocation;
|
||||
u32 fadeOutLocation;
|
||||
u32 fractalLocation;
|
||||
public:
|
||||
static ShaderFractalColor *instance() {
|
||||
if(!shaderInstance) {
|
||||
shaderInstance = new ShaderFractalColor();
|
||||
}
|
||||
return shaderInstance;
|
||||
}
|
||||
static void destroyInstance() {
|
||||
if(shaderInstance) {
|
||||
delete shaderInstance;
|
||||
shaderInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void setShaders(void) const
|
||||
{
|
||||
fetchShader->setShader();
|
||||
vertexShader.setShader();
|
||||
pixelShader.setShader();
|
||||
}
|
||||
|
||||
void setAttributeBuffer(const u32 & vtxCount = 0, const f32 * posVtxs_in = NULL, const f32 * texCoords_in = NULL, const u8 * colorVtxs_in = NULL) const
|
||||
{
|
||||
if(posVtxs_in && texCoords_in && vtxCount)
|
||||
{
|
||||
VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in);
|
||||
VertexShader::setAttributeBuffer(1, vtxCount * cuTexCoordAttrSize, cuTexCoordAttrSize, texCoords_in);
|
||||
VertexShader::setAttributeBuffer(2, vtxCount * cuColorAttrSize, cuColorAttrSize, colorVtxs_in);
|
||||
}
|
||||
else {
|
||||
//! use default quad vertex and texture coordinates if nothing is passed
|
||||
VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
|
||||
VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
|
||||
VertexShader::setAttributeBuffer(2, ciColorVtxsSize, cuColorAttrSize, colorVtxs);
|
||||
}
|
||||
}
|
||||
|
||||
void setProjectionMtx(const glm::mat4 & mtx)
|
||||
{
|
||||
VertexShader::setUniformReg(projectionMatrixLocation, 16, &mtx[0][0]);
|
||||
}
|
||||
void setViewMtx(const glm::mat4 & mtx)
|
||||
{
|
||||
VertexShader::setUniformReg(viewMatrixLocation, 16, &mtx[0][0]);
|
||||
}
|
||||
void setModelViewMtx(const glm::mat4 & mtx)
|
||||
{
|
||||
VertexShader::setUniformReg(modelMatrixLocation, 16, &mtx[0][0]);
|
||||
}
|
||||
|
||||
void setBlurBorder(const float & blurBorderSize)
|
||||
{
|
||||
PixelShader::setUniformReg(blurLocation, 4, &blurBorderSize);
|
||||
}
|
||||
void setColorIntensity(const glm::vec4 & vec)
|
||||
{
|
||||
PixelShader::setUniformReg(colorIntensityLocation, 4, &vec[0]);
|
||||
}
|
||||
void setAlphaFadeOut(const glm::vec4 & vec)
|
||||
{
|
||||
PixelShader::setUniformReg(fadeOutLocation, 4, &vec[0]);
|
||||
}
|
||||
void setFractalColor(const int & fractalColorEnable)
|
||||
{
|
||||
PixelShader::setUniformReg(fractalLocation, 4, &fractalColorEnable);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHADER_FRACTAL_COLOR_H_
|
271
src/video/shaders/Texture2DShader.cpp
Normal file
271
src/video/shaders/Texture2DShader.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
/****************************************************************************
|
||||
* 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 "Texture2DShader.h"
|
||||
|
||||
static const u32 cpVertexShaderProgram[] =
|
||||
{
|
||||
0x00000000,0x00008009,0x20000000,0x000080a0,
|
||||
0x3c200100,0x88060094,0x00400000,0x88042014,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x02290001,0x80000000,0x02041f00,0x900c0020,
|
||||
0x00a11f00,0xfc00624f,0xfd041f00,0x900c4060,
|
||||
0x02001f80,0x900c0000,0x83f9223e,0x0000803f,
|
||||
0xfe081f00,0x00080020,0xfe202081,0x10004040,
|
||||
0xfea49f80,0xfd00620f,0xdb0f49c0,0xdb0fc940,
|
||||
0xfea01f80,0x9000e06f,0x83f9223e,0x00000000,
|
||||
0xfe0c1f80,0x00370000,0xffa01f00,0x80000040,
|
||||
0xff101f00,0x800c0060,0x7f0c1f80,0x80370040,
|
||||
0x0000103f,0x00000000,0xffa01f00,0x80000000,
|
||||
0xff001f00,0x800c0020,0x02c51f01,0x80000040,
|
||||
0xfeac9f80,0x80000060,0x0000103f,0x398ee33f,
|
||||
0xfea01f00,0x80000000,0x02c19f01,0x9000e02f,
|
||||
0x01c41f01,0x9000e04f,0x02c59f80,0x80000060,
|
||||
0x398ee33f,0x00000000,0x01c49f01,0x80000020,
|
||||
0x02c11f80,0x80000040,0x01e08f00,0xfe04624f,
|
||||
0x01c01f81,0x7f08626f,0xfe2c2000,0x10004000,
|
||||
0xfe28a080,0x10004020,0xeb825790,0xb6f711be,
|
||||
0x7c0e2df2,0x81173cfa
|
||||
};
|
||||
|
||||
static const u32 cpVertexShaderRegs[] = {
|
||||
0x00000103,0x00000000,0x00000000,0x00000001,
|
||||
0xffffff00,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0xffffffff,0xffffffff,
|
||||
0xffffffff,0xffffffff,0x00000000,0xfffffffc,
|
||||
0x00000002,0x00000000,0x00000001,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x000000ff,0x000000ff,0x000000ff,
|
||||
0x000000ff,0x00000000,0x0000000e,0x00000010
|
||||
};
|
||||
|
||||
static const u32 cPixelShaderProgram[] =
|
||||
{
|
||||
0x20000000,0x00000ca4,0x0b000000,0x00000085,
|
||||
0x24000000,0x000050a0,0xb0000000,0x000cc080,
|
||||
0x39000000,0x00005ca0,0xb8000000,0x000cc080,
|
||||
0x51000000,0x000078a0,0xc0000000,0x000cc080,
|
||||
0x70000000,0x000064a0,0xc8000000,0x0008c080,
|
||||
0x8a000000,0x00005ca0,0x0e000000,0x01008086,
|
||||
0xce000000,0x0000c080,0xa2000000,0x00000ca8,
|
||||
0x00800000,0x88062094,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00051f00,0x80060000,0x00011f80,0x80060040,
|
||||
0xfec81f80,0xfb802320,0x01041f80,0x8c220000,
|
||||
0x00a41f00,0xfc10620f,0x010d1f00,0x900c0021,
|
||||
0x00091f00,0x80060040,0x00a01f80,0xfc10626f,
|
||||
0x00000040,0x00000000,0xfe080000,0xfe8cc300,
|
||||
0xfe088080,0xfe80c320,0x00a11f00,0xfe000200,
|
||||
0x00a51f00,0xfe040220,0x00a19f00,0xfe000240,
|
||||
0x00a59f00,0xfe040260,0x00a11f81,0xfe002600,
|
||||
0x4260e5bc,0xa69bc4bc,0x0ad7a3bc,0x00000000,
|
||||
0x00a11f00,0x06004200,0x00a59f00,0x06042220,
|
||||
0x00a51f00,0x06044240,0x00a11f01,0x06008260,
|
||||
0x00a51f81,0x06048620,0x6f1283bc,0x0ad7a3bc,
|
||||
0xa69b44bc,0x00000000,0x00a41f00,0x80000000,
|
||||
0x00a01f00,0x80000020,0x00ac1f00,0x80000040,
|
||||
0x00a81f00,0x80000060,0x00a19f80,0x06000600,
|
||||
0xcac3123c,0x6f1203bc,0x03a41f00,0xfe00620f,
|
||||
0x03a01f00,0xfe04622f,0x03ac1f00,0xfe08624f,
|
||||
0x03a81f00,0xfe0c626f,0x00a59f80,0x06040620,
|
||||
0xcc28913b,0x6f1203bc,0x01a41f00,0xfe00620f,
|
||||
0x01a01f00,0xfe04622f,0x01ac1f00,0xfe08624f,
|
||||
0x01a81f00,0xfe0c626f,0x00a19f80,0x06002600,
|
||||
0xe8eab03c,0x6f1283bb,0x02ac1f00,0xfe084200,
|
||||
0x02a81f00,0xfe0c4220,0x02a41f00,0xfe004240,
|
||||
0x02a01f00,0xfe044260,0x00a59f80,0x06042620,
|
||||
0x92bb353d,0x6f1283bb,0x04a81f00,0x0204620f,
|
||||
0x04ac1f00,0x0200662f,0x04a41f00,0x0208624f,
|
||||
0x04a01f00,0x020c626f,0x00a19f80,0x06004600,
|
||||
0xc4139f3d,0x6f12833b,0x00a41f00,0xfe08620f,
|
||||
0x00a01f00,0xfe0c622f,0x00ac1f00,0xfe04624f,
|
||||
0x00a81f00,0xfe00626f,0x00a59f80,0x06044620,
|
||||
0xb950ed3d,0x6f12833b,0x01a41f00,0xfe00620f,
|
||||
0x01a01f00,0xfe04622f,0x01ac1f00,0xfe08624f,
|
||||
0x01a81f00,0xfe0c626f,0x00a19f80,0x06002600,
|
||||
0xecd7163e,0x6f12033c,0x03a41f00,0xfe000200,
|
||||
0x03a01f00,0xfe040220,0x03ac1f00,0xfe082240,
|
||||
0x03a81f00,0xfe0c2260,0x00a59f80,0x06042620,
|
||||
0x2168233e,0x6f12033c,0x00a11f00,0x06006200,
|
||||
0x00a51f00,0x06046220,0x00a19f00,0x06006240,
|
||||
0x00a59f00,0x06046260,0x00a11f81,0x0600e600,
|
||||
0xa69b443c,0x6f12833c,0x0ad7a33c,0x00000000,
|
||||
0x02ac1f00,0x0108620f,0x02a81f00,0x010c622f,
|
||||
0x02a41f00,0x0000624f,0x02a01f00,0x0004666f,
|
||||
0x00a59f80,0x0604e620,0xecd7163e,0x0ad7a33c,
|
||||
0x04a81f00,0xfe04620f,0x04ac1f00,0xfe00622f,
|
||||
0x04a41f00,0xfe08624f,0x04a01f00,0xfe0c626f,
|
||||
0x00a19f80,0x06008600,0xb950ed3d,0xa69bc43c,
|
||||
0x05a41f00,0xfe08620f,0x05a01f00,0xfe0c622f,
|
||||
0x05ac1f00,0xfe04624f,0x05a81f00,0xfe00626f,
|
||||
0x00a59f80,0x06048620,0xc4139f3d,0xa69bc43c,
|
||||
0x03a41f00,0xfe00a200,0x03a01f00,0xfe04a220,
|
||||
0x03ac1f00,0xfe086240,0x03a81f00,0xfe0c6260,
|
||||
0x00a19f80,0x06006600,0x92bb353d,0x4260e53c,
|
||||
0x00a51f80,0x06046220,0x4260e53c,0x00000000,
|
||||
0x07ac1f00,0x0308620f,0x07a81f00,0x030c622f,
|
||||
0x07a41f00,0x0500624f,0x07a01f80,0x0504626f,
|
||||
0xe8eab03c,0x00000000,0x04a81f00,0xfe04620f,
|
||||
0x04ac1f00,0xfe00622f,0x04a41f00,0xfe08624f,
|
||||
0x04a01f80,0xfe0c626f,0xcac3123c,0x00000000,
|
||||
0x06a41f00,0xfe08620f,0x06a01f00,0xfe0c622f,
|
||||
0x06ac1f00,0xfe04624f,0x06a81f80,0xfe00626f,
|
||||
0xcc28913b,0x00000000,0xfe20a000,0x9000e00f,
|
||||
0xfe242000,0x9000e02f,0xfe28a001,0x9000e04f,
|
||||
0xfe2c2081,0x9000e06f,0xfe28a081,0x80060020,
|
||||
0xfee48f00,0x7f842300,0xfee40f00,0x7f802320,
|
||||
0xfee48f01,0x7f8c2340,0xfee40f81,0x08842b60,
|
||||
0x00202000,0x90002000,0x0024a000,0x90002020,
|
||||
0x00282001,0x90002040,0x002ca081,0x90002060,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x10000000,0x03100df0,0x00008010,0xecdfea0d,
|
||||
0x10000000,0x00100df0,0x0000a051,0xecdfea0d,
|
||||
0x10000100,0x01100df0,0x00008010,0xecdfea0d,
|
||||
0x10000200,0x02100df0,0x00000011,0xecdfea0d,
|
||||
0x10000400,0x04100df0,0x0000b070,0xecdfea0d,
|
||||
0x10000000,0x00100df0,0x00008010,0xecdfea0d,
|
||||
0x10000100,0x01100df0,0x00008010,0xecdfea0d,
|
||||
0x10000600,0x03100df0,0x00008010,0xecdfea0d,
|
||||
0x10000200,0x02100df0,0x00008010,0xecdfea0d,
|
||||
0x10000100,0x04100df0,0x00008010,0xecdfea0d,
|
||||
0x10000300,0x05100df0,0x00008010,0xecdfea0d,
|
||||
0x10000300,0x03100df0,0x0000a051,0xecdfea0d,
|
||||
0x10000700,0x07100df0,0x00008010,0xecdfea0d,
|
||||
0x10000400,0x04100df0,0x00008010,0xecdfea0d,
|
||||
0x10000300,0x06100df0,0x00008010,0xecdfea0d,
|
||||
0x10000000,0x00100df0,0x00008010,0xecdfea0d,
|
||||
0xc8581837,0x22740275,0x281eddcc,0xfa8b9b65
|
||||
};
|
||||
static const u32 cPixelShaderRegs[] = {
|
||||
0x00000109,0x00000002,0x14000001,0x00000000,
|
||||
0x00000001,0x00000100,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
0x00000000,0x0000000f,0x00000001,0x00000010,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
Texture2DShader * Texture2DShader::shaderInstance = NULL;
|
||||
|
||||
Texture2DShader::Texture2DShader()
|
||||
: vertexShader(cuAttributeCount)
|
||||
{
|
||||
//! create pixel shader
|
||||
pixelShader.setProgram(cPixelShaderProgram, sizeof(cPixelShaderProgram), cPixelShaderRegs, sizeof(cPixelShaderRegs));
|
||||
|
||||
blurLocation = 0;
|
||||
colorIntensityLocation = 4;
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_blur_texture_direction", GX2_VAR_TYPE_VEC3, 1, blurLocation, 0xffffffff });
|
||||
pixelShader.addUniformVar((GX2UniformVar){ "unf_color_intensity", GX2_VAR_TYPE_VEC4, 1, colorIntensityLocation, 0xffffffff });
|
||||
|
||||
samplerLocation = 0;
|
||||
pixelShader.addSamplerVar((GX2SamplerVar){ "sampl_texture", GX2_SAMPLER_TYPE_2D, samplerLocation });
|
||||
|
||||
//! create vertex shader
|
||||
vertexShader.setProgram(cpVertexShaderProgram, sizeof(cpVertexShaderProgram), cpVertexShaderRegs, sizeof(cpVertexShaderRegs));
|
||||
|
||||
angleLocation = 0;
|
||||
offsetLocation = 4;
|
||||
scaleLocation = 8;
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "unf_angle", GX2_VAR_TYPE_FLOAT, 1, angleLocation, 0xffffffff });
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "unf_offset", GX2_VAR_TYPE_VEC3, 1, offsetLocation, 0xffffffff });
|
||||
vertexShader.addUniformVar((GX2UniformVar){ "unf_scale", GX2_VAR_TYPE_VEC3, 1, scaleLocation, 0xffffffff });
|
||||
|
||||
positionLocation = 0;
|
||||
texCoordLocation = 1;
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_position", GX2_VAR_TYPE_VEC3, 0, positionLocation });
|
||||
vertexShader.addAttribVar((GX2AttribVar){ "attr_texture_coord", GX2_VAR_TYPE_VEC2, 0, texCoordLocation });
|
||||
|
||||
//! setup attribute streams
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(0), positionLocation, 0, 0, GX2_ATTRIB_FORMAT_32_32_32_FLOAT);
|
||||
GX2InitAttribStream(vertexShader.getAttributeBuffer(1), texCoordLocation, 1, 0, GX2_ATTRIB_FORMAT_32_32_FLOAT);
|
||||
|
||||
//! create fetch shader
|
||||
fetchShader = new FetchShader(vertexShader.getAttributeBuffer(), vertexShader.getAttributesCount());
|
||||
|
||||
//! model vertex has to be align and cannot be in unknown regions for GX2 like 0xBCAE1000
|
||||
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciPositionVtxsSize);
|
||||
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, ciTexCoordsVtxsSize);
|
||||
|
||||
//! defaults for normal square
|
||||
//! position vertex structure and texture coordinate vertex structure
|
||||
int i = 0;
|
||||
posVtxs[i++] = -1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = 1.0f; posVtxs[i++] = -1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = 1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
|
||||
posVtxs[i++] = -1.0f; posVtxs[i++] = 1.0f; posVtxs[i++] = 0.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, posVtxs, ciPositionVtxsSize);
|
||||
|
||||
i = 0;
|
||||
texCoords[i++] = 0.0f; texCoords[i++] = 1.0f;
|
||||
texCoords[i++] = 1.0f; texCoords[i++] = 1.0f;
|
||||
texCoords[i++] = 1.0f; texCoords[i++] = 0.0f;
|
||||
texCoords[i++] = 0.0f; texCoords[i++] = 0.0f;
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoords, ciTexCoordsVtxsSize);
|
||||
}
|
||||
|
||||
Texture2DShader::~Texture2DShader()
|
||||
{
|
||||
if(posVtxs)
|
||||
{
|
||||
free(posVtxs);
|
||||
posVtxs = NULL;
|
||||
}
|
||||
if(texCoords)
|
||||
{
|
||||
free(texCoords);
|
||||
texCoords = NULL;
|
||||
}
|
||||
|
||||
delete fetchShader;
|
||||
fetchShader = NULL;
|
||||
}
|
112
src/video/shaders/Texture2DShader.h
Normal file
112
src/video/shaders/Texture2DShader.h
Normal file
@ -0,0 +1,112 @@
|
||||
/****************************************************************************
|
||||
* 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 __TEXTURE_2D_SHADER_H_
|
||||
#define __TEXTURE_2D_SHADER_H_
|
||||
|
||||
#include "VertexShader.h"
|
||||
#include "PixelShader.h"
|
||||
#include "FetchShader.h"
|
||||
|
||||
class Texture2DShader : public Shader
|
||||
{
|
||||
private:
|
||||
Texture2DShader();
|
||||
virtual ~Texture2DShader();
|
||||
|
||||
static const u32 cuAttributeCount = 2;
|
||||
static const u32 ciPositionVtxsSize = 4 * cuVertexAttrSize;
|
||||
static const u32 ciTexCoordsVtxsSize = 4 * cuTexCoordAttrSize;
|
||||
|
||||
static Texture2DShader *shaderInstance;
|
||||
|
||||
FetchShader *fetchShader;
|
||||
VertexShader vertexShader;
|
||||
PixelShader pixelShader;
|
||||
|
||||
f32 *posVtxs;
|
||||
f32 *texCoords;
|
||||
|
||||
u32 angleLocation;
|
||||
u32 offsetLocation;
|
||||
u32 scaleLocation;
|
||||
u32 colorIntensityLocation;
|
||||
u32 blurLocation;
|
||||
u32 samplerLocation;
|
||||
u32 positionLocation;
|
||||
u32 texCoordLocation;
|
||||
public:
|
||||
static Texture2DShader *instance() {
|
||||
if(!shaderInstance) {
|
||||
shaderInstance = new Texture2DShader();
|
||||
}
|
||||
return shaderInstance;
|
||||
}
|
||||
static void destroyInstance() {
|
||||
if(shaderInstance) {
|
||||
delete shaderInstance;
|
||||
shaderInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void setShaders(void) const
|
||||
{
|
||||
fetchShader->setShader();
|
||||
vertexShader.setShader();
|
||||
pixelShader.setShader();
|
||||
}
|
||||
|
||||
void setAttributeBuffer(const f32 * texCoords_in = NULL, const f32 * posVtxs_in = NULL, const u32 & vtxCount = 0) const
|
||||
{
|
||||
if(posVtxs_in && texCoords_in && vtxCount)
|
||||
{
|
||||
VertexShader::setAttributeBuffer(0, vtxCount * cuVertexAttrSize, cuVertexAttrSize, posVtxs_in);
|
||||
VertexShader::setAttributeBuffer(1, vtxCount * cuTexCoordAttrSize, cuTexCoordAttrSize, texCoords_in);
|
||||
}
|
||||
else {
|
||||
VertexShader::setAttributeBuffer(0, ciPositionVtxsSize, cuVertexAttrSize, posVtxs);
|
||||
VertexShader::setAttributeBuffer(1, ciTexCoordsVtxsSize, cuTexCoordAttrSize, texCoords);
|
||||
}
|
||||
}
|
||||
|
||||
void setAngle(const float & val)
|
||||
{
|
||||
VertexShader::setUniformReg(angleLocation, 4, &val);
|
||||
}
|
||||
void setOffset(const glm::vec3 & vec)
|
||||
{
|
||||
VertexShader::setUniformReg(offsetLocation, 4, &vec[0]);
|
||||
}
|
||||
void setScale(const glm::vec3 & vec)
|
||||
{
|
||||
VertexShader::setUniformReg(scaleLocation, 4, &vec[0]);
|
||||
}
|
||||
void setColorIntensity(const glm::vec4 & vec)
|
||||
{
|
||||
PixelShader::setUniformReg(colorIntensityLocation, 4, &vec[0]);
|
||||
}
|
||||
void setBlurring(const glm::vec3 & vec)
|
||||
{
|
||||
PixelShader::setUniformReg(blurLocation, 4, &vec[0]);
|
||||
}
|
||||
|
||||
void setTextureAndSampler(const GX2Texture *texture, const GX2Sampler *sampler) const {
|
||||
GX2SetPixelTexture(texture, samplerLocation);
|
||||
GX2SetPixelSampler(sampler, samplerLocation);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __TEXTURE_2D_SHADER_H_
|
178
src/video/shaders/VertexShader.h
Normal file
178
src/video/shaders/VertexShader.h
Normal file
@ -0,0 +1,178 @@
|
||||
/****************************************************************************
|
||||
* 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 VERTEX_SHADER_H
|
||||
#define VERTEX_SHADER_H
|
||||
|
||||
#include <string.h>
|
||||
#include "Shader.h"
|
||||
|
||||
class VertexShader : public Shader
|
||||
{
|
||||
public:
|
||||
VertexShader(u32 numAttr)
|
||||
: attributesCount( numAttr )
|
||||
, attributes( new GX2AttribStream[attributesCount] )
|
||||
, vertexShader( (GX2VertexShader*) memalign(0x40, sizeof(GX2VertexShader)) )
|
||||
{
|
||||
if(vertexShader)
|
||||
{
|
||||
memset(vertexShader, 0, sizeof(GX2VertexShader));
|
||||
vertexShader->shader_mode = GX2_SHADER_MODE_UNIFORM_REGISTER;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~VertexShader() {
|
||||
delete [] attributes;
|
||||
|
||||
if(vertexShader)
|
||||
{
|
||||
if(vertexShader->shader_data)
|
||||
free(vertexShader->shader_data);
|
||||
|
||||
for(u32 i = 0; i < vertexShader->uniform_blocks_count; i++)
|
||||
free((void*)vertexShader->uniform_block[i].name);
|
||||
|
||||
if(vertexShader->uniform_block)
|
||||
free((void*)vertexShader->uniform_block);
|
||||
|
||||
for(u32 i = 0; i < vertexShader->uniform_vars_count; i++)
|
||||
free((void*)vertexShader->uniform_var[i].name);
|
||||
|
||||
if(vertexShader->uniform_var)
|
||||
free((void*)vertexShader->uniform_var);
|
||||
|
||||
if(vertexShader->initial_value)
|
||||
free((void*)vertexShader->initial_value);
|
||||
|
||||
for(u32 i = 0; i < vertexShader->sampler_vars_count; i++)
|
||||
free((void*)vertexShader->sampler_var[i].name);
|
||||
|
||||
if(vertexShader->sampler_var)
|
||||
free((void*)vertexShader->sampler_var);
|
||||
|
||||
for(u32 i = 0; i < vertexShader->attribute_vars_count; i++)
|
||||
free((void*)vertexShader->attribute_var[i].name);
|
||||
|
||||
if(vertexShader->attribute_var)
|
||||
free((void*)vertexShader->attribute_var);
|
||||
|
||||
if(vertexShader->loops_data)
|
||||
free((void*)vertexShader->loops_data);
|
||||
|
||||
free(vertexShader);
|
||||
}
|
||||
}
|
||||
|
||||
void setProgram(const u32 * program, const u32 & programSize, const u32 * regs, const u32 & regsSize)
|
||||
{
|
||||
if(!vertexShader)
|
||||
return;
|
||||
|
||||
//! this must be moved into an area where the graphic engine has access to and must be aligned to 0x100
|
||||
vertexShader->shader_size = programSize;
|
||||
vertexShader->shader_data = memalign(GX2_SHADER_ALIGNMENT, vertexShader->shader_size);
|
||||
if(vertexShader->shader_data)
|
||||
{
|
||||
memcpy(vertexShader->shader_data, program, vertexShader->shader_size);
|
||||
GX2Invalidate(GX2_INVALIDATE_CPU_SHADER, vertexShader->shader_data, vertexShader->shader_size);
|
||||
}
|
||||
|
||||
memcpy(vertexShader->regs, regs, regsSize);
|
||||
}
|
||||
|
||||
void addUniformVar(const GX2UniformVar & var)
|
||||
{
|
||||
if(!vertexShader)
|
||||
return;
|
||||
|
||||
u32 idx = vertexShader->uniform_vars_count;
|
||||
|
||||
GX2UniformVar* newVar = (GX2UniformVar*) malloc((vertexShader->uniform_vars_count + 1) * sizeof(GX2UniformVar));
|
||||
if(newVar)
|
||||
{
|
||||
if(vertexShader->uniform_vars_count > 0)
|
||||
{
|
||||
memcpy(newVar, vertexShader->uniform_var, vertexShader->uniform_vars_count * sizeof(GX2UniformVar));
|
||||
free(vertexShader->uniform_var);
|
||||
}
|
||||
vertexShader->uniform_var = newVar;
|
||||
|
||||
memcpy(vertexShader->uniform_var + idx, &var, sizeof(GX2UniformVar));
|
||||
vertexShader->uniform_var[idx].name = (char*) malloc(strlen(var.name) + 1);
|
||||
strcpy((char*)vertexShader->uniform_var[idx].name, var.name);
|
||||
|
||||
vertexShader->uniform_vars_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void addAttribVar(const GX2AttribVar & var)
|
||||
{
|
||||
if(!vertexShader)
|
||||
return;
|
||||
|
||||
u32 idx = vertexShader->attribute_vars_count;
|
||||
|
||||
GX2AttribVar* newVar = (GX2AttribVar*) malloc((vertexShader->attribute_vars_count + 1) * sizeof(GX2AttribVar));
|
||||
if(newVar)
|
||||
{
|
||||
if(vertexShader->attribute_vars_count > 0)
|
||||
{
|
||||
memcpy(newVar, vertexShader->attribute_var, vertexShader->attribute_vars_count * sizeof(GX2AttribVar));
|
||||
free(vertexShader->attribute_var);
|
||||
}
|
||||
vertexShader->attribute_var = newVar;
|
||||
|
||||
memcpy(vertexShader->attribute_var + idx, &var, sizeof(GX2AttribVar));
|
||||
vertexShader->attribute_var[idx].name = (char*) malloc(strlen(var.name) + 1);
|
||||
strcpy((char*)vertexShader->attribute_var[idx].name, var.name);
|
||||
|
||||
vertexShader->attribute_vars_count++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void setAttributeBuffer(u32 bufferIdx, u32 bufferSize, u32 stride, const void * buffer) {
|
||||
GX2SetAttribBuffer(bufferIdx, bufferSize, stride, buffer);
|
||||
}
|
||||
|
||||
GX2VertexShader *getVertexShader() const {
|
||||
return vertexShader;
|
||||
}
|
||||
|
||||
void setShader(void) const {
|
||||
GX2SetVertexShader(vertexShader);
|
||||
}
|
||||
|
||||
GX2AttribStream * getAttributeBuffer(u32 idx = 0) const {
|
||||
if(idx >= attributesCount) {
|
||||
return NULL;
|
||||
}
|
||||
return &attributes[idx];
|
||||
}
|
||||
u32 getAttributesCount() const {
|
||||
return attributesCount;
|
||||
}
|
||||
|
||||
static void setUniformReg(u32 location, u32 size, const void * reg) {
|
||||
GX2SetVertexUniformReg(location, size, reg);
|
||||
}
|
||||
protected:
|
||||
u32 attributesCount;
|
||||
GX2AttribStream *attributes;
|
||||
GX2VertexShader *vertexShader;
|
||||
};
|
||||
|
||||
#endif // VERTEX_SHADER_H
|
Loading…
Reference in New Issue
Block a user