Merge branch 'master' of github.com:smealum/ctrulib
Conflicts: libctru/include/ctr/GSP.h libctru/source/GSP.c
This commit is contained in:
commit
4beea43184
@ -1,7 +1,7 @@
|
||||
CC = arm-none-eabi-gcc
|
||||
LINK = arm-none-eabi-ld
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
CTRULIB = "../libctru"
|
||||
CTRULIB = ../libctru
|
||||
CFLAGS += -Wall -std=c99 -march=armv6 -O3 -I"$(CTRULIB)/include" -I$(DEVKITPRO)/libnds/include
|
||||
LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(CTRULIB)/lib"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.section ".text"
|
||||
.section ".init"
|
||||
.arm
|
||||
.align 4
|
||||
.global _init
|
||||
|
@ -139,6 +139,14 @@ int main()
|
||||
swapBuffers();
|
||||
copyBuffer();
|
||||
}
|
||||
else if(status == APP_SUSPENDING)
|
||||
{
|
||||
aptReturnToMenu();
|
||||
}
|
||||
else if(status == APP_SLEEPMODE)
|
||||
{
|
||||
aptWaitStatusEvent();
|
||||
}
|
||||
svc_sleepThread(16666666);
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,8 @@ CC = arm-none-eabi-gcc
|
||||
LINK = arm-none-eabi-gcc
|
||||
AS = arm-none-eabi-as
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
CTRULIB = "../libctru"
|
||||
AEMSTROPATH = "../../aemstro"
|
||||
CTRULIB = ../libctru
|
||||
AEMSTROPATH = ../../aemstro
|
||||
CFLAGS += -Wall -std=c99 -march=armv6 -O3 -I"$(CTRULIB)/include" -I$(DEVKITPRO)/libnds/include
|
||||
# LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(DEVKITARM)/lib/gcc/arm-none-eabi/4.7.1" -L"$(CTRULIB)/lib"
|
||||
# LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(CTRULIB)/lib"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.section ".text"
|
||||
.section ".init"
|
||||
.arm
|
||||
.align 4
|
||||
.global _init
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <ctr/SHDR.h>
|
||||
#include <ctr/svc.h>
|
||||
#include "costable.h"
|
||||
#include "test_vsh_bin.h"
|
||||
#include "test_shbin.h"
|
||||
|
||||
u8* gspHeap;
|
||||
u32* gxCmdBuf;
|
||||
@ -101,7 +101,7 @@ int main()
|
||||
|
||||
GPU_Reset(gxCmdBuf, gpuCmd, gpuCmdSize);
|
||||
|
||||
DVLB_s* shader=SHDR_ParseSHBIN((u32*)test_vsh_bin,test_vsh_bin_size);
|
||||
DVLB_s* shader=SHDR_ParseSHBIN((u32*)test_shbin,test_shbin_size);
|
||||
|
||||
APP_STATUS status;
|
||||
while((status=aptGetStatus())!=APP_EXITING)
|
||||
@ -128,6 +128,14 @@ int main()
|
||||
|
||||
swapBuffers();
|
||||
}
|
||||
else if(status == APP_SUSPENDING)
|
||||
{
|
||||
aptReturnToMenu();
|
||||
}
|
||||
else if(status == APP_SLEEPMODE)
|
||||
{
|
||||
aptWaitStatusEvent();
|
||||
}
|
||||
svc_sleepThread(16666666);
|
||||
}
|
||||
|
||||
|
2
libctru/.gitignore
vendored
Normal file
2
libctru/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
build
|
||||
lib
|
8
libctru/include/ctr/AC.h
Normal file
8
libctru/include/ctr/AC.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef AC_H
|
||||
#define AC_H
|
||||
|
||||
Result ACU_GetWifiStatus(Handle servhandle, u32 *out);
|
||||
Result ACU_WaitInternetConnection();
|
||||
|
||||
#endif
|
||||
|
@ -9,9 +9,13 @@ typedef enum{
|
||||
}NS_APPID; // cf http://3dbrew.org/wiki/NS#AppIDs
|
||||
|
||||
typedef enum{
|
||||
APP_NOTINITIALIZED,
|
||||
APP_RUNNING,
|
||||
APP_SUSPENDED,
|
||||
APP_EXITING
|
||||
APP_EXITING,
|
||||
APP_SUSPENDING,
|
||||
APP_SLEEPMODE,
|
||||
APP_PREPARE_SLEEPMODE
|
||||
}APP_STATUS;
|
||||
|
||||
extern Handle aptEvents[3];
|
||||
@ -23,10 +27,16 @@ void aptCloseSession();
|
||||
void aptSetupEventHandler();
|
||||
void aptSetStatus(APP_STATUS status);
|
||||
APP_STATUS aptGetStatus();
|
||||
u32 aptGetStatusPower();//This can be used when the status is APP_SUSPEND* to check how the return-to-menu was triggered: 0 = home-button, 1 = power-button.
|
||||
void aptSetStatusPower(u32 status);
|
||||
void aptReturnToMenu();//This should be called by the user application when aptGetStatus() returns APP_SUSPENDING, not calling this will result in return-to-menu being disabled with the status left at APP_SUSPENDING. This function will not return until the system returns to the application, or when the status was changed to APP_EXITING.
|
||||
void aptWaitStatusEvent();
|
||||
NS_APPID aptGetMenuAppID();
|
||||
|
||||
Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle);
|
||||
Result APT_Initialize(Handle* handle, NS_APPID appId, Handle* eventHandle1, Handle* eventHandle2);
|
||||
Result APT_Enable(Handle* handle, u32 a);
|
||||
Result APT_GetAppletManInfo(Handle* handle, u8 inval, u8 *outval8, u32 *outval32, NS_APPID *menu_appid, NS_APPID *active_appid);
|
||||
Result APT_PrepareToJumpToHomeMenu(Handle* handle);
|
||||
Result APT_JumpToHomeMenu(Handle* handle, u32 a, u32 b, u32 c);
|
||||
Result APT_InquireNotification(Handle* handle, u32 appID, u8* signalType);
|
||||
@ -34,7 +44,10 @@ Result APT_NotifyToWait(Handle* handle, NS_APPID appID);
|
||||
Result APT_AppletUtility(Handle* handle, u32* out, u32 a, u32 size1, u8* buf1, u32 size2, u8* buf2);
|
||||
Result APT_GlanceParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize, u8* signalType);
|
||||
Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32* buffer, u32* actualSize, u8* signalType);
|
||||
Result APT_SendParameter(Handle* handle, NS_APPID src_appID, NS_APPID dst_appID, u32 bufferSize, u32* buffer, Handle paramhandle, u8 signalType);
|
||||
Result APT_SendCaptureBufferInfo(Handle* handle, u32 bufferSize, u32* buffer);
|
||||
Result APT_ReplySleepQuery(Handle* handle, NS_APPID appID, u32 a);
|
||||
Result APT_ReplySleepNotificationComplete(Handle* handle, NS_APPID appID);
|
||||
Result APT_PrepareToCloseApplication(Handle* handle, u8 a);
|
||||
Result APT_CloseApplication(Handle* handle, u32 a, u32 b, u32 c);
|
||||
|
||||
|
12
libctru/include/ctr/CFGNOR.h
Normal file
12
libctru/include/ctr/CFGNOR.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef CFGNOR_H
|
||||
#define CFGNOR_H
|
||||
|
||||
Result CFGNOR_Initialize(u8 value);
|
||||
Result CFGNOR_Shutdown();
|
||||
Result CFGNOR_ReadData(u32 offset, u32 *buf, u32 size);
|
||||
Result CFGNOR_WriteData(u32 offset, u32 *buf, u32 size);
|
||||
Result CFGNOR_DumpFlash(u32 *buf, u32 size);
|
||||
Result CFGNOR_WriteFlash(u32 *buf, u32 size);
|
||||
|
||||
#endif
|
||||
|
19
libctru/include/ctr/CSND.h
Normal file
19
libctru/include/ctr/CSND.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef CSND_H
|
||||
#define CSND_H
|
||||
|
||||
#define CSND_SHAREDMEM_DEFAULT 0x10004000
|
||||
|
||||
Result CSND_initialize(u32* sharedMem);
|
||||
Result CSND_shutdown();
|
||||
|
||||
Result CSND_playsound(u32 channel, u32 looping, u32 encoding, u32 samplerate, u32 *vaddr0, u32 *vaddr1, u32 totalbytesize, u32 unk0, u32 unk1);
|
||||
void CSND_setchannel_playbackstate(u32 channel, u32 value);
|
||||
void CSND_sharedmemtype0_cmd0(u32 channel, u32 value);
|
||||
void CSND_writesharedmem_cmdtype0(u16 cmdid, u8 *cmdparams);
|
||||
Result CSND_sharedmemtype0_cmdupdatestate(int waitdone);
|
||||
|
||||
Result CSND_getchannelstate(u32 entryindex, u32 *out);
|
||||
Result CSND_getchannelstate_isplaying(u32 entryindex, u8 *status);
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@ Result FSFILE_Close(Handle handle);
|
||||
Result FSFILE_Read(Handle handle, u32 *bytesRead, u64 offset, u32 *buffer, u32 size);
|
||||
Result FSFILE_Write(Handle handle, u32 *bytesWritten, u64 offset, u32 *buffer, u32 size, u32 flushFlags);
|
||||
Result FSFILE_GetSize(Handle handle, u64 *size);
|
||||
Result FSFILE_SetSize(Handle handle, u64 size);
|
||||
|
||||
Result FSDIR_Read(Handle handle, u32 *entriesRead, u32 entrycount, u16 *buffer);
|
||||
Result FSDIR_Close(Handle handle);
|
||||
|
@ -3,12 +3,40 @@
|
||||
|
||||
#define GSP_REBASE_REG(r) ((r)-0x1EB00000)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 active_framebuf;//"0=first, 1=second"
|
||||
u32 *framebuf0_vaddr;//"Framebuffer virtual address, for the main screen this is the 3D left framebuffer"
|
||||
u32 *framebuf1_vaddr;//"For the main screen: 3D right framebuffer address"
|
||||
u32 framebuf_widthbytesize;//"Value for 0x1EF00X90, controls framebuffer width"
|
||||
u32 format;//"Framebuffer format, this u16 is written to the low u16 for LCD register 0x1EF00X70."
|
||||
u32 framebuf_dispselect;//"Value for 0x1EF00X78, controls which framebuffer is displayed"
|
||||
u32 unk;//"?"
|
||||
} GSP_FramebufferInfo;
|
||||
|
||||
typedef struct//See this for GSP_CaptureInfoEntry and GSP_CaptureInfo: http://3dbrew.org/wiki/GSPGPU:ImportDisplayCaptureInfo
|
||||
{
|
||||
u32 *framebuf0_vaddr;
|
||||
u32 *framebuf1_vaddr;
|
||||
u32 format;
|
||||
u32 framebuf_widthbytesize;
|
||||
} GSP_CaptureInfoEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GSP_CaptureInfoEntry screencapture[2];
|
||||
} GSP_CaptureInfo;
|
||||
|
||||
Result gspInit();
|
||||
void gspExit();
|
||||
|
||||
Result GSPGPU_AcquireRight(Handle *handle, u8 flags);
|
||||
Result GSPGPU_ReleaseRight(Handle *handle);
|
||||
Result GSPGPU_ImportDisplayCaptureInfo(Handle* handle, GSP_CaptureInfo *captureinfo);
|
||||
Result GSPGPU_SaveVramSysArea(Handle* handle);
|
||||
Result GSPGPU_RestoreVramSysArea(Handle* handle);
|
||||
Result GSPGPU_SetLcdForceBlack(Handle *handle, u8 flags);
|
||||
Result GSPGPU_SetBufferSwap(Handle* handle, u32 screenid, GSP_FramebufferInfo *framebufinfo);
|
||||
Result GSPGPU_FlushDataCache(Handle *handle, u8* adr, u32 size);
|
||||
Result GSPGPU_InvalidateDataCache(Handle* handle, u8* adr, u32 size);
|
||||
Result GSPGPU_WriteHWRegs(Handle *handle, u32 regAddr, u32* data, u8 size);
|
||||
|
15
libctru/include/ctr/IR.h
Normal file
15
libctru/include/ctr/IR.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef IR_H
|
||||
#define IR_H
|
||||
|
||||
Result IRU_Initialize(u32 *sharedmem_addr, u32 sharedmem_size);//The permissions for the specified memory is set to RO. This memory must be already mapped.
|
||||
Result IRU_Shutdown();
|
||||
Handle IRU_GetServHandle();
|
||||
Result IRU_SendData(u8 *buf, u32 size, u32 wait);
|
||||
Result IRU_RecvData(u8 *buf, u32 size, u8 flag, u32 *transfercount, u32 wait);
|
||||
Result IRU_SetBitRate(u8 value);
|
||||
Result IRU_GetBitRate(u8 *out);
|
||||
Result IRU_SetIRLEDState(u32 value);
|
||||
Result IRU_GetIRLEDRecvState(u32 *out);
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef SOC_H
|
||||
#define SOC_H
|
||||
|
||||
Result SOC_Initialize(u32 *context_addr, u32 context_size);
|
||||
Result SOC_Initialize(u32 *context_addr, u32 context_size);//Example context_size: 0x48000. The specified context buffer can no longer be accessed by the process which called this function, since the userland permissions for this block are set to no-access.
|
||||
Result SOC_Shutdown();
|
||||
int SOC_GetErrno();
|
||||
|
||||
|
@ -24,6 +24,7 @@ typedef enum{
|
||||
Result svc_createMutex(Handle* mutex, bool initialLocked);
|
||||
Result svc_releaseMutex(Handle handle);
|
||||
Result svc_createEvent(Handle* event, u8 resettype);
|
||||
Result svc_signalEvent(Handle handle);
|
||||
Result svc_clearEvent(Handle handle);
|
||||
Result svc_createMemoryBlock(Handle* memblock, u32 addr, u32 size, u32 mypermission, u32 otherpermission);
|
||||
Result svc_mapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission);
|
||||
@ -31,8 +32,10 @@ typedef enum{
|
||||
Result svc_waitSynchronization1(Handle handle, s64 nanoseconds);
|
||||
Result svc_waitSynchronizationN(s32* out, Handle* handles, s32 handlecount, bool waitAll, s64 nanoseconds);
|
||||
Result svc_closeHandle(Handle handle);
|
||||
u64 svc_getSystemTick();
|
||||
Result svc_getSystemInfo(s64* out, u32 type, s32 param);
|
||||
Result svc_connectToPort(volatile Handle* out, const char* portName);
|
||||
Result svc_sendSyncRequest(Handle session);
|
||||
Result svc_getProcessId(u32 *out, Handle handle);
|
||||
|
||||
#endif
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define U64_MAX (0xFFFFFFFFFFFFFFFF)
|
||||
#define U64_MAX UINT64_MAX
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
@ -26,8 +26,6 @@
|
||||
typedef volatile s32 vs32;
|
||||
typedef volatile s64 vs64;
|
||||
|
||||
typedef u16 wchar;
|
||||
|
||||
typedef u32 Handle;
|
||||
typedef s32 Result;
|
||||
typedef void (*ThreadFunc)(u32);
|
||||
|
87
libctru/source/AC.c
Normal file
87
libctru/source/AC.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctr/types.h>
|
||||
|
||||
#include <ctr/AC.h>
|
||||
#include <ctr/svc.h>
|
||||
#include <ctr/srv.h>
|
||||
|
||||
Result ACU_cmd1(Handle servhandle, u32 *ptr)//Unknown what this cmd does at the time of writing. (ptr=0x200-byte outbuf)
|
||||
{
|
||||
u32 tmp0, tmp1;
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
tmp0 = cmdbuf[0x100>>2];
|
||||
tmp1 = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0] = 0x00010000;
|
||||
cmdbuf[0x100>>2] = 0x00800002;
|
||||
cmdbuf[0x104>>2] = (u32)ptr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(servhandle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = tmp0;
|
||||
cmdbuf[0x104>>2] = tmp1;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result ACU_cmd26(Handle servhandle, u32 *ptr, u8 val)//Unknown what this cmd does at the time of writing. (ptr=0x200-byte inbuf/outbuf)
|
||||
{
|
||||
u32 tmp0, tmp1;
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
tmp0 = cmdbuf[0x100>>2];
|
||||
tmp1 = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0] = 0x00260042;
|
||||
cmdbuf[1] = (u32)val;
|
||||
cmdbuf[0x100>>2] = 0x00800002;
|
||||
cmdbuf[0x104>>2] = (u32)ptr;
|
||||
cmdbuf[2] = 0x00800002;
|
||||
cmdbuf[3] = (u32)ptr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(servhandle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = tmp0;
|
||||
cmdbuf[0x104>>2] = tmp1;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result ACU_GetWifiStatus(Handle servhandle, u32 *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x000D0000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(servhandle))!=0)return ret;
|
||||
|
||||
*out = cmdbuf[2];
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result ACU_WaitInternetConnection()
|
||||
{
|
||||
Handle servhandle = 0;
|
||||
Result ret=0;
|
||||
u32 outval=0;
|
||||
|
||||
if((ret = srv_getServiceHandle(NULL, &servhandle, "ac:u"))!=0)return ret;
|
||||
|
||||
while(1)
|
||||
{
|
||||
ret = ACU_GetWifiStatus(servhandle, &outval);
|
||||
if(ret==0 && outval==1)break;
|
||||
}
|
||||
|
||||
svc_closeHandle(servhandle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -19,13 +19,166 @@ Handle aptEventHandlerThread;
|
||||
u64 aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]; //u64 so that it's 8-byte aligned
|
||||
|
||||
Handle aptStatusMutex;
|
||||
u32 aptStatus;
|
||||
Handle aptStatusEvent = 0;
|
||||
APP_STATUS aptStatus = APP_NOTINITIALIZED;
|
||||
APP_STATUS aptStatus_beforesleepmode = APP_NOTINITIALIZED;
|
||||
u32 aptStatusPower = 0;
|
||||
|
||||
u32 aptParameters[0x1000/4]; //TEMP
|
||||
|
||||
void aptInitCaptureInfo(u32 *ns_capinfo)
|
||||
{
|
||||
u32 tmp=0;
|
||||
u32 main_pixsz, sub_pixsz;
|
||||
GSP_CaptureInfo gspcapinfo;
|
||||
|
||||
memset(&gspcapinfo, 0, sizeof(GSP_CaptureInfo));
|
||||
|
||||
GSPGPU_ImportDisplayCaptureInfo(NULL, &gspcapinfo);
|
||||
|
||||
if(gspcapinfo.screencapture[0].framebuf0_vaddr != gspcapinfo.screencapture[1].framebuf0_vaddr)ns_capinfo[1] = 1;
|
||||
|
||||
ns_capinfo[4] = gspcapinfo.screencapture[0].format & 0x7;
|
||||
ns_capinfo[7] = gspcapinfo.screencapture[1].format & 0x7;
|
||||
|
||||
if(ns_capinfo[4] < 2)
|
||||
{
|
||||
main_pixsz = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
main_pixsz = 2;
|
||||
}
|
||||
|
||||
if(ns_capinfo[7] < 2)
|
||||
{
|
||||
sub_pixsz = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
sub_pixsz = 2;
|
||||
}
|
||||
|
||||
ns_capinfo[2] = sub_pixsz * 0x14000;
|
||||
ns_capinfo[3] = ns_capinfo[2];
|
||||
|
||||
if(ns_capinfo[1])ns_capinfo[3] = main_pixsz * 0x19000 + ns_capinfo[2];
|
||||
|
||||
tmp = main_pixsz * 0x19000 + ns_capinfo[3];
|
||||
ns_capinfo[0] = main_pixsz * 0x7000 + tmp;
|
||||
}
|
||||
|
||||
void aptWaitStatusEvent()
|
||||
{
|
||||
svc_waitSynchronization1(aptStatusEvent, U64_MAX);
|
||||
svc_clearEvent(aptStatusEvent);
|
||||
}
|
||||
|
||||
void aptAppletUtility_Exit_RetToApp()
|
||||
{
|
||||
u8 buf1[4], buf2[4];
|
||||
|
||||
memset(buf1, 0, 4);
|
||||
|
||||
buf1[0]=0x10;
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
|
||||
buf1[0]=0x00;
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
|
||||
buf1[0]=0x01;
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
|
||||
buf1[0]=0x00;
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
}
|
||||
|
||||
NS_APPID aptGetMenuAppID()
|
||||
{
|
||||
NS_APPID menu_appid;
|
||||
|
||||
aptOpenSession();
|
||||
APT_GetAppletManInfo(NULL, 0xff, NULL, NULL, &menu_appid, NULL);
|
||||
aptCloseSession();
|
||||
|
||||
return menu_appid;
|
||||
}
|
||||
|
||||
void aptReturnToMenu()
|
||||
{
|
||||
NS_APPID menu_appid;
|
||||
u32 tmp0 = 1, tmp1 = 0;
|
||||
u32 ns_capinfo[0x20>>2];
|
||||
u32 tmp_params[0x20>>2];
|
||||
|
||||
if(aptGetStatusPower()==0)//This is only executed when ret-to-menu was triggered via the home-button, not the power-button.
|
||||
{
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x6, 0x4, (u8*)&tmp0, 0x1, (u8*)&tmp1);
|
||||
aptCloseSession();
|
||||
}
|
||||
|
||||
aptOpenSession();
|
||||
APT_PrepareToJumpToHomeMenu(NULL); //prepare for return to menu
|
||||
aptCloseSession();
|
||||
|
||||
svc_clearEvent(aptStatusEvent);
|
||||
aptSetStatus(APP_SUSPENDED);
|
||||
|
||||
GSPGPU_SaveVramSysArea(NULL);
|
||||
|
||||
memset(tmp_params, 0, 0x20);
|
||||
memset(ns_capinfo, 0, 0x20);
|
||||
|
||||
aptInitCaptureInfo(ns_capinfo);
|
||||
|
||||
menu_appid = aptGetMenuAppID();
|
||||
|
||||
aptOpenSession();
|
||||
APT_SendParameter(NULL, currentAppId, menu_appid, 0x20, ns_capinfo, 0x0, 0x10);
|
||||
aptCloseSession();
|
||||
|
||||
aptOpenSession();
|
||||
APT_SendCaptureBufferInfo(NULL, 0x20, ns_capinfo);
|
||||
aptCloseSession();
|
||||
|
||||
GSPGPU_ReleaseRight(NULL); //disable GSP module access
|
||||
|
||||
aptOpenSession();
|
||||
APT_JumpToHomeMenu(NULL, 0x0, 0x0, 0x0); //jump !
|
||||
aptCloseSession();
|
||||
|
||||
aptOpenSession();
|
||||
APT_NotifyToWait(NULL, currentAppId);
|
||||
aptCloseSession();
|
||||
|
||||
if(aptGetStatusPower()==0)//This is only executed when ret-to-menu was triggered via the home-button, not the power-button.
|
||||
{
|
||||
tmp0 = 0;
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, (u8*)&tmp0, 0x1, (u8*)&tmp1);
|
||||
aptCloseSession();
|
||||
}
|
||||
|
||||
aptWaitStatusEvent();
|
||||
}
|
||||
|
||||
void aptEventHandler(u32 arg)
|
||||
{
|
||||
bool runThread=true;
|
||||
|
||||
while(runThread)
|
||||
{
|
||||
s32 syncedID=0x0;
|
||||
@ -45,17 +198,44 @@ void aptEventHandler(u32 arg)
|
||||
switch(signalType)
|
||||
{
|
||||
case 0x1: //home menu button got pressed
|
||||
case 0x8: //power button got pressed
|
||||
if(aptGetStatus()==APP_RUNNING)
|
||||
{
|
||||
aptOpenSession();
|
||||
APT_ReplySleepQuery(NULL, currentAppId, 0x0);
|
||||
aptCloseSession();
|
||||
|
||||
if(signalType==0x1)aptSetStatusPower(0);
|
||||
if(signalType==0x8)aptSetStatusPower(1);
|
||||
aptSetStatus(APP_SUSPENDING);//The main thread should call aptReturnToMenu() when the status gets set to this.
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x3: //preparing to enter sleep-mode
|
||||
aptStatus_beforesleepmode = aptGetStatus();
|
||||
aptOpenSession();
|
||||
APT_PrepareToJumpToHomeMenu(NULL); //prepare for return to menu
|
||||
APT_ReplySleepQuery(NULL, currentAppId, 0x1);
|
||||
aptCloseSession();
|
||||
aptSetStatus(APP_PREPARE_SLEEPMODE);
|
||||
break;
|
||||
|
||||
aptSetStatus(APP_SUSPENDED);
|
||||
case 0x5: //entering sleep-mode
|
||||
if(aptGetStatus()==APP_PREPARE_SLEEPMODE)
|
||||
{
|
||||
aptOpenSession();
|
||||
APT_ReplySleepNotificationComplete(NULL, currentAppId);
|
||||
aptCloseSession();
|
||||
aptSetStatus(APP_SLEEPMODE);
|
||||
}
|
||||
break;
|
||||
|
||||
GSPGPU_ReleaseRight(NULL); //disable GSP module access
|
||||
|
||||
aptOpenSession();
|
||||
APT_JumpToHomeMenu(NULL, 0x0, 0x0, 0x0); //jump !
|
||||
aptCloseSession();
|
||||
case 0x6: //leaving sleep-mode
|
||||
if(aptGetStatus()==APP_SLEEPMODE)
|
||||
{
|
||||
if(aptStatus_beforesleepmode == APP_RUNNING)GSPGPU_SetLcdForceBlack(NULL, 0);
|
||||
aptSetStatus(aptStatus_beforesleepmode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -73,13 +253,11 @@ void aptEventHandler(u32 arg)
|
||||
break;
|
||||
case 0xB: //just returned from menu
|
||||
GSPGPU_AcquireRight(NULL, 0x0);
|
||||
GSPGPU_RestoreVramSysArea(NULL);
|
||||
aptAppletUtility_Exit_RetToApp();
|
||||
aptSetStatus(APP_RUNNING);
|
||||
break;
|
||||
case 0xC: //exiting application
|
||||
aptOpenSession();
|
||||
APT_ReplySleepQuery(NULL, currentAppId, 0x0);
|
||||
aptCloseSession();
|
||||
|
||||
runThread=false;
|
||||
aptSetStatus(APP_EXITING); //app exit signal
|
||||
break;
|
||||
@ -117,31 +295,21 @@ Result aptInit(NS_APPID appID)
|
||||
if((ret=APT_NotifyToWait(NULL, currentAppId)))return ret;
|
||||
aptCloseSession();
|
||||
|
||||
svc_createEvent(&aptStatusEvent, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aptExit()
|
||||
{
|
||||
u8 buf1[4], buf2[4];
|
||||
|
||||
buf1[0]=0x02; buf1[1]=0x00; buf1[2]=0x00; buf1[3]=0x00;
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
aptAppletUtility_Exit_RetToApp();
|
||||
|
||||
if(aptGetStatusPower()==1)//This is only executed when application-termination was triggered via the home-menu power-off screen.
|
||||
{
|
||||
aptOpenSession();
|
||||
APT_ReplySleepQuery(NULL, currentAppId, 0x0);
|
||||
aptCloseSession();
|
||||
}
|
||||
|
||||
aptOpenSession();
|
||||
APT_PrepareToCloseApplication(NULL, 0x1);
|
||||
@ -153,13 +321,14 @@ void aptExit()
|
||||
|
||||
svc_closeHandle(aptStatusMutex);
|
||||
// svc_closeHandle(aptLockHandle);
|
||||
svc_closeHandle(aptStatusEvent);
|
||||
}
|
||||
|
||||
void aptSetupEventHandler()
|
||||
{
|
||||
u8 buf1[4], buf2[4];
|
||||
|
||||
buf1[0]=0x02; buf1[1]=0x00; buf1[2]=0x00; buf1[3]=0x04;
|
||||
/*buf1[0]=0x02; buf1[1]=0x00; buf1[2]=0x00; buf1[3]=0x04;
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
@ -177,6 +346,22 @@ void aptSetupEventHandler()
|
||||
APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
|
||||
aptCloseSession();*/
|
||||
|
||||
memset(buf1, 0, 4);
|
||||
|
||||
buf1[0] = 0x10;
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x7, 0x4, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
|
||||
buf1[0] = 0x00;
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
|
||||
aptOpenSession();
|
||||
APT_AppletUtility(NULL, NULL, 0x4, 0x1, buf1, 0x1, buf2);
|
||||
aptCloseSession();
|
||||
@ -185,6 +370,8 @@ void aptSetupEventHandler()
|
||||
aptStatus=0;
|
||||
svc_releaseMutex(aptStatusMutex);
|
||||
|
||||
aptSetStatus(APP_RUNNING);
|
||||
|
||||
//create thread for stuff handling APT events
|
||||
svc_createThread(&aptEventHandlerThread, aptEventHandler, 0x0, (u32*)(&aptEventHandlerStack[APT_HANDLER_STACKSIZE/8]), 0x31, 0xfffffffe);
|
||||
}
|
||||
@ -200,8 +387,35 @@ APP_STATUS aptGetStatus()
|
||||
|
||||
void aptSetStatus(APP_STATUS status)
|
||||
{
|
||||
u32 prevstatus;
|
||||
|
||||
svc_waitSynchronization1(aptStatusMutex, U64_MAX);
|
||||
aptStatus=status;
|
||||
|
||||
prevstatus = status;
|
||||
aptStatus = status;
|
||||
|
||||
if(prevstatus!=APP_NOTINITIALIZED)
|
||||
{
|
||||
if(status==APP_RUNNING)svc_signalEvent(aptStatusEvent);
|
||||
if(status==APP_EXITING)svc_signalEvent(aptStatusEvent);
|
||||
}
|
||||
|
||||
svc_releaseMutex(aptStatusMutex);
|
||||
}
|
||||
|
||||
u32 aptGetStatusPower()
|
||||
{
|
||||
u32 ret;
|
||||
svc_waitSynchronization1(aptStatusMutex, U64_MAX);
|
||||
ret=aptStatusPower;
|
||||
svc_releaseMutex(aptStatusMutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void aptSetStatusPower(u32 status)
|
||||
{
|
||||
svc_waitSynchronization1(aptStatusMutex, U64_MAX);
|
||||
aptStatusPower = status;
|
||||
svc_releaseMutex(aptStatusMutex);
|
||||
}
|
||||
|
||||
@ -262,6 +476,24 @@ Result APT_Enable(Handle* handle, u32 a)
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_GetAppletManInfo(Handle* handle, u8 inval, u8 *outval8, u32 *outval32, NS_APPID *menu_appid, NS_APPID *active_appid)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x00050040; //request header code
|
||||
cmdbuf[1]=inval;
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svc_sendSyncRequest(*handle)))return ret;
|
||||
|
||||
if(outval8)*outval8=cmdbuf[2];
|
||||
if(outval32)*outval32=cmdbuf[3];
|
||||
if(menu_appid)*menu_appid=cmdbuf[4];
|
||||
if(active_appid)*active_appid=cmdbuf[5];
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_InquireNotification(Handle* handle, u32 appID, u8* signalType)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
@ -380,6 +612,47 @@ Result APT_ReceiveParameter(Handle* handle, NS_APPID appID, u32 bufferSize, u32*
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_SendParameter(Handle* handle, NS_APPID src_appID, NS_APPID dst_appID, u32 bufferSize, u32* buffer, Handle paramhandle, u8 signalType)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
if(!handle)handle=&aptuHandle;
|
||||
|
||||
cmdbuf[0] = 0x000C0104; //request header code
|
||||
cmdbuf[1] = src_appID;
|
||||
cmdbuf[2] = dst_appID;
|
||||
cmdbuf[3] = signalType;
|
||||
cmdbuf[4] = bufferSize;
|
||||
|
||||
cmdbuf[5]=0x0;
|
||||
cmdbuf[6] = paramhandle;
|
||||
|
||||
cmdbuf[7] = (bufferSize<<14) | 2;
|
||||
cmdbuf[8] = (u32)buffer;
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svc_sendSyncRequest(*handle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_SendCaptureBufferInfo(Handle* handle, u32 bufferSize, u32* buffer)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
if(!handle)handle=&aptuHandle;
|
||||
|
||||
cmdbuf[0] = 0x00400042; //request header code
|
||||
cmdbuf[1] = bufferSize;
|
||||
cmdbuf[2] = (bufferSize<<14) | 2;
|
||||
cmdbuf[3] = (u32)buffer;
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svc_sendSyncRequest(*handle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_ReplySleepQuery(Handle* handle, NS_APPID appID, u32 a)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
@ -395,6 +668,20 @@ Result APT_ReplySleepQuery(Handle* handle, NS_APPID appID, u32 a)
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_ReplySleepNotificationComplete(Handle* handle, NS_APPID appID)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x3F0040; //request header code
|
||||
cmdbuf[1]=appID;
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svc_sendSyncRequest(*handle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result APT_PrepareToCloseApplication(Handle* handle, u8 a)
|
||||
{
|
||||
if(!handle)handle=&aptuHandle;
|
||||
|
113
libctru/source/CFGNOR.c
Normal file
113
libctru/source/CFGNOR.c
Normal file
@ -0,0 +1,113 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ctr/types.h>
|
||||
#include <ctr/svc.h>
|
||||
#include <ctr/srv.h>
|
||||
|
||||
#include <ctr/CFGNOR.h>
|
||||
|
||||
Handle CFGNOR_handle = 0;
|
||||
|
||||
Result CFGNOR_Initialize(u8 value)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
ret = srv_getServiceHandle(NULL, &CFGNOR_handle, "cfg:nor");
|
||||
if(ret!=0)return ret;
|
||||
|
||||
cmdbuf[0] = 0x00010040;
|
||||
cmdbuf[1] = (u32)value;
|
||||
|
||||
if((ret = svc_sendSyncRequest(CFGNOR_handle))!=0)return ret;
|
||||
|
||||
ret = (Result)cmdbuf[1];
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result CFGNOR_Shutdown()
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00020000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(CFGNOR_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
svc_closeHandle(CFGNOR_handle);
|
||||
CFGNOR_handle = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result CFGNOR_ReadData(u32 offset, u32 *buf, u32 size)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00050082;
|
||||
cmdbuf[1] = offset;
|
||||
cmdbuf[2] = size;
|
||||
cmdbuf[3] = (size<<4) | 12;
|
||||
cmdbuf[4] = (u32)buf;
|
||||
|
||||
if((ret = svc_sendSyncRequest(CFGNOR_handle))!=0)return ret;
|
||||
|
||||
ret = (Result)cmdbuf[1];
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result CFGNOR_WriteData(u32 offset, u32 *buf, u32 size)
|
||||
{
|
||||
u32 ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00060082;
|
||||
cmdbuf[1] = offset;
|
||||
cmdbuf[2] = size;
|
||||
cmdbuf[3] = (size<<4) | 10;
|
||||
cmdbuf[4] = (u32)buf;
|
||||
|
||||
if((ret = svc_sendSyncRequest(CFGNOR_handle))!=0)return ret;
|
||||
|
||||
ret = (Result)cmdbuf[1];
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result CFGNOR_DumpFlash(u32 *buf, u32 size)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 pos=0;
|
||||
u32 chunksize = 0x100;
|
||||
|
||||
for(pos=0; pos<size; pos+=chunksize)
|
||||
{
|
||||
if(size-pos < chunksize)chunksize = size-pos;
|
||||
|
||||
ret = CFGNOR_ReadData(pos, &buf[pos>>2], chunksize);
|
||||
if(ret!=0)break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result CFGNOR_WriteFlash(u32 *buf, u32 size)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 pos=0;
|
||||
u32 chunksize = 0x100;
|
||||
|
||||
for(pos=0; pos<size; pos+=chunksize)
|
||||
{
|
||||
if(size-pos < chunksize)chunksize = size-pos;
|
||||
|
||||
ret = CFGNOR_WriteData(pos, &buf[pos>>2], chunksize);
|
||||
if(ret!=0)break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
325
libctru/source/CSND.c
Normal file
325
libctru/source/CSND.c
Normal file
@ -0,0 +1,325 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctr/types.h>
|
||||
|
||||
#include <ctr/CSND.h>
|
||||
#include <ctr/svc.h>
|
||||
#include <ctr/srv.h>
|
||||
|
||||
//See here regarding CSND shared-mem commands, etc: http://3dbrew.org/wiki/CSND_Shared_Memory
|
||||
|
||||
Handle CSND_handle = 0;
|
||||
Handle CSND_mutexhandle = 0;
|
||||
Handle CSND_sharedmemhandle = 0;
|
||||
u32 *CSND_sharedmem = NULL;
|
||||
static u32 CSND_bitmask=0;
|
||||
|
||||
static u32 CSND_sharedmem_cmdblocksize = 0x2000;
|
||||
static u32 CSND_sharedmem_startcmdoff = 0;
|
||||
static u32 CSND_sharedmem_currentcmdoff = 0;
|
||||
|
||||
Result CSND_cmd1(Handle *mutexhandle, Handle *sharedmemhandle, u32 sharedmem_size, u32 off0, u32 off1, u32 off2, u32 off3)
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00010140;
|
||||
cmdbuf[1] = sharedmem_size;
|
||||
cmdbuf[2] = off0;
|
||||
cmdbuf[3] = off1;
|
||||
cmdbuf[4] = off2;
|
||||
cmdbuf[5] = off3;
|
||||
|
||||
if((ret = svc_sendSyncRequest(CSND_handle))!=0)return ret;
|
||||
|
||||
*mutexhandle = cmdbuf[3];
|
||||
*sharedmemhandle = cmdbuf[4];
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result CSND_cmd2()
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00020000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(CSND_handle))!=0)return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result CSND_cmd5(u32 *bitmask)
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00050000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(CSND_handle))!=0)return ret;
|
||||
|
||||
*bitmask = cmdbuf[2];
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result CSND_initialize(u32* sharedMem)
|
||||
{
|
||||
Result ret=0;
|
||||
|
||||
if(sharedMem==NULL)sharedMem = (u32*)CSND_SHAREDMEM_DEFAULT;
|
||||
CSND_sharedmem = sharedMem;
|
||||
|
||||
ret = srv_getServiceHandle(NULL, &CSND_handle, "csnd:SND");
|
||||
if(ret!=0)return ret;
|
||||
|
||||
ret = CSND_cmd1(&CSND_mutexhandle, &CSND_sharedmemhandle, CSND_sharedmem_cmdblocksize+0x114, CSND_sharedmem_cmdblocksize, CSND_sharedmem_cmdblocksize+8, CSND_sharedmem_cmdblocksize+0xc8, CSND_sharedmem_cmdblocksize+0xd8);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
ret = svc_mapMemoryBlock(CSND_sharedmemhandle, (u32)CSND_sharedmem, 3, 0x10000000);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
memset(CSND_sharedmem, 0, 0x2114);
|
||||
|
||||
ret = CSND_cmd5(&CSND_bitmask);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result CSND_shutdown()
|
||||
{
|
||||
Result ret;
|
||||
|
||||
svc_unmapMemoryBlock(CSND_sharedmemhandle, (u32)CSND_sharedmem);
|
||||
svc_closeHandle(CSND_sharedmemhandle);
|
||||
|
||||
ret = CSND_cmd2();
|
||||
if(ret!=0)return ret;
|
||||
|
||||
return svc_closeHandle(CSND_handle);
|
||||
}
|
||||
|
||||
Result CSND_cmd3(u32 offset)
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00030040;
|
||||
cmdbuf[1] = offset;
|
||||
|
||||
if((ret = svc_sendSyncRequest(CSND_handle))!=0)return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
void CSND_writesharedmem_cmdtype0(u16 cmdid, u8 *cmdparams)
|
||||
{
|
||||
u16 *ptr;
|
||||
u32 prevoff;
|
||||
s32 outindex=0;
|
||||
|
||||
svc_waitSynchronizationN(&outindex, &CSND_mutexhandle, 1, 0, ~0);
|
||||
|
||||
if(CSND_sharedmem_startcmdoff != CSND_sharedmem_currentcmdoff)
|
||||
{
|
||||
if(CSND_sharedmem_currentcmdoff>=0x20)
|
||||
{
|
||||
prevoff = CSND_sharedmem_currentcmdoff-0x20;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevoff = CSND_sharedmem_cmdblocksize-0x20;
|
||||
}
|
||||
|
||||
ptr = (u16*)&CSND_sharedmem[prevoff>>2];
|
||||
*ptr = CSND_sharedmem_currentcmdoff;
|
||||
}
|
||||
|
||||
ptr = (u16*)&CSND_sharedmem[CSND_sharedmem_currentcmdoff>>2];
|
||||
|
||||
ptr[0] = 0xffff;
|
||||
ptr[1] = cmdid;
|
||||
ptr[2] = 0;
|
||||
ptr[3] = 0;
|
||||
memcpy(&ptr[8>>1], cmdparams, 0x18);
|
||||
|
||||
CSND_sharedmem_currentcmdoff+= 0x20;
|
||||
if(CSND_sharedmem_currentcmdoff >= CSND_sharedmem_cmdblocksize)CSND_sharedmem_currentcmdoff = 0;
|
||||
|
||||
svc_releaseMutex(CSND_mutexhandle);
|
||||
}
|
||||
|
||||
Result CSND_processtype0cmds()
|
||||
{
|
||||
Result ret=0;
|
||||
|
||||
if(CSND_sharedmem_startcmdoff == CSND_sharedmem_currentcmdoff)return 0;
|
||||
|
||||
ret = CSND_cmd3(CSND_sharedmem_startcmdoff);
|
||||
CSND_sharedmem_startcmdoff = CSND_sharedmem_currentcmdoff;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 CSND_convertsamplerate(u32 samplerate)
|
||||
{
|
||||
return (u32)(6.7027964E+07f / ((float)samplerate));
|
||||
}
|
||||
|
||||
void CSND_sharedmemtype0_cmd0(u32 channel, u32 value)
|
||||
{
|
||||
u32 cmdparams[0x18>>2];
|
||||
|
||||
memset(cmdparams, 0, 0x18);
|
||||
|
||||
cmdparams[0] = channel & 0x1f;
|
||||
cmdparams[1] = value;
|
||||
|
||||
CSND_writesharedmem_cmdtype0(0x0, (u8*)&cmdparams);
|
||||
}
|
||||
|
||||
void CSND_setchannel_playbackstate(u32 channel, u32 value)
|
||||
{
|
||||
u32 cmdparams[0x18>>2];
|
||||
|
||||
memset(cmdparams, 0, 0x18);
|
||||
|
||||
cmdparams[0] = channel & 0x1f;
|
||||
cmdparams[1] = value;
|
||||
|
||||
CSND_writesharedmem_cmdtype0(0x1, (u8*)&cmdparams);
|
||||
}
|
||||
|
||||
void CSND_sharedmemtype0_cmd3(u32 channel, u32 physaddr, u32 size)
|
||||
{
|
||||
u32 cmdparams[0x18>>2];
|
||||
|
||||
memset(cmdparams, 0, 0x18);
|
||||
|
||||
cmdparams[0] = channel & 0x1f;
|
||||
cmdparams[1] = physaddr;
|
||||
cmdparams[2] = size;
|
||||
|
||||
CSND_writesharedmem_cmdtype0(0x3, (u8*)&cmdparams);
|
||||
}
|
||||
|
||||
void CSND_sharedmemtype0_cmd9(u32 channel, u16 value)
|
||||
{
|
||||
u32 cmdparams[0x18>>2];
|
||||
|
||||
memset(cmdparams, 0, 0x18);
|
||||
|
||||
cmdparams[0] = channel & 0x1f;
|
||||
cmdparams[1] = value | (value<<16);
|
||||
|
||||
CSND_writesharedmem_cmdtype0(0x9, (u8*)&cmdparams);
|
||||
}
|
||||
|
||||
void CSND_sharedmemtype0_cmd8(u32 channel, u32 samplerate)
|
||||
{
|
||||
u32 cmdparams[0x18>>2];
|
||||
|
||||
memset(cmdparams, 0, 0x18);
|
||||
|
||||
cmdparams[0] = channel & 0x1f;
|
||||
cmdparams[1] = CSND_convertsamplerate(samplerate);
|
||||
|
||||
CSND_writesharedmem_cmdtype0(0x8, (u8*)&cmdparams);
|
||||
}
|
||||
|
||||
void CSND_sharedmemtype0_cmde(u32 channel, u32 looping, u32 encoding, u32 samplerate, u32 unk0, u32 unk1, u32 physaddr0, u32 physaddr1, u32 totalbytesize)
|
||||
{
|
||||
u32 val;
|
||||
u32 cmdparams[0x18>>2];
|
||||
|
||||
memset(cmdparams, 0, 0x18);
|
||||
|
||||
cmdparams[0] = channel & 0x1f;
|
||||
cmdparams[0] |= (unk0 & 0xf) << 6;
|
||||
if(!looping)cmdparams[0] |= 2 << 10;
|
||||
if(looping)cmdparams[0] |= 1 << 10;
|
||||
cmdparams[0] |= (encoding & 3) << 12;
|
||||
cmdparams[0] |= (unk1 & 3) << 14;
|
||||
|
||||
val = CSND_convertsamplerate(samplerate);
|
||||
if(val<0x42)val = 0x42;
|
||||
if(val>0xffff)val = 0xffff;
|
||||
cmdparams[0] |= val<<16;
|
||||
|
||||
cmdparams[3] = physaddr0;
|
||||
cmdparams[4] = physaddr1;
|
||||
cmdparams[5] = totalbytesize;
|
||||
|
||||
CSND_writesharedmem_cmdtype0(0xe, (u8*)&cmdparams);
|
||||
}
|
||||
|
||||
Result CSND_sharedmemtype0_cmdupdatestate(int waitdone)
|
||||
{
|
||||
u8 *ptr;
|
||||
int ret=0;
|
||||
|
||||
u32 cmdparams[0x18>>2];
|
||||
|
||||
memset(cmdparams, 0, 0x18);
|
||||
|
||||
ptr = (u8*)&CSND_sharedmem[CSND_sharedmem_startcmdoff>>2];
|
||||
|
||||
CSND_writesharedmem_cmdtype0(0x300, (u8*)&cmdparams);
|
||||
|
||||
ret = CSND_processtype0cmds();
|
||||
if(ret!=0)return ret;
|
||||
|
||||
if(waitdone)
|
||||
{
|
||||
while(*ptr == 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result CSND_playsound(u32 channel, u32 looping, u32 encoding, u32 samplerate, u32 *vaddr0, u32 *vaddr1, u32 totalbytesize, u32 unk0, u32 unk1)
|
||||
{
|
||||
u32 physaddr0 = 0;
|
||||
u32 physaddr1 = 0;
|
||||
|
||||
if((u32)vaddr0 >= 0x14000000 && (u32)vaddr0<0x1c000000)physaddr0 = (u32)vaddr0 + 0x0c000000;
|
||||
if((u32)vaddr1 >= 0x14000000 && (u32)vaddr1<0x1c000000)physaddr1 = (u32)vaddr1 + 0x0c000000;
|
||||
|
||||
CSND_sharedmemtype0_cmde(channel, looping, encoding, samplerate, unk0, unk1, physaddr0, physaddr1, totalbytesize);
|
||||
CSND_sharedmemtype0_cmd8(channel, samplerate);
|
||||
if(looping)CSND_sharedmemtype0_cmd3(channel, physaddr0, totalbytesize);
|
||||
CSND_sharedmemtype0_cmd8(channel, samplerate);
|
||||
CSND_sharedmemtype0_cmd9(channel, 0xffff);
|
||||
CSND_setchannel_playbackstate(channel, 1);
|
||||
|
||||
return CSND_sharedmemtype0_cmdupdatestate(0);
|
||||
}
|
||||
|
||||
Result CSND_getchannelstate(u32 entryindex, u32 *out)
|
||||
{
|
||||
Result ret=0;
|
||||
|
||||
if((ret = CSND_sharedmemtype0_cmdupdatestate(1))!=0)return ret;
|
||||
|
||||
memcpy(out, &CSND_sharedmem[(CSND_sharedmem_cmdblocksize+8 + entryindex*0xc) >> 2], 0xc);
|
||||
out[2] -= 0x0c000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result CSND_getchannelstate_isplaying(u32 entryindex, u8 *status)
|
||||
{
|
||||
Result ret;
|
||||
u32 entry[0xc>>2];
|
||||
|
||||
ret = CSND_getchannelstate(entryindex, entry);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
*status = entry[0] & 0xff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -189,6 +189,21 @@ Result FSFILE_GetSize(Handle handle, u64 *size)
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSFILE_SetSize(Handle handle, u64 size)
|
||||
{
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x08050080;
|
||||
cmdbuf[1] = (u32)size;
|
||||
cmdbuf[2] = (u32)(size >> 32);
|
||||
|
||||
Result ret = 0;
|
||||
if ((ret = svc_sendSyncRequest(handle)))return ret;
|
||||
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result FSDIR_Read(Handle handle, u32 *entriesRead, u32 entrycount, u16 *buffer)
|
||||
{
|
||||
u32 *cmdbuf=getThreadCommandBuffer();
|
||||
|
@ -47,6 +47,52 @@ Result GSPGPU_ReleaseRight(Handle* handle)
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result GSPGPU_ImportDisplayCaptureInfo(Handle* handle, GSP_CaptureInfo *captureinfo)
|
||||
{
|
||||
if(!handle)handle=&gspGpuHandle;
|
||||
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x00180000; //request header code
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svc_sendSyncRequest(*handle)))return ret;
|
||||
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(ret==0)
|
||||
{
|
||||
memcpy(captureinfo, &cmdbuf[2], 0x20);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result GSPGPU_SaveVramSysArea(Handle* handle)
|
||||
{
|
||||
if(!handle)handle=&gspGpuHandle;
|
||||
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x00190000; //request header code
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svc_sendSyncRequest(*handle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result GSPGPU_RestoreVramSysArea(Handle* handle)
|
||||
{
|
||||
if(!handle)handle=&gspGpuHandle;
|
||||
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x001A0000; //request header code
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svc_sendSyncRequest(*handle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result GSPGPU_SetLcdForceBlack(Handle* handle, u8 flags)
|
||||
{
|
||||
if(!handle)handle=&gspGpuHandle;
|
||||
@ -61,6 +107,22 @@ Result GSPGPU_SetLcdForceBlack(Handle* handle, u8 flags)
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result GSPGPU_SetBufferSwap(Handle* handle, u32 screenid, GSP_FramebufferInfo *framebufinfo)
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
if(!handle)handle=&gspGpuHandle;
|
||||
|
||||
cmdbuf[0] = 0x00050200;
|
||||
cmdbuf[1] = screenid;
|
||||
memcpy(&cmdbuf[2], framebufinfo, sizeof(GSP_FramebufferInfo));
|
||||
|
||||
if((ret=svc_sendSyncRequest(*handle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result GSPGPU_FlushDataCache(Handle* handle, u8* adr, u32 size)
|
||||
{
|
||||
if(!handle)handle=&gspGpuHandle;
|
||||
@ -80,16 +142,17 @@ Result GSPGPU_FlushDataCache(Handle* handle, u8* adr, u32 size)
|
||||
|
||||
Result GSPGPU_InvalidateDataCache(Handle* handle, u8* adr, u32 size)
|
||||
{
|
||||
Result ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
if(!handle)handle=&gspGpuHandle;
|
||||
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x90082; //request header code
|
||||
cmdbuf[1]=(u32)adr;
|
||||
cmdbuf[2]=size;
|
||||
cmdbuf[3]=0x0;
|
||||
cmdbuf[4]=0xffff8001;
|
||||
cmdbuf[0] = 0x00090082;
|
||||
cmdbuf[1] = (u32)adr;
|
||||
cmdbuf[2] = size;
|
||||
cmdbuf[3] = 0;
|
||||
cmdbuf[4] = 0xFFFF8001;
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svc_sendSyncRequest(*handle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
|
237
libctru/source/IR.c
Normal file
237
libctru/source/IR.c
Normal file
@ -0,0 +1,237 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ctr/types.h>
|
||||
#include <ctr/svc.h>
|
||||
#include <ctr/srv.h>
|
||||
|
||||
#include <ctr/IR.h>
|
||||
|
||||
static Handle iru_handle=0;
|
||||
static Handle iru_sharedmem_handle=0;
|
||||
static u32 *iru_sharedmem = NULL;
|
||||
static u32 iru_sharedmem_size = 0;
|
||||
|
||||
Result irucmd_Initialize()
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00010000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result irucmd_Shutdown()
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00020000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result irucmd_StartSendTransfer(u8 *buf, u32 size)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00030042;
|
||||
cmdbuf[1] = size;
|
||||
cmdbuf[2] = (size<<4) | 10;
|
||||
cmdbuf[3] = (u32)buf;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result irucmd_WaitSendTransfer()
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00040000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result irucmd_StartRecvTransfer(u32 size, u8 flag)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x000500C2;
|
||||
cmdbuf[1] = iru_sharedmem_size;
|
||||
cmdbuf[2] = size;
|
||||
cmdbuf[3] = (u8)flag;
|
||||
cmdbuf[4] = 0;
|
||||
cmdbuf[5] = iru_sharedmem_handle;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result irucmd_WaitRecvTransfer(u32 *transfercount)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00060000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
*transfercount = cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result IRU_SetBitRate(u8 value)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00090040;
|
||||
cmdbuf[1] = (u32)value;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result IRU_GetBitRate(u8 *out)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x000A0000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
*out = (u8)cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result IRU_SetIRLEDState(u32 value)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x000B0040;
|
||||
cmdbuf[1] = value;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result IRU_GetIRLEDRecvState(u32 *out)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x000C0000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(iru_handle))!=0)return ret;
|
||||
ret = (Result)cmdbuf[1];
|
||||
|
||||
*out = cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result IRU_Initialize(u32 *sharedmem_addr, u32 sharedmem_size)
|
||||
{
|
||||
Result ret = 0;
|
||||
|
||||
if(iru_handle)return 0;
|
||||
|
||||
ret = srv_getServiceHandle(NULL, &iru_handle, "ir:u");
|
||||
if(ret!=0)return ret;
|
||||
|
||||
ret = irucmd_Initialize();
|
||||
if(ret!=0)return ret;
|
||||
|
||||
ret = svc_createMemoryBlock(&iru_sharedmem_handle, (u32)sharedmem_addr, sharedmem_size, 1, 3);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
iru_sharedmem = sharedmem_addr;
|
||||
iru_sharedmem_size = sharedmem_size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result IRU_Shutdown()
|
||||
{
|
||||
Result ret = 0;
|
||||
|
||||
if(iru_handle==0)return 0;
|
||||
|
||||
ret = irucmd_Shutdown();
|
||||
if(ret!=0)return ret;
|
||||
|
||||
svc_closeHandle(iru_handle);
|
||||
svc_closeHandle(iru_sharedmem_handle);
|
||||
|
||||
iru_handle = 0;
|
||||
iru_sharedmem_handle = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Handle IRU_GetServHandle()
|
||||
{
|
||||
return iru_handle;
|
||||
}
|
||||
|
||||
Result IRU_SendData(u8 *buf, u32 size, u32 wait)
|
||||
{
|
||||
Result ret = 0;
|
||||
|
||||
ret = irucmd_StartSendTransfer(buf, size);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
if(wait==0)return 0;
|
||||
|
||||
return irucmd_WaitSendTransfer();
|
||||
}
|
||||
|
||||
Result IRU_RecvData(u8 *buf, u32 size, u8 flag, u32 *transfercount, u32 wait)
|
||||
{
|
||||
Result ret = 0;
|
||||
|
||||
*transfercount = 0;
|
||||
|
||||
ret = irucmd_StartRecvTransfer(size, flag);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
if(wait)
|
||||
{
|
||||
ret = irucmd_WaitRecvTransfer(transfercount);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
if(buf)memcpy(buf, iru_sharedmem, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@ -9,9 +10,103 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
static Handle socu_handle = 0;
|
||||
static int soc_errno = 0;
|
||||
Handle SOCU_handle = 0;
|
||||
static int SOCU_errno = 0;
|
||||
|
||||
#define NET_UNKNOWN_ERROR_OFFSET -10000//This is from libogc network_wii.c.
|
||||
|
||||
static u8 _net_error_code_map[] = { //This is based on the array from libogc network_wii.c.
|
||||
0, // 0
|
||||
E2BIG,
|
||||
EACCES,
|
||||
EADDRINUSE,
|
||||
EADDRNOTAVAIL,
|
||||
EAFNOSUPPORT, // 5
|
||||
EAGAIN,
|
||||
EALREADY,
|
||||
EBADF,
|
||||
EBADMSG,
|
||||
EBUSY, // 10
|
||||
ECANCELED,
|
||||
ECHILD,
|
||||
ECONNABORTED,
|
||||
ECONNREFUSED,
|
||||
ECONNRESET, // 15
|
||||
EDEADLK,
|
||||
EDESTADDRREQ,
|
||||
EDOM,
|
||||
EDQUOT,
|
||||
EEXIST, // 20
|
||||
EFAULT,
|
||||
EFBIG,
|
||||
EHOSTUNREACH,
|
||||
EIDRM,
|
||||
EILSEQ, // 25
|
||||
EINPROGRESS,
|
||||
EINTR,
|
||||
EINVAL,
|
||||
EIO,
|
||||
EISCONN, // 30
|
||||
EISDIR,
|
||||
ELOOP,
|
||||
EMFILE,
|
||||
EMLINK,
|
||||
EMSGSIZE, // 35
|
||||
EMULTIHOP,
|
||||
ENAMETOOLONG,
|
||||
ENETDOWN,
|
||||
ENETRESET,
|
||||
ENETUNREACH, // 40
|
||||
ENFILE,
|
||||
ENOBUFS,
|
||||
ENODATA,
|
||||
ENODEV,
|
||||
ENOENT, // 45
|
||||
ENOEXEC,
|
||||
ENOLCK,
|
||||
ENOLINK,
|
||||
ENOMEM,
|
||||
ENOMSG, // 50
|
||||
ENOPROTOOPT,
|
||||
ENOSPC,
|
||||
ENOSR,
|
||||
ENOSTR,
|
||||
ENOSYS, // 55
|
||||
ENOTCONN,
|
||||
ENOTDIR,
|
||||
ENOTEMPTY,
|
||||
ENOTSOCK,
|
||||
ENOTSUP, // 60
|
||||
ENOTTY,
|
||||
ENXIO,
|
||||
EOPNOTSUPP,
|
||||
EOVERFLOW,
|
||||
EPERM, // 65
|
||||
EPIPE,
|
||||
EPROTO,
|
||||
EPROTONOSUPPORT,
|
||||
EPROTOTYPE,
|
||||
ERANGE, // 70
|
||||
EROFS,
|
||||
ESPIPE,
|
||||
ESRCH,
|
||||
ESTALE,
|
||||
ETIME, // 75
|
||||
ETIMEDOUT,
|
||||
};
|
||||
|
||||
static s32 _net_convert_error(s32 sock_retval)//This is based on the function from libogc network_wii.c.
|
||||
{
|
||||
if (sock_retval >= 0) return sock_retval;
|
||||
if (sock_retval < -sizeof(_net_error_code_map)
|
||||
|| !_net_error_code_map[-sock_retval])
|
||||
return NET_UNKNOWN_ERROR_OFFSET + sock_retval;
|
||||
return -_net_error_code_map[-sock_retval];
|
||||
}
|
||||
|
||||
Result socu_cmd1(Handle memhandle, u32 memsize)
|
||||
{
|
||||
@ -24,7 +119,7 @@ Result socu_cmd1(Handle memhandle, u32 memsize)
|
||||
cmdbuf[4] = 0;
|
||||
cmdbuf[5] = memhandle;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
@ -36,14 +131,14 @@ Result SOC_Shutdown()
|
||||
|
||||
cmdbuf[0] = 0x00190000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
svc_closeHandle(socu_handle);
|
||||
svc_closeHandle(SOCU_handle);
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result SOC_Initialize(u32 *context_addr, u32 context_size)//Example context_size: 0x48000. The specified context buffer can no longer be accessed by the process which called this function, since the userland permissions for this block are set to no-access.
|
||||
Result SOC_Initialize(u32 *context_addr, u32 context_size)
|
||||
{
|
||||
Result ret=0;
|
||||
Handle memhandle = 0;
|
||||
@ -51,14 +146,14 @@ Result SOC_Initialize(u32 *context_addr, u32 context_size)//Example context_size
|
||||
ret = svc_createMemoryBlock(&memhandle, (u32)context_addr, context_size, 0, 3);
|
||||
if(ret!=0)return ret;
|
||||
|
||||
if((ret = srv_getServiceHandle(NULL, &socu_handle, "soc:U"))!=0)return ret;
|
||||
if((ret = srv_getServiceHandle(NULL, &SOCU_handle, "soc:U"))!=0)return ret;
|
||||
|
||||
return socu_cmd1(memhandle, context_size);
|
||||
}
|
||||
|
||||
int SOC_GetErrno()
|
||||
{
|
||||
return soc_errno;
|
||||
return SOCU_errno;
|
||||
}
|
||||
|
||||
int socket(int domain, int type, int protocol)
|
||||
@ -72,13 +167,13 @@ int socket(int domain, int type, int protocol)
|
||||
cmdbuf[3] = protocol;
|
||||
cmdbuf[4] = 0x20;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
soc_errno = ret;
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
return (int)cmdbuf[2];
|
||||
return _net_convert_error(cmdbuf[2]);
|
||||
}
|
||||
|
||||
int closesocket(int sockfd)
|
||||
@ -90,11 +185,11 @@ int closesocket(int sockfd)
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = 0x20;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
soc_errno = ret;
|
||||
if(ret==0)ret =_net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
return 0;
|
||||
@ -110,11 +205,11 @@ int shutdown(int sockfd, int shutdown_type)
|
||||
cmdbuf[2] = (u32)shutdown_type;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
soc_errno = ret;
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
return 0;
|
||||
@ -130,11 +225,11 @@ int listen(int sockfd, int max_connections)
|
||||
cmdbuf[2] = (u32)max_connections;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
soc_errno = ret;
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret!=0)return -1;
|
||||
return 0;
|
||||
@ -143,12 +238,12 @@ int listen(int sockfd, int max_connections)
|
||||
int accept(int sockfd, struct sockaddr *addr, int *addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
int tmp_addrlen=0x1c;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[8];
|
||||
int tmp_addrlen=8;
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
memset(tmpaddr, 0, 8);
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
cmdbuf[0] = 0x00040082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
@ -161,21 +256,20 @@ int accept(int sockfd, struct sockaddr *addr, int *addrlen)
|
||||
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = saved_threadstorage[0];
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret<0)soc_errno = ret;
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret>=0 && addr!=NULL)
|
||||
{
|
||||
*addrlen = tmpaddr[0];
|
||||
memset(addr, 0, sizeof(struct sockaddr));
|
||||
addr->sa_family = tmpaddr[1];
|
||||
memcpy(&addr->sa_data, &tmpaddr[2], tmp_addrlen-2);
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
@ -185,27 +279,43 @@ int accept(int sockfd, struct sockaddr *addr, int *addrlen)
|
||||
int bind(int sockfd, const struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
int tmp_addrlen=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[8];
|
||||
struct sockaddr_in *inaddr = (struct sockaddr_in*)addr;
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
addrlen = 8;
|
||||
tmpaddr[0] = 8;
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &addr->sa_data, addrlen-2);
|
||||
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
|
||||
|
||||
cmdbuf[0] = 0x00050084;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)addrlen;
|
||||
cmdbuf[2] = (u32)tmp_addrlen;
|
||||
cmdbuf[3] = 0x20;
|
||||
cmdbuf[5] = (((u32)addrlen)<<14) | 2;
|
||||
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
|
||||
cmdbuf[6] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
soc_errno = ret;
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return 0;
|
||||
@ -214,27 +324,43 @@ int bind(int sockfd, const struct sockaddr *addr, int addrlen)
|
||||
int connect(int sockfd, const struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
int tmp_addrlen=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[8];
|
||||
struct sockaddr_in *inaddr = (struct sockaddr_in*)addr;
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
addrlen = 8;
|
||||
tmpaddr[0] = 8;
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &addr->sa_data, addrlen-2);
|
||||
memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);
|
||||
|
||||
cmdbuf[0] = 0x00060084;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)addrlen;
|
||||
cmdbuf[3] = 0x20;
|
||||
cmdbuf[5] = (((u32)addrlen)<<14) | 2;
|
||||
cmdbuf[5] = (((u32)tmp_addrlen)<<14) | 2;
|
||||
cmdbuf[6] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
soc_errno = ret;
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return 0;
|
||||
@ -244,11 +370,13 @@ int socuipc_cmd7(int sockfd, void *buf, int len, int flags, struct sockaddr *src
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[8];
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
memset(tmpaddr, 0, 8);
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(src_addr)tmp_addrlen = 0x1c;
|
||||
|
||||
cmdbuf[0] = 0x00070104;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
@ -265,14 +393,21 @@ int socuipc_cmd7(int sockfd, void *buf, int len, int flags, struct sockaddr *src
|
||||
cmdbuf[0x100>>2] = (tmp_addrlen<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = saved_threadstorage[0];
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret<0)soc_errno = ret;
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret>0 && src_addr!=NULL)
|
||||
{
|
||||
src_addr->sa_family = tmpaddr[1];
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
@ -282,11 +417,13 @@ int socuipc_cmd8(int sockfd, void *buf, int len, int flags, struct sockaddr *src
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[8];
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[4];
|
||||
|
||||
memset(tmpaddr, 0, 8);
|
||||
if(src_addr)tmp_addrlen = 0x1c;
|
||||
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
cmdbuf[0] = 0x00080102;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
@ -305,7 +442,7 @@ int socuipc_cmd8(int sockfd, void *buf, int len, int flags, struct sockaddr *src
|
||||
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
|
||||
cmdbuf[0x10c>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = saved_threadstorage[0];
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
@ -313,21 +450,50 @@ int socuipc_cmd8(int sockfd, void *buf, int len, int flags, struct sockaddr *src
|
||||
cmdbuf[0x10c>>2] = saved_threadstorage[3];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret<0)soc_errno = ret;
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret>0 && src_addr!=NULL)
|
||||
{
|
||||
src_addr->sa_family = tmpaddr[1];
|
||||
if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
|
||||
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int socuipc_cmd9(int sockfd, const void *buf, int len, int flags, struct sockaddr *dest_addr, int addrlen)
|
||||
int socuipc_cmd9(int sockfd, const void *buf, int len, int flags, const struct sockaddr *dest_addr, int addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[8];
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 8);
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(dest_addr)
|
||||
{
|
||||
if(dest_addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = dest_addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
|
||||
}
|
||||
|
||||
cmdbuf[0] = 0x00090106;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
@ -340,24 +506,46 @@ int socuipc_cmd9(int sockfd, const void *buf, int len, int flags, struct sockadd
|
||||
cmdbuf[9] = (((u32)len)<<4) | 10;
|
||||
cmdbuf[10] = (u32)buf;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret<0)soc_errno = ret;
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int socuipc_cmda(int sockfd, const void *buf, int len, int flags, struct sockaddr *dest_addr, int addrlen)
|
||||
int socuipc_cmda(int sockfd, const void *buf, int len, int flags, const struct sockaddr *dest_addr, int addrlen)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u8 tmpaddr[8];
|
||||
int tmp_addrlen=0;
|
||||
u32 tmp_addrlen=0;
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
memset(tmpaddr, 0, 8);
|
||||
memset(tmpaddr, 0, 0x1c);
|
||||
|
||||
if(dest_addr)
|
||||
{
|
||||
if(dest_addr->sa_family == AF_INET)
|
||||
{
|
||||
tmp_addrlen = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_addrlen = 0x1c;
|
||||
}
|
||||
|
||||
if(addrlen < tmp_addrlen)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpaddr[0] = tmp_addrlen;
|
||||
tmpaddr[1] = dest_addr->sa_family;
|
||||
memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2);
|
||||
}
|
||||
|
||||
cmdbuf[0] = 0x000A0106;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
@ -370,25 +558,25 @@ int socuipc_cmda(int sockfd, const void *buf, int len, int flags, struct sockadd
|
||||
cmdbuf[9] = (tmp_addrlen<<14) | 0x402;
|
||||
cmdbuf[10] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(socu_handle))!=0)return ret;
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = (int)cmdbuf[2];
|
||||
if(ret<0)soc_errno = ret;
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int recvfrom(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr, int *addrlen)//UDP is not supported for these since the input/output sockaddr is not used.
|
||||
int recvfrom(int sockfd, void *buf, int len, int flags, struct sockaddr *src_addr, int *addrlen)
|
||||
{
|
||||
//if(len<0x2000)return socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen);
|
||||
if(len<0x2000)return socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen);
|
||||
return socuipc_cmd7(sockfd, buf, len, flags, src_addr, addrlen);
|
||||
}
|
||||
|
||||
int sendto(int sockfd, const void *buf, int len, int flags, const struct sockaddr *dest_addr, int addrlen)
|
||||
{
|
||||
//if(len<0x2000)return socuipc_cmda(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
if(len<0x2000)return socuipc_cmda(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
return socuipc_cmd9(sockfd, buf, len, flags, (struct sockaddr*)dest_addr, addrlen);
|
||||
}
|
||||
|
||||
@ -402,3 +590,217 @@ int send(int sockfd, const void *buf, int len, int flags)
|
||||
return sendto(sockfd, buf, len, flags, NULL, 0);
|
||||
}
|
||||
|
||||
int getsockopt(int sockfd, int level, int option_name, void * data, int * data_len)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
cmdbuf[0] = 0x00110102;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)level;
|
||||
cmdbuf[3] = (u32)option_name;
|
||||
cmdbuf[4] = (u32)*data_len;
|
||||
cmdbuf[5] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = ((*data_len)<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)data;
|
||||
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = saved_threadstorage[0];
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret==0)*data_len = cmdbuf[3];
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int setsockopt(int sockfd, int level, int option_name, const void * data, int data_len)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00120104;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)level;
|
||||
cmdbuf[3] = (u32)option_name;
|
||||
cmdbuf[4] = (u32)data_len;
|
||||
cmdbuf[5] = 0x20;
|
||||
cmdbuf[7] = (data_len<<14) | 0x2402;
|
||||
cmdbuf[8] = (u32)data;
|
||||
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fcntl(int sockfd, int cmd, ...)
|
||||
{
|
||||
int ret=0;
|
||||
int arg=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
va_list args;
|
||||
va_start(args, cmd);
|
||||
|
||||
if(cmd!=F_GETFL && cmd!=F_SETFL)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(cmd==F_SETFL)
|
||||
{
|
||||
arg = va_arg(args, int);
|
||||
|
||||
if(arg && arg!=O_NONBLOCK)
|
||||
{
|
||||
SOCU_errno = -EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(arg==O_NONBLOCK)arg = 0x4;
|
||||
}
|
||||
|
||||
cmdbuf[0] = 0x001300C2;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = (u32)cmd;
|
||||
cmdbuf[3] = (u32)arg;
|
||||
cmdbuf[4] = 0x20;
|
||||
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sockatmark(int sockfd)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00150042;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = 0x20;
|
||||
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
long gethostid()
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = 0x00160000;
|
||||
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int getsockname(int sockfd, struct sockaddr *addr, int * addr_len)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
cmdbuf[0] = 0x00170082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = 0x1c;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = saved_threadstorage[0];
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret==0)
|
||||
{
|
||||
addr->sa_family = tmpaddr[1];
|
||||
if(*addr_len > tmpaddr[0])*addr_len = tmpaddr[0];
|
||||
memset(addr, 0, sizeof(struct sockaddr));
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addr_len - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int getpeername(int sockfd, struct sockaddr *addr, int * addr_len)
|
||||
{
|
||||
int ret=0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
u8 tmpaddr[0x1c];
|
||||
|
||||
cmdbuf[0] = 0x00180082;
|
||||
cmdbuf[1] = (u32)sockfd;
|
||||
cmdbuf[2] = 0x1c;
|
||||
cmdbuf[3] = 0x20;
|
||||
|
||||
saved_threadstorage[0] = cmdbuf[0x100>>2];
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
|
||||
cmdbuf[0x100>>2] = (0x1c<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)tmpaddr;
|
||||
|
||||
if((ret = svc_sendSyncRequest(SOCU_handle))!=0)return ret;
|
||||
|
||||
cmdbuf[0x100>>2] = saved_threadstorage[0];
|
||||
cmdbuf[0x104>>2] = saved_threadstorage[1];
|
||||
|
||||
ret = (int)cmdbuf[1];
|
||||
if(ret==0)ret = _net_convert_error(cmdbuf[2]);
|
||||
if(ret<0)SOCU_errno = ret;
|
||||
|
||||
if(ret==0)
|
||||
{
|
||||
addr->sa_family = tmpaddr[1];
|
||||
if(*addr_len > tmpaddr[0])*addr_len = tmpaddr[0];
|
||||
memset(addr, 0, sizeof(struct sockaddr));
|
||||
memcpy(addr->sa_data, &tmpaddr[2], *addr_len - 2);
|
||||
}
|
||||
|
||||
if(ret<0)return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,12 @@ svc_createEvent:
|
||||
str r1, [r2]
|
||||
bx lr
|
||||
|
||||
.global svc_signalEvent
|
||||
.type svc_signalEvent, %function
|
||||
svc_signalEvent:
|
||||
svc 0x18
|
||||
bx lr
|
||||
|
||||
.global svc_clearEvent
|
||||
.type svc_clearEvent, %function
|
||||
svc_clearEvent:
|
||||
@ -128,6 +134,12 @@ svc_waitSynchronizationN:
|
||||
ldr r5, [sp], #4
|
||||
bx lr
|
||||
|
||||
.global svc_getSystemTick
|
||||
.type svc_getSystemTick, %function
|
||||
svc_getSystemTick:
|
||||
svc 0x28
|
||||
bx lr
|
||||
|
||||
.global svc_getSystemInfo
|
||||
.type svc_getSystemInfo, %function
|
||||
svc_getSystemInfo:
|
||||
@ -154,3 +166,12 @@ svc_connectToPort:
|
||||
svc_sendSyncRequest:
|
||||
svc 0x32
|
||||
bx lr
|
||||
|
||||
.global svc_getProcessId
|
||||
.type svc_getProcessId, %function
|
||||
svc_getProcessId:
|
||||
str r0, [sp,#-0x4]!
|
||||
svc 0x35
|
||||
ldr r3, [sp], #4
|
||||
str r1, [r3]
|
||||
bx lr
|
||||
|
@ -2,7 +2,7 @@ CC = arm-none-eabi-gcc
|
||||
LINK = arm-none-eabi-ld
|
||||
AS = arm-none-eabi-as
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
CTRULIB = "../libctru"
|
||||
CTRULIB = ../libctru
|
||||
CFLAGS += -Wall -std=c99 -march=armv6 -O3 -I"$(CTRULIB)/include" -I$(DEVKITPRO)/libnds/include
|
||||
LDFLAGS += --script=ccd00.ld -L"$(DEVKITARM)/arm-none-eabi/lib" -L"$(CTRULIB)/lib"
|
||||
|
||||
@ -28,7 +28,10 @@ endef
|
||||
|
||||
.PHONY:=all
|
||||
|
||||
all: $(PROJECTNAME).bin
|
||||
all: dir $(PROJECTNAME).bin
|
||||
|
||||
dir:
|
||||
@mkdir -p build
|
||||
|
||||
ctrulib:
|
||||
cd $(CTRULIB) && make
|
||||
|
@ -1,4 +1,4 @@
|
||||
.section ".text"
|
||||
.section ".init"
|
||||
.arm
|
||||
.align 4
|
||||
.global _init
|
||||
|
@ -137,20 +137,32 @@ int main()
|
||||
|
||||
aptSetupEventHandler();
|
||||
|
||||
while(!aptGetStatus())
|
||||
APP_STATUS status;
|
||||
while((status=aptGetStatus())!=APP_EXITING)
|
||||
{
|
||||
u32 PAD=hidSharedMem[7];
|
||||
renderEffect();
|
||||
swapBuffers();
|
||||
copyBuffer();
|
||||
u32 regData=PAD|0x01000000;
|
||||
GSPGPU_WriteHWRegs(NULL, 0x202A04, ®Data, 4);
|
||||
svc_sleepThread(1000000000);
|
||||
if(status==APP_RUNNING)
|
||||
{
|
||||
u32 PAD=hidSharedMem[7];
|
||||
renderEffect();
|
||||
swapBuffers();
|
||||
copyBuffer();
|
||||
u32 regData=PAD|0x01000000;
|
||||
GSPGPU_WriteHWRegs(NULL, 0x202A04, ®Data, 4);
|
||||
svc_sleepThread(1000000000);
|
||||
}
|
||||
else if(status == APP_SUSPENDING)
|
||||
{
|
||||
aptReturnToMenu();
|
||||
}
|
||||
else if(status == APP_SLEEPMODE)
|
||||
{
|
||||
aptWaitStatusEvent();
|
||||
}
|
||||
}
|
||||
|
||||
svc_closeHandle(fsuHandle);
|
||||
hidExit();
|
||||
gspGpuInit();
|
||||
gspGpuExit();
|
||||
aptExit();
|
||||
svc_exitProcess();
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user