Missing files

This commit is contained in:
Maschell 2016-04-25 22:22:22 +02:00
parent 4893fc7c67
commit e8bd4647eb
56 changed files with 8390 additions and 0 deletions

29
hidtopad.cbp Normal file
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,25 @@
#ifndef __OS_DEFS_H_
#define __OS_DEFS_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _OsSpecifics
{
unsigned int addr_OSDynLoad_Acquire;
unsigned int addr_OSDynLoad_FindExport;
unsigned int addr_OSTitle_main_entry;
unsigned int addr_KernSyscallTbl1;
unsigned int addr_KernSyscallTbl2;
unsigned int addr_KernSyscallTbl3;
unsigned int addr_KernSyscallTbl4;
unsigned int addr_KernSyscallTbl5;
} OsSpecifics;
#ifdef __cplusplus
}
#endif
#endif // __OS_DEFS_H_

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

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

@ -0,0 +1 @@
Subproject commit c1a02aa7c7a3a9031f9170ac284e15c9dd8df603

1
src/dynamic_libs Submodule

@ -0,0 +1 @@
Subproject commit 1fcfb43f395c248aa45bb909012fbecbbbb2df2a

14
src/entry.c Normal file
View File

@ -0,0 +1,14 @@
#include <string.h>
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/sys_functions.h"
#include "common/common.h"
#include "utils/utils.h"
#include "main.h"
int __entry_menu(int argc, char **argv)
{
//! *******************************************************************
//! * Jump to our application *
//! *******************************************************************
return Menu_Main();
}

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

@ -0,0 +1,182 @@
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "common/fs_defs.h"
#include "dynamic_libs/fs_functions.h"
int MountFS(void *pClient, void *pCmd, char **mount_path)
{
int result = -1;
void *mountSrc = malloc(FS_MOUNT_SOURCE_SIZE);
if(!mountSrc)
return -3;
char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE);
if(!mountPath) {
free(mountSrc);
return -4;
}
memset(mountSrc, 0, FS_MOUNT_SOURCE_SIZE);
memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE);
// Mount sdcard
if (FSGetMountSource(pClient, pCmd, FS_SOURCETYPE_EXTERNAL, mountSrc, -1) == 0)
{
result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1);
if((result == 0) && mount_path) {
*mount_path = (char*)malloc(strlen(mountPath) + 1);
if(*mount_path)
strcpy(*mount_path, mountPath);
}
}
free(mountPath);
free(mountSrc);
return result;
}
int UmountFS(void *pClient, void *pCmd, const char *mountPath)
{
int result = -1;
result = FSUnmount(pClient, pCmd, mountPath, -1);
return result;
}
int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size)
{
//! always initialze input
*inbuffer = NULL;
if(size)
*size = 0;
int iFd = open(filepath, O_RDONLY);
if (iFd < 0)
return -1;
u32 filesize = lseek(iFd, 0, SEEK_END);
lseek(iFd, 0, SEEK_SET);
u8 *buffer = (u8 *) malloc(filesize);
if (buffer == NULL)
{
close(iFd);
return -2;
}
u32 blocksize = 0x4000;
u32 done = 0;
int readBytes = 0;
while(done < filesize)
{
if(done + blocksize > filesize) {
blocksize = filesize - done;
}
readBytes = read(iFd, buffer + done, blocksize);
if(readBytes <= 0)
break;
done += readBytes;
}
close(iFd);
if (done != filesize)
{
free(buffer);
return -3;
}
*inbuffer = buffer;
//! sign is optional input
if(size)
*size = filesize;
return filesize;
}
int CheckFile(const char * filepath)
{
if(!filepath)
return 0;
struct stat filestat;
char dirnoslash[strlen(filepath)+2];
snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath);
while(dirnoslash[strlen(dirnoslash)-1] == '/')
dirnoslash[strlen(dirnoslash)-1] = '\0';
char * notRoot = strrchr(dirnoslash, '/');
if(!notRoot)
{
strcat(dirnoslash, "/");
}
if (stat(dirnoslash, &filestat) == 0)
return 1;
return 0;
}
int CreateSubfolder(const char * fullpath)
{
if(!fullpath)
return 0;
int result = 0;
char dirnoslash[strlen(fullpath)+1];
strcpy(dirnoslash, fullpath);
int pos = strlen(dirnoslash)-1;
while(dirnoslash[pos] == '/')
{
dirnoslash[pos] = '\0';
pos--;
}
if(CheckFile(dirnoslash))
{
return 1;
}
else
{
char parentpath[strlen(dirnoslash)+2];
strcpy(parentpath, dirnoslash);
char * ptr = strrchr(parentpath, '/');
if(!ptr)
{
//!Device root directory (must be with '/')
strcat(parentpath, "/");
struct stat filestat;
if (stat(parentpath, &filestat) == 0)
return 1;
return 0;
}
ptr++;
ptr[0] = '\0';
result = CreateSubfolder(parentpath);
}
if(!result)
return 0;
if (mkdir(dirnoslash, 0777) == -1)
{
return 0;
}
return 1;
}

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

@ -0,0 +1,23 @@
#ifndef __FS_UTILS_H_
#define __FS_UTILS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <gctypes.h>
int MountFS(void *pClient, void *pCmd, char **mount_path);
int UmountFS(void *pClient, void *pCmd, const char *mountPath);
int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size);
//! todo: C++ class
int CreateSubfolder(const char * fullpath);
int CheckFile(const char * filepath);
#ifdef __cplusplus
}
#endif
#endif // __FS_UTILS_H_

1019
src/fs/sd_fat_devoptab.c Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,38 @@
/***************************************************************************
* Copyright (C) 2015
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef __SD_FAT_DEVOPTAB_H_
#define __SD_FAT_DEVOPTAB_H_
#ifdef __cplusplus
extern "C" {
#endif
int mount_sd_fat(const char *path);
int unmount_sd_fat(const char *path);
#ifdef __cplusplus
}
#endif
#endif // __SD_FAT_DEVOPTAB_H_

1729
src/game/memory_area_table.c Normal file

File diff suppressed because it is too large Load Diff

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

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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

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

View 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();
}

View 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

View 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;
}

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

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

View 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
View File

@ -0,0 +1,198 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <malloc.h>
#include <string.h>
#include "dynamic_libs/os_functions.h"
#include "common/common.h"
#include "memory.h"
#define MEMORY_ARENA_1 0
#define MEMORY_ARENA_2 1
#define MEMORY_ARENA_3 2
#define MEMORY_ARENA_4 3
#define MEMORY_ARENA_5 4
#define MEMORY_ARENA_6 5
#define MEMORY_ARENA_7 6
#define MEMORY_ARENA_8 7
#define MEMORY_ARENA_FG_BUCKET 8
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! Memory functions
//! This is the only place where those are needed so lets keep them more or less private
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
extern unsigned int * pMEMAllocFromDefaultHeapEx;
extern unsigned int * pMEMAllocFromDefaultHeap;
extern unsigned int * pMEMFreeToDefaultHeap;
extern int (* MEMGetBaseHeapHandle)(int mem_arena);
extern unsigned int (* MEMGetAllocatableSizeForFrmHeapEx)(int heap, int align);
extern void *(* MEMAllocFromFrmHeapEx)(int heap, unsigned int size, int align);
extern void (* MEMFreeToFrmHeap)(int heap, int mode);
extern void *(* MEMAllocFromExpHeapEx)(int heap, unsigned int size, int align);
extern int (* MEMCreateExpHeapEx)(void* address, unsigned int size, unsigned short flags);
extern void *(* MEMDestroyExpHeap)(int heap);
extern void (* MEMFreeToExpHeap)(int heap, void* ptr);
static int mem1_heap = -1;
static int bucket_heap = -1;
void memoryInitialize(void)
{
int mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1);
unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4);
void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4);
if(mem1_memory)
mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0);
int bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET);
unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4);
void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4);
if(bucket_memory)
bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0);
}
void memoryRelease(void)
{
MEMDestroyExpHeap(mem1_heap);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3);
mem1_heap = -1;
MEMDestroyExpHeap(bucket_heap);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3);
bucket_heap = -1;
}
//!-------------------------------------------------------------------------------------------
//! wraps
//!-------------------------------------------------------------------------------------------
void *__wrap_malloc(size_t size)
{
// pointer to a function resolve
return ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size);
}
void *__wrap_memalign(size_t align, size_t size)
{
if (align < 4)
align = 4;
// pointer to a function resolve
return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align);
}
void __wrap_free(void *p)
{
// pointer to a function resolve
if(p != 0)
((void (*)(void *))(*pMEMFreeToDefaultHeap))(p);
}
void *__wrap_calloc(size_t n, size_t size)
{
void *p = __wrap_malloc(n * size);
if (p != 0) {
memset(p, 0, n * size);
}
return p;
}
size_t __wrap_malloc_usable_size(void *p)
{
//! TODO: this is totally wrong and needs to be addressed
return 0x7FFFFFFF;
}
void *__wrap_realloc(void *p, size_t size)
{
void *new_ptr = __wrap_malloc(size);
if (new_ptr != 0)
{
memcpy(new_ptr, p, __wrap_malloc_usable_size(p) < size ? __wrap_malloc_usable_size(p) : size);
__wrap_free(p);
}
return new_ptr;
}
//!-------------------------------------------------------------------------------------------
//! reent versions
//!-------------------------------------------------------------------------------------------
void *__wrap__malloc_r(struct _reent *r, size_t size)
{
return __wrap_malloc(size);
}
void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size)
{
return __wrap_calloc(n, size);
}
void *__wrap__memalign_r(struct _reent *r, size_t align, size_t size)
{
return __wrap_memalign(align, size);
}
void __wrap__free_r(struct _reent *r, void *p)
{
__wrap_free(p);
}
size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p)
{
return __wrap_malloc_usable_size(p);
}
void *__wrap__realloc_r(struct _reent *r, void *p, size_t size)
{
return __wrap_realloc(p, size);
}
//!-------------------------------------------------------------------------------------------
//! some wrappers
//!-------------------------------------------------------------------------------------------
void * MEM2_alloc(unsigned int size, unsigned int align)
{
return __wrap_memalign(align, size);
}
void MEM2_free(void *ptr)
{
__wrap_free(ptr);
}
void * MEM1_alloc(unsigned int size, unsigned int align)
{
if (align < 4)
align = 4;
return MEMAllocFromExpHeapEx(mem1_heap, size, align);
}
void MEM1_free(void *ptr)
{
MEMFreeToExpHeap(mem1_heap, ptr);
}
void * MEMBucket_alloc(unsigned int size, unsigned int align)
{
if (align < 4)
align = 4;
return MEMAllocFromExpHeapEx(bucket_heap, size, align);
}
void MEMBucket_free(void *ptr)
{
MEMFreeToExpHeap(bucket_heap, ptr);
}

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

@ -0,0 +1,42 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef __MEMORY_H_
#define __MEMORY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <malloc.h>
void memoryInitialize(void);
void memoryRelease(void);
void * MEM2_alloc(unsigned int size, unsigned int align);
void MEM2_free(void *ptr);
void * MEM1_alloc(unsigned int size, unsigned int align);
void MEM1_free(void *ptr);
void * MEMBucket_alloc(unsigned int size, unsigned int align);
void MEMBucket_free(void *ptr);
#ifdef __cplusplus
}
#endif
#endif // __MEMORY_H_

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

@ -0,0 +1,89 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "common/common.h"
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "logger.h"
#ifdef DEBUG_LOGGER
static int log_socket = -1;
static volatile int log_lock = 0;
void log_init(const char * ipString)
{
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0)
return;
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = 4405;
inet_aton(ipString, &connect_addr.sin_addr);
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
{
socketclose(log_socket);
log_socket = -1;
}
}
void log_deinit(void)
{
if(log_socket >= 0)
{
socketclose(log_socket);
log_socket = -1;
}
}
void log_print(const char *str)
{
// socket is always 0 initially as it is in the BSS
if(log_socket < 0) {
return;
}
while(log_lock)
usleep(1000);
log_lock = 1;
int len = strlen(str);
int ret;
while (len > 0) {
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
ret = send(log_socket, str, block, 0);
if(ret < 0)
break;
len -= ret;
str += ret;
}
log_lock = 0;
}
void log_printf(const char *format, ...)
{
if(log_socket < 0) {
return;
}
char * tmp = NULL;
va_list va;
va_start(va, format);
if((vasprintf(&tmp, format, va) >= 0) && tmp)
{
log_print(tmp);
}
va_end(va);
if(tmp)
free(tmp);
}
#endif

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

@ -0,0 +1,26 @@
#ifndef __LOGGER_H_
#define __LOGGER_H_
#ifdef __cplusplus
extern "C" {
#endif
#define DEBUG_LOGGER 1
#ifdef DEBUG_LOGGER
void log_init(const char * ip);
void log_deinit(void);
void log_print(const char *str);
void log_printf(const char *format, ...);
#else
#define log_init(x)
#define log_deinit()
#define log_print(x)
#define log_printf(x, ...)
#endif
#ifdef __cplusplus
}
#endif
#endif

636
src/utils/net.c Normal file
View 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
View 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
View File

@ -0,0 +1,47 @@
#ifndef __UTILS_H_
#define __UTILS_H_
#include <malloc.h>
#include "../common/types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FlushBlock(addr) asm volatile("dcbf %0, %1\n" \
"icbi %0, %1\n" \
"sync\n" \
"eieio\n" \
"isync\n" \
: \
:"r"(0), "r"(((addr) & ~31)) \
:"memory", "ctr", "lr", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" \
);
#define LIMIT(x, min, max) \
({ \
typeof( x ) _x = x; \
typeof( min ) _min = min; \
typeof( max ) _max = max; \
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
})
#define DegToRad(a) ( (a) * 0.01745329252f )
#define RadToDeg(a) ( (a) * 57.29577951f )
#define ALIGN4(x) (((x) + 3) & ~3)
#define ALIGN32(x) (((x) + 31) & ~31)
// those work only in powers of 2
#define ROUNDDOWN(val, align) ((val) & ~(align-1))
#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align)
#define le16(i) ((((u16) ((i) & 0xFF)) << 8) | ((u16) (((i) & 0xFF00) >> 8)))
#define le32(i) ((((u32)le16((i) & 0xFFFF)) << 16) | ((u32)le16(((i) & 0xFFFF0000) >> 16)))
#define le64(i) ((((u64)le32((i) & 0xFFFFFFFFLL)) << 32) | ((u64)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
#ifdef __cplusplus
}
#endif
#endif // __UTILS_H_

View 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;
}

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

View 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;
}

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

View 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

View 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

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

View 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;
}

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

View 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;
}

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

View 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;
}

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

View 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