├── .gitattributes ├── .gitignore ├── LICENSE.txt ├── Makefile ├── launcher ├── Makefile ├── icon.png └── source │ └── main.c ├── libctru ├── .gitignore ├── Doxyfile ├── Doxyfile.internal ├── Makefile ├── data │ └── default_font.bin ├── default_icon.png ├── include │ ├── 3ds.h │ ├── 3ds │ │ ├── allocator │ │ │ ├── linear.h │ │ │ ├── mappable.h │ │ │ └── vram.h │ │ ├── console.h │ │ ├── env.h │ │ ├── gfx.h │ │ ├── gpu │ │ │ ├── enums.h │ │ │ ├── gpu-old.h │ │ │ ├── gpu.h │ │ │ ├── gx.h │ │ │ ├── registers.h │ │ │ ├── shaderProgram.h │ │ │ └── shbin.h │ │ ├── ipc.h │ │ ├── linear.h │ │ ├── mappable.h │ │ ├── ndsp │ │ │ ├── channel.h │ │ │ └── ndsp.h │ │ ├── os.h │ │ ├── result.h │ │ ├── romfs.h │ │ ├── sdmc.h │ │ ├── services │ │ │ ├── ac.h │ │ │ ├── am.h │ │ │ ├── apt.h │ │ │ ├── cam.h │ │ │ ├── cfgnor.h │ │ │ ├── cfgu.h │ │ │ ├── csnd.h │ │ │ ├── dsp.h │ │ │ ├── fs.h │ │ │ ├── gspgpu.h │ │ │ ├── gsplcd.h │ │ │ ├── hb.h │ │ │ ├── hid.h │ │ │ ├── httpc.h │ │ │ ├── ir.h │ │ │ ├── irrst.h │ │ │ ├── mic.h │ │ │ ├── mvd.h │ │ │ ├── news.h │ │ │ ├── ns.h │ │ │ ├── pm.h │ │ │ ├── ps.h │ │ │ ├── ptm.h │ │ │ ├── ptmsysm.h │ │ │ ├── ptmu.h │ │ │ ├── qtm.h │ │ │ ├── soc.h │ │ │ ├── srvpm.h │ │ │ └── y2r.h │ │ ├── srv.h │ │ ├── svc.h │ │ ├── synchronization.h │ │ ├── types.h │ │ ├── util │ │ │ ├── rbtree.h │ │ │ └── utf.h │ │ └── vram.h │ ├── arpa │ │ └── inet.h │ ├── netdb.h │ ├── netinet │ │ ├── in.h │ │ └── tcp.h │ ├── poll.h │ └── sys │ │ ├── ioctl.h │ │ ├── select.h │ │ └── socket.h ├── lib │ └── libctru.a ├── libctru.cfg ├── libctru.cppcheck └── source │ ├── allocator │ ├── addrmap.h │ ├── linear.cpp │ ├── mappable.cpp │ ├── mem_pool.cpp │ ├── mem_pool.h │ └── vram.cpp │ ├── console.c │ ├── env.c │ ├── gfx.c │ ├── gpu │ ├── gpu-old.c │ ├── gpu.c │ ├── gpuResetSequence.c │ ├── gx.c │ ├── shaderProgram.c │ └── shbin.c │ ├── internal.h │ ├── ndsp │ ├── ndsp-channel.c │ ├── ndsp-internal.h │ └── ndsp.c │ ├── os-versionbin.c │ ├── os.c │ ├── romfs_dev.c │ ├── sdmc_dev.c │ ├── services │ ├── ac.c │ ├── am.c │ ├── apt.c │ ├── cam.c │ ├── cfgnor.c │ ├── cfgu.c │ ├── csnd.c │ ├── dsp.c │ ├── fs.c │ ├── gspgpu.c │ ├── gsplcd.c │ ├── gx.c │ ├── hb.c │ ├── hid.c │ ├── httpc.c │ ├── ir.c │ ├── irrst.c │ ├── mic.c │ ├── mvd.c │ ├── news.c │ ├── ns.c │ ├── pm.c │ ├── ps.c │ ├── ptm.c │ ├── ptmsysm.c │ ├── ptmu.c │ ├── qtm.c │ ├── soc │ │ ├── soc_accept.c │ │ ├── soc_bind.c │ │ ├── soc_closesocket.c │ │ ├── soc_common.c │ │ ├── soc_common.h │ │ ├── soc_connect.c │ │ ├── soc_fcntl.c │ │ ├── soc_gethostbyaddr.c │ │ ├── soc_gethostbyname.c │ │ ├── soc_gethostid.c │ │ ├── soc_getpeername.c │ │ ├── soc_getsockname.c │ │ ├── soc_getsockopt.c │ │ ├── soc_herror.c │ │ ├── soc_hstrerror.c │ │ ├── soc_inet_addr.c │ │ ├── soc_inet_aton.c │ │ ├── soc_inet_ntoa.c │ │ ├── soc_init.c │ │ ├── soc_ioctl.c │ │ ├── soc_listen.c │ │ ├── soc_poll.c │ │ ├── soc_recv.c │ │ ├── soc_recvfrom.c │ │ ├── soc_select.c │ │ ├── soc_send.c │ │ ├── soc_sendto.c │ │ ├── soc_setsockopt.c │ │ ├── soc_shutdown.c │ │ ├── soc_sockatmark.c │ │ └── soc_socket.c │ ├── srvpm.c │ └── y2r.c │ ├── srv.c │ ├── svc.s │ ├── synchronization.c │ ├── system │ ├── allocateHeaps.c │ ├── appExit.c │ ├── appInit.c │ ├── ctru_exit.c │ ├── initArgv.c │ ├── initSystem.c │ └── stack_adjust.s │ └── util │ ├── rbtree │ ├── rbtree_clear.c │ ├── rbtree_empty.c │ ├── rbtree_find.c │ ├── rbtree_init.c │ ├── rbtree_insert.c │ ├── rbtree_internal.h │ ├── rbtree_iterator.c │ ├── rbtree_minmax.c │ ├── rbtree_remove.c │ ├── rbtree_rotate.c │ └── rbtree_size.c │ └── utf │ ├── decode_utf16.c │ ├── decode_utf8.c │ ├── encode_utf16.c │ ├── encode_utf8.c │ ├── utf16_to_utf32.c │ ├── utf16_to_utf8.c │ ├── utf32_to_utf16.c │ ├── utf32_to_utf8.c │ ├── utf8_to_utf16.c │ └── utf8_to_utf32.c └── source ├── automap.c ├── ff_ctr.c ├── fmopl.c ├── id_ca.c ├── id_us.c ├── id_vh.c ├── include ├── audiosod.h ├── audiowl6.h ├── ff.h ├── fmopl.h ├── foreign.h ├── gfxv_sdm.h ├── gfxv_sod.h ├── gfxv_wl1.h ├── gfxv_wl6.h ├── gfxv_wl6_92.h ├── id_ca.h ├── id_heads.h ├── id_us.h ├── id_vh.h ├── misc.h ├── sd_comm.h ├── version.h ├── vi_comm.h ├── wl_act3.h ├── wl_def.h └── wl_menu.h ├── misc.c ├── objs.c ├── sd_comm.c ├── sd_ctr.c ├── sd_null.c ├── sys_ctr.c ├── vi_comm.c ├── wl_act1.c ├── wl_act2.c ├── wl_act3.c ├── wl_agent.c ├── wl_debug.c ├── wl_draw.c ├── wl_game.c ├── wl_inter.c ├── wl_main.c ├── wl_menu.c ├── wl_play.c ├── wl_state.c └── wl_text.c /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /launcher/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rinnegatamante/ctrWolfen/f243d125d66f6ffea08f9580728075d6c36a3144/launcher/icon.png -------------------------------------------------------------------------------- /libctru/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | docs 3 | internal_docs 4 | *.bz2 -------------------------------------------------------------------------------- /libctru/data/default_font.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rinnegatamante/ctrWolfen/f243d125d66f6ffea08f9580728075d6c36a3144/libctru/data/default_font.bin -------------------------------------------------------------------------------- /libctru/default_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rinnegatamante/ctrWolfen/f243d125d66f6ffea08f9580728075d6c36a3144/libctru/default_icon.png -------------------------------------------------------------------------------- /libctru/include/3ds/allocator/linear.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file linear.h 3 | * @brief Linear memory allocator. 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * @brief Allocates a 0x80-byte aligned buffer. 9 | * @param size Size of the buffer to allocate. 10 | * @return The allocated buffer. 11 | */ 12 | void* linearAlloc(size_t size); 13 | 14 | /** 15 | * @brief Allocates a buffer aligned to the given size. 16 | * @param size Size of the buffer to allocate. 17 | * @param alignment Alignment to use. 18 | * @return The allocated buffer. 19 | */ 20 | void* linearMemAlign(size_t size, size_t alignment); 21 | 22 | /** 23 | * @brief Reallocates a buffer. 24 | * Note: Not implemented yet. 25 | * @param mem Buffer to reallocate. 26 | * @param size Size of the buffer to allocate. 27 | * @return The reallocated buffer. 28 | */ 29 | void* linearRealloc(void* mem, size_t size); 30 | 31 | /** 32 | * @brief Frees a buffer. 33 | * @param mem Buffer to free. 34 | */ 35 | void linearFree(void* mem); 36 | 37 | /** 38 | * @brief Gets the current linear free space. 39 | * @return The current linear free space. 40 | */ 41 | u32 linearSpaceFree(void); 42 | -------------------------------------------------------------------------------- /libctru/include/3ds/allocator/mappable.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mappable.h 3 | * @brief Mappable memory allocator. 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * @brief Allocates a page-aligned buffer. 9 | * @param size Size of the buffer to allocate. 10 | * @return The allocated buffer. 11 | */ 12 | void* mappableAlloc(size_t size); 13 | 14 | /** 15 | * @brief Frees a buffer. 16 | * @param mem Buffer to free. 17 | */ 18 | void mappableFree(void* mem); 19 | 20 | /** 21 | * @brief Gets the current mappable free space. 22 | * @return The current mappable free space. 23 | */ 24 | u32 mappableSpaceFree(void); 25 | -------------------------------------------------------------------------------- /libctru/include/3ds/allocator/vram.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file vram.h 3 | * @brief VRAM allocator. 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * @brief Allocates a 0x80-byte aligned buffer. 9 | * @param size Size of the buffer to allocate. 10 | * @return The allocated buffer. 11 | */ 12 | void* vramAlloc(size_t size); 13 | 14 | /** 15 | * @brief Allocates a buffer aligned to the given size. 16 | * @param size Size of the buffer to allocate. 17 | * @param alignment Alignment to use. 18 | * @return The allocated buffer. 19 | */ 20 | void* vramMemAlign(size_t size, size_t alignment); 21 | 22 | /** 23 | * @brief Reallocates a buffer. 24 | * Note: Not implemented yet. 25 | * @param mem Buffer to reallocate. 26 | * @param size Size of the buffer to allocate. 27 | * @return The reallocated buffer. 28 | */ 29 | void* vramRealloc(void* mem, size_t size); 30 | 31 | /** 32 | * @brief Frees a buffer. 33 | * @param mem Buffer to free. 34 | */ 35 | void vramFree(void* mem); 36 | 37 | /** 38 | * @brief Gets the current VRAM free space. 39 | * @return The current VRAM free space. 40 | */ 41 | u32 vramSpaceFree(void); 42 | -------------------------------------------------------------------------------- /libctru/include/3ds/env.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file env.h 3 | * @brief Homebrew environment information. 4 | */ 5 | #pragma once 6 | 7 | /// System run-flags. 8 | enum { 9 | RUNFLAG_APTWORKAROUND = BIT(0), ///< Use APT workaround. 10 | RUNFLAG_APTREINIT = BIT(1), ///< Reinitialize APT. 11 | }; 12 | 13 | /** 14 | * @brief Gets whether the application was launched from a homebrew environment. 15 | * @return Whether the application was launched from a homebrew environment. 16 | */ 17 | static inline bool envIsHomebrew(void) { 18 | extern void* __service_ptr; 19 | return __service_ptr != NULL; 20 | } 21 | 22 | /** 23 | * @brief Retrieves a handle from the environment handle list. 24 | * @param name Name of the handle. 25 | * @return The retrieved handle. 26 | */ 27 | Handle envGetHandle(const char* name); 28 | 29 | /** 30 | * @brief Gets the environment-recommended app ID to use with APT. 31 | * @return The APT app ID. 32 | */ 33 | static inline u32 envGetAptAppId(void) { 34 | extern u32 __apt_appid; 35 | return __apt_appid; 36 | } 37 | 38 | /** 39 | * @brief Gets the environment-recommended heap size. 40 | * @return The heap size. 41 | */ 42 | static inline u32 envGetHeapSize(void) { 43 | extern u32 __heap_size; 44 | return __heap_size; 45 | } 46 | 47 | /** 48 | * @brief Gets the environment-recommended linear heap size. 49 | * @return The linear heap size. 50 | */ 51 | static inline u32 envGetLinearHeapSize(void) { 52 | extern u32 __linear_heap_size; 53 | return __linear_heap_size; 54 | } 55 | 56 | /** 57 | * @brief Gets the environment argument list. 58 | * @return The argument list. 59 | */ 60 | static inline const char* envGetSystemArgList(void) { 61 | extern const char* __system_arglist; 62 | return __system_arglist; 63 | } 64 | 65 | /** 66 | * @brief Gets the environment run flags. 67 | * @return The run flags. 68 | */ 69 | static inline u32 envGetSystemRunFlags(void) { 70 | extern u32 __system_runflags; 71 | return __system_runflags; 72 | } 73 | -------------------------------------------------------------------------------- /libctru/include/3ds/gpu/shbin.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file shbin.h 3 | * @brief Shader binary support. 4 | */ 5 | #pragma once 6 | 7 | #include <3ds/gpu/gpu.h> 8 | 9 | /// DVLE type. 10 | typedef enum{ 11 | VERTEX_SHDR=GPU_VERTEX_SHADER, ///< Vertex shader. 12 | GEOMETRY_SHDR=GPU_GEOMETRY_SHADER ///< Geometry shader. 13 | }DVLE_type; 14 | 15 | /// Constant type. 16 | typedef enum{ 17 | DVLE_CONST_BOOL=0x0, ///< Bool. 18 | DVLE_CONST_u8=0x1, ///< Unsigned 8-bit integer. 19 | DVLE_CONST_FLOAT24=0x2, ///< 24-bit float. 20 | }DVLE_constantType; 21 | 22 | /// Output attribute. 23 | typedef enum{ 24 | RESULT_POSITION = 0x0, ///< Position. 25 | RESULT_NORMALQUAT = 0x1, ///< Normal Quaternion. 26 | RESULT_COLOR = 0x2, ///< Color. 27 | RESULT_TEXCOORD0 = 0x3, ///< Texture coordinate 0. 28 | RESULT_TEXCOORD0W = 0x4, ///< Texture coordinate 0 W. 29 | RESULT_TEXCOORD1 = 0x5, ///< Texture coordinate 1. 30 | RESULT_TEXCOORD2 = 0x6, ///< Texture coordinate 2. 31 | RESULT_VIEW = 0x8 ///< View. 32 | }DVLE_outputAttribute_t; 33 | 34 | /// DVLP data. 35 | typedef struct{ 36 | u32 codeSize; ///< Code size. 37 | u32* codeData; ///< Code data. 38 | u32 opdescSize; ///< Operand description size. 39 | u32* opcdescData; ///< Operand description data. 40 | }DVLP_s; 41 | 42 | /// DVLE constant entry data. 43 | typedef struct{ 44 | u16 type; ///< Constant type. See @ref DVLE_constantType 45 | u16 id; ///< Constant ID. 46 | u32 data[4]; ///< Constant data. 47 | }DVLE_constEntry_s; 48 | 49 | /// DVLE output entry data. 50 | typedef struct{ 51 | u16 type; ///< Output type. See @ref DVLE_outputAttribute_t 52 | u16 regID; ///< Output register ID. 53 | u8 mask; ///< Output mask. 54 | u8 unk[3]; ///< Unknown. 55 | }DVLE_outEntry_s; 56 | 57 | /// DVLE uniform entry data. 58 | typedef struct{ 59 | u32 symbolOffset; ///< Symbol offset. 60 | u16 startReg; ///< Start register. 61 | u16 endReg; ///< End register. 62 | }DVLE_uniformEntry_s; 63 | 64 | /// DVLE data. 65 | typedef struct{ 66 | DVLE_type type; ///< DVLE type. 67 | DVLP_s* dvlp; ///< Contained DVLPs. 68 | u32 mainOffset; ///< Offset of the start of the main function. 69 | u32 endmainOffset; ///< Offset of the end of the main function. 70 | u32 constTableSize; ///< Constant table size. 71 | DVLE_constEntry_s* constTableData; ///< Constant table data. 72 | u32 outTableSize; ///< Output table size. 73 | DVLE_outEntry_s* outTableData; ///< Output table data. 74 | u32 uniformTableSize; ///< Uniform table size. 75 | DVLE_uniformEntry_s* uniformTableData; ///< Uniform table data. 76 | char* symbolTableData; ///< Symbol table data. 77 | u8 outmapMask; ///< Output map mask. 78 | u32 outmapData[8]; ///< Output map data. 79 | }DVLE_s; 80 | 81 | /// DVLB data. 82 | typedef struct{ 83 | u32 numDVLE; ///< DVLE count. 84 | DVLP_s DVLP; ///< Primary DVLP. 85 | DVLE_s* DVLE; ///< Contained DVLE. 86 | }DVLB_s; 87 | 88 | /** 89 | * @brief Parses a shader binary. 90 | * @param shbinData Shader binary data. 91 | * @param shbinSize Shader binary size. 92 | * @return The parsed shader binary. 93 | */ 94 | DVLB_s* DVLB_ParseFile(u32* shbinData, u32 shbinSize); 95 | 96 | /** 97 | * @brief Frees shader binary data. 98 | * @param dvlb DVLB to free. 99 | */ 100 | void DVLB_Free(DVLB_s* dvlb); 101 | 102 | /** 103 | * @brief Gets a uniform register index from a shader. 104 | * @param dvle Shader to get the register from. 105 | * @param name Name of the register. 106 | * @return The uniform register index. 107 | */ 108 | s8 DVLE_GetUniformRegister(DVLE_s* dvle, const char* name); 109 | 110 | /** 111 | * @brief Generates a shader output map. 112 | * @param dvle Shader to generate an output map for. 113 | */ 114 | void DVLE_GenerateOutmap(DVLE_s* dvle); 115 | -------------------------------------------------------------------------------- /libctru/include/3ds/linear.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file linear.h 3 | * @brief Linear memory allocator. 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * @brief Allocates a 0x80-byte aligned buffer. 9 | * @param size Size of the buffer to allocate. 10 | * @return The allocated buffer. 11 | */ 12 | void* linearAlloc(size_t size); 13 | 14 | /** 15 | * @brief Allocates a buffer aligned to the given size. 16 | * @param size Size of the buffer to allocate. 17 | * @param alignment Alignment to use. 18 | * @return The allocated buffer. 19 | */ 20 | void* linearMemAlign(size_t size, size_t alignment); 21 | 22 | /** 23 | * @brief Reallocates a buffer. 24 | * Note: Not implemented yet. 25 | * @param mem Buffer to reallocate. 26 | * @param size Size of the buffer to allocate. 27 | * @return The reallocated buffer. 28 | */ 29 | void* linearRealloc(void* mem, size_t size); 30 | 31 | /** 32 | * @brief Frees a buffer. 33 | * @param mem Buffer to free. 34 | */ 35 | void linearFree(void* mem); 36 | 37 | /** 38 | * @brief Gets the current linear free space. 39 | * @return The current linear free space. 40 | */ 41 | u32 linearSpaceFree(void); 42 | -------------------------------------------------------------------------------- /libctru/include/3ds/mappable.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mappable.h 3 | * @brief Mappable memory allocator. 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * @brief Allocates a page-aligned buffer. 9 | * @param size Size of the buffer to allocate. 10 | * @return The allocated buffer. 11 | */ 12 | void* mappableAlloc(size_t size); 13 | 14 | /** 15 | * @brief Frees a buffer. 16 | * @param mem Buffer to free. 17 | */ 18 | void mappableFree(void* mem); 19 | 20 | /** 21 | * @brief Gets the current mappable free space. 22 | * @return The current mappable free space. 23 | */ 24 | u32 mappableSpaceFree(void); 25 | -------------------------------------------------------------------------------- /libctru/include/3ds/result.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file result.h 3 | * @brief 3DS result code tools 4 | */ 5 | #pragma once 6 | #include "types.h" 7 | 8 | /// Checks whether a result code indicates success. 9 | #define R_SUCCEEDED(res) ((res)>=0) 10 | /// Checks whether a result code indicates failure. 11 | #define R_FAILED(res) ((res)<0) 12 | /// Returns the level of a result code. 13 | #define R_LEVEL(res) (((res)>>27)&0x1F) 14 | /// Returns the summary of a result code. 15 | #define R_SUMMARY(res) (((res)>>21)&0x3F) 16 | /// Returns the module ID of a result code. 17 | #define R_MODULE(res) (((res)>>10)&0xFF) 18 | /// Returns the description of a result code. 19 | #define R_DESCRIPTION(res) ((res)&0x3FF) 20 | 21 | /// Builds a result code from its constituent components. 22 | #define MAKERESULT(level,summary,module,description) \ 23 | ((((level)&0x1F)<<27) | (((summary)&0x3F)<<21) | (((module)&0xFF)<<10) | ((description)&0x3FF)) 24 | 25 | /// Result code level values. 26 | enum 27 | { 28 | // >= 0 29 | RL_SUCCESS = 0, 30 | RL_INFO = 1, 31 | 32 | // < 0 33 | RL_FATAL = 0x1F, 34 | RL_RESET = RL_FATAL - 1, 35 | RL_REINITIALIZE = RL_FATAL - 2, 36 | RL_USAGE = RL_FATAL - 3, 37 | RL_PERMANENT = RL_FATAL - 4, 38 | RL_TEMPORARY = RL_FATAL - 5, 39 | RL_STATUS = RL_FATAL - 6, 40 | }; 41 | 42 | /// Result code summary values. 43 | enum 44 | { 45 | RS_SUCCESS = 0, 46 | RS_NOP = 1, 47 | RS_WOULDBLOCK = 2, 48 | RS_OUTOFRESOURCE = 3, 49 | RS_NOTFOUND = 4, 50 | RS_INVALIDSTATE = 5, 51 | RS_NOTSUPPORTED = 6, 52 | RS_INVALIDARG = 7, 53 | RS_WRONGARG = 8, 54 | RS_CANCELED = 9, 55 | RS_STATUSCHANGED = 10, 56 | RS_INTERNAL = 11, 57 | RS_INVALIDRESVAL = 63, 58 | }; 59 | 60 | /// Result code generic description values. 61 | enum 62 | { 63 | RD_SUCCESS = 0, 64 | RD_INVALID_RESULT_VALUE = 0x3FF, 65 | RD_TIMEOUT = RD_INVALID_RESULT_VALUE - 1, 66 | RD_OUT_OF_RANGE = RD_INVALID_RESULT_VALUE - 2, 67 | RD_ALREADY_EXISTS = RD_INVALID_RESULT_VALUE - 3, 68 | RD_CANCEL_REQUESTED = RD_INVALID_RESULT_VALUE - 4, 69 | RD_NOT_FOUND = RD_INVALID_RESULT_VALUE - 5, 70 | RD_ALREADY_INITIALIZED = RD_INVALID_RESULT_VALUE - 6, 71 | RD_NOT_INITIALIZED = RD_INVALID_RESULT_VALUE - 7, 72 | RD_INVALID_HANDLE = RD_INVALID_RESULT_VALUE - 8, 73 | RD_INVALID_POINTER = RD_INVALID_RESULT_VALUE - 9, 74 | RD_INVALID_ADDRESS = RD_INVALID_RESULT_VALUE - 10, 75 | RD_NOT_IMPLEMENTED = RD_INVALID_RESULT_VALUE - 11, 76 | RD_OUT_OF_MEMORY = RD_INVALID_RESULT_VALUE - 12, 77 | RD_MISALIGNED_SIZE = RD_INVALID_RESULT_VALUE - 13, 78 | RD_MISALIGNED_ADDRESS = RD_INVALID_RESULT_VALUE - 14, 79 | RD_BUSY = RD_INVALID_RESULT_VALUE - 15, 80 | RD_NO_DATA = RD_INVALID_RESULT_VALUE - 16, 81 | RD_INVALID_COMBINATION = RD_INVALID_RESULT_VALUE - 17, 82 | RD_INVALID_ENUM_VALUE = RD_INVALID_RESULT_VALUE - 18, 83 | RD_INVALID_SIZE = RD_INVALID_RESULT_VALUE - 19, 84 | RD_ALREADY_DONE = RD_INVALID_RESULT_VALUE - 20, 85 | RD_NOT_AUTHORIZED = RD_INVALID_RESULT_VALUE - 21, 86 | RD_TOO_LARGE = RD_INVALID_RESULT_VALUE - 22, 87 | RD_INVALID_SELECTION = RD_INVALID_RESULT_VALUE - 23, 88 | }; 89 | -------------------------------------------------------------------------------- /libctru/include/3ds/romfs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file romfs.h 3 | * @brief RomFS driver. 4 | */ 5 | #pragma once 6 | 7 | #include <3ds/types.h> 8 | 9 | /// RomFS header. 10 | typedef struct 11 | { 12 | u32 headerSize; ///< Size of the header. 13 | u32 dirHashTableOff; ///< Offset of the directory hash table. 14 | u32 dirHashTableSize; ///< Size of the directory hash table. 15 | u32 dirTableOff; ///< Offset of the directory table. 16 | u32 dirTableSize; ///< Size of the directory table. 17 | u32 fileHashTableOff; ///< Offset of the file hash table. 18 | u32 fileHashTableSize; ///< Size of the file hash table. 19 | u32 fileTableOff; ///< Offset of the file table. 20 | u32 fileTableSize; ///< Size of the file table. 21 | u32 fileDataOff; ///< Offset of the file data. 22 | } romfs_header; 23 | 24 | /// RomFS directory. 25 | typedef struct 26 | { 27 | u32 parent; ///< Offset of the parent directory. 28 | u32 sibling; ///< Offset of the next sibling directory. 29 | u32 childDir; ///< Offset of the first child directory. 30 | u32 childFile; ///< Offset of the first file. 31 | u32 nextHash; ///< Directory hash table pointer. 32 | u32 nameLen; ///< Name length. 33 | u16 name[]; ///< Name. (UTF-16) 34 | } romfs_dir; 35 | 36 | /// RomFS file. 37 | typedef struct 38 | { 39 | u32 parent; ///< Offset of the parent directory. 40 | u32 sibling; ///< Offset of the next sibling file. 41 | u64 dataOff; ///< Offset of the file's data. 42 | u64 dataSize; ///< Length of the file's data. 43 | u32 nextHash; ///< File hash table pointer. 44 | u32 nameLen; ///< Name length. 45 | u16 name[]; ///< Name. (UTF-16) 46 | } romfs_file; 47 | 48 | /// Initializes the RomFS driver. 49 | Result romfsInit(void); 50 | 51 | /** 52 | * @brief Initializes the RomFS driver from a RomFS file. 53 | * @param file Handle of the RomFS file. 54 | * @param offset Offset of the RomFS within the file. 55 | */ 56 | Result romfsInitFromFile(Handle file, u32 offset); 57 | 58 | /// Exits the RomFS driver. 59 | Result romfsExit(void); 60 | -------------------------------------------------------------------------------- /libctru/include/3ds/sdmc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file sdmc.h 3 | * @brief SDMC driver. 4 | */ 5 | #pragma once 6 | 7 | #include <3ds/types.h> 8 | 9 | /// Initializes the SDMC driver. 10 | Result sdmcInit(void); 11 | 12 | /// Exits the SDMC driver. 13 | Result sdmcExit(void); 14 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/ac.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ac.h 3 | * @brief AC service. 4 | */ 5 | #pragma once 6 | 7 | /// Initializes AC. 8 | Result acInit(void); 9 | 10 | /// Exits AC. 11 | void acExit(void); 12 | 13 | /// Waits for the system to connect to the internet. 14 | Result acWaitInternetConnection(void); 15 | 16 | /** 17 | * @brief Gets the current Wifi status. 18 | * @param out Pointer to output the current Wifi status to. (0 = not connected, 1 = O3DS Internet, 2 = N3DS Internet) 19 | */ 20 | Result ACU_GetWifiStatus(u32 *out); 21 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/cfgnor.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cfgnor.h 3 | * @brief CFGNOR service. 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * @brief Initializes CFGNOR. 9 | * @param value Unknown, usually 1. 10 | */ 11 | Result cfgnorInit(u8 value); 12 | 13 | /// Exits CFGNOR 14 | void cfgnorExit(void); 15 | 16 | /** 17 | * @brief Dumps the NOR flash. 18 | * @param buf Buffer to dump to. 19 | * @param size Size of the buffer. 20 | */ 21 | Result cfgnorDumpFlash(u32 *buf, u32 size); 22 | 23 | /** 24 | * @brief Writes the NOR flash. 25 | * @param buf Buffer to write from. 26 | * @param size Size of the buffer. 27 | */ 28 | Result cfgnorWriteFlash(u32 *buf, u32 size); 29 | 30 | /** 31 | * @brief Initializes the CFGNOR session. 32 | * @param value Unknown, usually 1. 33 | */ 34 | Result CFGNOR_Initialize(u8 value); 35 | 36 | /// Shuts down the CFGNOR session. 37 | Result CFGNOR_Shutdown(void); 38 | 39 | /** 40 | * @brief Reads data from NOR. 41 | * @param offset Offset to read from. 42 | * @param buf Buffer to read data to. 43 | * @param size Size of the buffer. 44 | */ 45 | Result CFGNOR_ReadData(u32 offset, u32 *buf, u32 size); 46 | 47 | /** 48 | * @brief Writes data to NOR. 49 | * @param offset Offset to write to. 50 | * @param buf Buffer to write data from. 51 | * @param size Size of the buffer. 52 | */ 53 | Result CFGNOR_WriteData(u32 offset, u32 *buf, u32 size); 54 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/cfgu.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cfgu.h 3 | * @brief CFGU (Configuration) Service 4 | */ 5 | #pragma once 6 | 7 | /// Configuration region values. 8 | typedef enum 9 | { 10 | CFG_REGION_JPN = 0, ///< Japan 11 | CFG_REGION_USA = 1, ///< USA 12 | CFG_REGION_EUR = 2, ///< Europe 13 | CFG_REGION_AUS = 3, ///< Australia 14 | CFG_REGION_CHN = 4, ///< China 15 | CFG_REGION_KOR = 5, ///< Korea 16 | CFG_REGION_TWN = 6, ///< Taiwan 17 | } CFG_Region; 18 | 19 | /// Configuration language values. 20 | typedef enum 21 | { 22 | CFG_LANGUAGE_JP = 0, ///< Japanese 23 | CFG_LANGUAGE_EN = 1, ///< English 24 | CFG_LANGUAGE_FR = 2, ///< French 25 | CFG_LANGUAGE_DE = 3, ///< German 26 | CFG_LANGUAGE_IT = 4, ///< Italian 27 | CFG_LANGUAGE_ES = 5, ///< Spanish 28 | CFG_LANGUAGE_ZH = 6, ///< Simplified Chinese 29 | CFG_LANGUAGE_KO = 7, ///< Korean 30 | CFG_LANGUAGE_NL = 8, ///< Dutch 31 | CFG_LANGUAGE_PT = 9, ///< Portugese 32 | CFG_LANGUAGE_RU = 10, ///< Russian 33 | CFG_LANGUAGE_TW = 11, ///< Traditional Chinese 34 | } CFG_Language; 35 | 36 | /// Initializes CFGU. 37 | Result cfguInit(void); 38 | 39 | /// Exits CFGU. 40 | void cfguExit(void); 41 | 42 | /** 43 | * @brief Gets the system's region from secure info. 44 | * @param region Pointer to output the region to. (see @ref CFG_Region) 45 | */ 46 | Result CFGU_SecureInfoGetRegion(u8* region); 47 | 48 | /** 49 | * @brief Generates a console-unique hash. 50 | * @param appIDSalt Salt to use. 51 | * @param hash Pointer to output the hash to. 52 | */ 53 | Result CFGU_GenHashConsoleUnique(u32 appIDSalt, u64* hash); 54 | 55 | /** 56 | * @brief Gets whether the system's region is Canada or USA. 57 | * @param value Pointer to output the result to. (0 = no, 1 = yes) 58 | */ 59 | Result CFGU_GetRegionCanadaUSA(u8* value); 60 | 61 | /** 62 | * @brief Gets the system's model. 63 | * @param model Pointer to output the model to. (0 = O3DS, 1 = O3DSXL, 2 = N3DS, 3 = 2DS, 4 = N3DSXL) 64 | */ 65 | Result CFGU_GetSystemModel(u8* model); 66 | 67 | /** 68 | * @brief Gets whether the system is a 2DS. 69 | * @param value Pointer to output the result to. (0 = yes, 1 = no) 70 | */ 71 | Result CFGU_GetModelNintendo2DS(u8* value); 72 | 73 | /** 74 | * @brief Gets a string representing a country code. 75 | * @param code Country code to use. 76 | * @param string Pointer to output the string to. 77 | */ 78 | Result CFGU_GetCountryCodeString(u16 code, u16* string); 79 | 80 | /** 81 | * @brief Gets a country code ID from its string. 82 | * @param string String to use. 83 | * @param code Pointer to output the country code to. 84 | */ 85 | Result CFGU_GetCountryCodeID(u16 string, u16* code); 86 | 87 | /** 88 | * @brief Gets a config info block. 89 | * @param size Size of the data to retrieve. 90 | * @param blkID ID of the block to retrieve. 91 | * @param outData Pointer to write the block data to. 92 | */ 93 | Result CFGU_GetConfigInfoBlk2(u32 size, u32 blkID, u8* outData); 94 | 95 | /** 96 | * @brief Gets the system's language. 97 | * @param language Pointer to write the language to. (see @ref CFG_Language) 98 | */ 99 | Result CFGU_GetSystemLanguage(u8* language); 100 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/gsplcd.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file gsplcd.h 3 | * @brief GSPLCD service. 4 | */ 5 | #pragma once 6 | #include <3ds/gfx.h> // For gfxScreen_t 7 | 8 | /// LCD screens. 9 | enum 10 | { 11 | GSPLCD_SCREEN_TOP = BIT(GFX_TOP), ///< Top screen. 12 | GSPLCD_SCREEN_BOTTOM = BIT(GFX_BOTTOM), ///< Bottom screen. 13 | GSPLCD_SCREEN_BOTH = GSPLCD_SCREEN_TOP | GSPLCD_SCREEN_BOTTOM, ///< Both screens. 14 | }; 15 | 16 | /// Initializes GSPLCD. 17 | Result gspLcdInit(void); 18 | 19 | /// Exits GSPLCD. 20 | void gspLcdExit(void); 21 | 22 | /** 23 | * @brief Powers on the backlight. 24 | * @param screen Screen to power on. 25 | */ 26 | Result GSPLCD_PowerOnBacklight(u32 screen); 27 | 28 | /** 29 | * @brief Powers off the backlight. 30 | * @param screen Screen to power off. 31 | */ 32 | Result GSPLCD_PowerOffBacklight(u32 screen); 33 | 34 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/hb.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file hb.h 3 | * @brief HB (Homebrew) service. 4 | */ 5 | #pragma once 6 | 7 | // WARNING ! THIS FILE PROVIDES AN INTERFACE TO A NON-OFFICIAL SERVICE PROVIDED BY NINJHAX 8 | // BY USING COMMANDS FROM THIS SERVICE YOU WILL LIKELY MAKE YOUR APPLICATION INCOMPATIBLE WITH OTHER HOMEBREW LAUNCHING METHODS 9 | // A GOOD WAY TO COPE WITH THIS IS TO CHECK THE OUTPUT OF hbInit FOR ERRORS 10 | 11 | #include <3ds/types.h> 12 | 13 | /// Initializes HB. 14 | Result hbInit(void); 15 | 16 | /// Exits HB. 17 | void hbExit(void); 18 | 19 | /// Flushes/invalidates the entire data/instruction cache. 20 | Result HB_FlushInvalidateCache(void); 21 | 22 | /** 23 | * @brief Fetches the address for Ninjhax 1.x bootloader addresses. 24 | * @param load3dsx void (*callBootloader)(Handle hb, Handle file); 25 | * @param setArgv void (*setArgs)(u32* src, u32 length); 26 | */ 27 | Result HB_GetBootloaderAddresses(void** load3dsx, void** setArgv); 28 | 29 | /** 30 | * @brief Changes the permissions of a given number of pages at address addr to mode. 31 | * Should it fail, the appropriate kernel error code will be returned and *reprotectedPages (if not NULL) 32 | * will be set to the number of sequential pages which were successfully reprotected + 1 33 | * @param addr Address to reprotect. 34 | * @param pages Number of pages to reprotect. 35 | * @param mode Mode to reprotect to. 36 | * @param reprotectedPages Number of successfully reprotected pages, on failure. 37 | */ 38 | Result HB_ReprotectMemory(u32* addr, u32 pages, u32 mode, u32* reprotectedPages); 39 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/ir.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ir.h 3 | * @brief IR service. 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * @brief Initializes IRU. 9 | * The permissions for the specified memory is set to RO. This memory must be already mapped. 10 | * @param sharedmem_addr Address of the shared memory block to use. 11 | * @param sharedmem_size Size of the shared memory block. 12 | */ 13 | Result iruInit(u32 *sharedmem_addr, u32 sharedmem_size); 14 | 15 | /// Shuts down IRU. 16 | void iruExit(void); 17 | 18 | /** 19 | * @brief Gets the IRU service handle. 20 | * @return The IRU service handle. 21 | */ 22 | Handle iruGetServHandle(void); 23 | 24 | /** 25 | * @brief Sends IR data. 26 | * @param buf Buffer to send data from. 27 | * @param size Size of the buffer. 28 | * @param wait Whether to wait for the data to be sent. 29 | */ 30 | Result iruSendData(u8 *buf, u32 size, bool wait); 31 | 32 | /** 33 | * @brief Receives IR data. 34 | * @param buf Buffer to receive data to. 35 | * @param size Size of the buffer. 36 | * @param flag Flags to receive data with. 37 | * @param transfercount Pointer to output the number of bytes read to. 38 | * @param wait Whether to wait for the data to be received. 39 | */ 40 | Result iruRecvData(u8 *buf, u32 size, u8 flag, u32 *transfercount, bool wait); 41 | 42 | /// Initializes the IR session. 43 | Result IRU_Initialize(void); 44 | 45 | /// Shuts down the IR session. 46 | Result IRU_Shutdown(void); 47 | 48 | /** 49 | * @brief Begins sending data. 50 | * @param buf Buffer to send. 51 | * @param size Size of the buffer. 52 | */ 53 | Result IRU_StartSendTransfer(u8 *buf, u32 size); 54 | 55 | /// Waits for a send operation to complete. 56 | Result IRU_WaitSendTransfer(void); 57 | 58 | /** 59 | * @brief Begins receiving data. 60 | * @param size Size of the data to receive. 61 | * @param flag Flags to use when receiving. 62 | */ 63 | Result IRU_StartRecvTransfer(u32 size, u8 flag); 64 | 65 | /** 66 | * @brief Waits for a receive operation to complete. 67 | * @param transfercount Pointer to output the number of bytes read to. 68 | */ 69 | Result IRU_WaitRecvTransfer(u32 *transfercount); 70 | 71 | /** 72 | * @brief Sets the IR bit rate. 73 | * @param value Bit rate to set. 74 | */ 75 | Result IRU_SetBitRate(u8 value); 76 | 77 | /** 78 | * @brief Gets the IR bit rate. 79 | * @param out Pointer to write the bit rate to. 80 | */ 81 | Result IRU_GetBitRate(u8 *out); 82 | 83 | /** 84 | * @brief Sets the IR LED state. 85 | * @param value IR LED state to set. 86 | */ 87 | Result IRU_SetIRLEDState(u32 value); 88 | 89 | /** 90 | * @brief Gets the IR KED state. 91 | * @param out Pointer to write the IR LED state to. 92 | */ 93 | Result IRU_GetIRLEDRecvState(u32 *out); 94 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/irrst.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file irrst.h 3 | * @brief IRRST service. 4 | */ 5 | #pragma once 6 | 7 | //See also: http://3dbrew.org/wiki/IR_Services http://3dbrew.org/wiki/IRRST_Shared_Memory 8 | 9 | #include "3ds/services/hid.h" // for circlePosition definition 10 | 11 | /// IRRST's shared memory handle. 12 | extern Handle irrstMemHandle; 13 | 14 | /// IRRST's shared memory. 15 | extern vu32* irrstSharedMem; 16 | 17 | /// Initializes IRRST. 18 | Result irrstInit(void); 19 | 20 | /// Exits IRRST. 21 | void irrstExit(void); 22 | 23 | /// Scans IRRST for input. 24 | void irrstScanInput(void); 25 | 26 | /** 27 | * @brief Gets IRRST's held keys. 28 | * @return IRRST's held keys. 29 | */ 30 | u32 irrstKeysHeld(void); 31 | 32 | /** 33 | * @brief Reads the current c-stick position. 34 | * @param pos Pointer to output the current c-stick position to. 35 | */ 36 | void irrstCstickRead(circlePosition* pos); 37 | 38 | /** 39 | * @brief Waits for the IRRST input event to trigger. 40 | * @param nextEvent Whether to discard the current event and wait until the next event. 41 | */ 42 | void irrstWaitForEvent(bool nextEvent); 43 | 44 | /// Macro for irrstCstickRead. 45 | #define hidCstickRead irrstCstickRead 46 | 47 | /** 48 | * @brief Gets the shared memory and event handles for IRRST. 49 | * @param outMemHandle Pointer to write the shared memory handle to. 50 | * @param outEventHandle Pointer to write the event handle to. 51 | */ 52 | Result IRRST_GetHandles(Handle* outMemHandle, Handle* outEventHandle); 53 | 54 | /** 55 | * @brief Initializes IRRST. 56 | * @param unk1 Unknown. 57 | * @param unk2 Unknown. 58 | */ 59 | Result IRRST_Initialize(u32 unk1, u8 unk2); 60 | 61 | /// Shuts down IRRST. 62 | Result IRRST_Shutdown(void); 63 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/mvd.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mvd.h 3 | * @brief MVD service. 4 | */ 5 | #pragma once 6 | 7 | //New3DS-only, see also: http://3dbrew.org/wiki/MVD_Services 8 | 9 | /// Processing mode. 10 | typedef enum { 11 | MVDMODE_COLORFORMATCONV, ///< Converting color formats. 12 | MVDMODE_VIDEOPROCESSING ///< Processing video. 13 | } MVDSTD_Mode; 14 | 15 | /// Input format. 16 | typedef enum { 17 | MVD_INPUT_YUYV422 = 0x00010001, ///< YUYV422 18 | MVD_INPUT_H264 = 0x00020001 ///< H264 19 | } MVDSTD_InputFormat; 20 | 21 | /// Output format. 22 | typedef enum { 23 | MVD_OUTPUT_RGB565 = 0x00040002 ///< RGB565 24 | } MVDSTD_OutputFormat; 25 | 26 | /// Processing configuration. 27 | typedef struct { 28 | MVDSTD_InputFormat input_type; ///< Input type. 29 | u32 unk_x04; ///< Unknown. 30 | u32 unk_x08; ///< Unknown. 31 | u32 inwidth; ///< Input width. 32 | u32 inheight; ///< Input height. 33 | u32 physaddr_colorconv_indata; ///< Physical address of color conversion input data. 34 | u32 unk_x18[0x28>>2]; ///< Unknown. 35 | u32 flag_x40; ///< Unknown. 0x0 for colorconv, 0x1 for H.264 36 | u32 unk_x44; ///< Unknown. 37 | u32 unk_x48; ///< Unknown. 38 | u32 outheight0; ///< First output width. Only set for H.264. 39 | u32 outwidth0; ///< First output height. Only set for H.264. 40 | u32 unk_x54; ///< Unknown. 41 | MVDSTD_OutputFormat output_type; ///< Output type. 42 | u32 outwidth1; ///< Second output width. 43 | u32 outheight1; ///< Second output height. 44 | u32 physaddr_outdata0; ///< Physical address of output data. 45 | u32 physaddr_outdata1_colorconv; ///< Physical address of color conversion output data. 46 | u32 unk_x6c[0xb0>>2]; ///< Unknown. 47 | } MVDSTD_Config; 48 | 49 | /** 50 | * @brief Initializes MVDSTD. Video processing / H.264 currently isn't supported. 51 | * @param mode Mode to initialize MVDSTD to. 52 | * @param input_type Type of input to process. 53 | * @param output_type Type of output to produce. 54 | * @param size Size of data to process. Not used when type == MVDTYPE_COLORFORMATCONV. 55 | */ 56 | Result mvdstdInit(MVDSTD_Mode mode, MVDSTD_InputFormat input_type, MVDSTD_OutputFormat output_type, u32 size); 57 | 58 | /// Shuts down MVDSTD. 59 | void mvdstdExit(void); 60 | 61 | /** 62 | * @brief Generates a default MVDSTD configuration. 63 | * @param config Pointer to output the generated config to. 64 | * @param input_width Input width. 65 | * @param input_height Input height. 66 | * @param output_width Output width. 67 | * @param output_height Output height. 68 | * @param vaddr_colorconv_indata Virtual address of the color conversion input data. 69 | * @param vaddr_outdata0 Virtual address of the output data. 70 | * @param vaddr_outdata1_colorconv Virtual address of the color conversion output data. 71 | */ 72 | void mvdstdGenerateDefaultConfig(MVDSTD_Config*config, u32 input_width, u32 input_height, u32 output_width, u32 output_height, u32 *vaddr_colorconv_indata, u32 *vaddr_outdata0, u32 *vaddr_outdata1_colorconv); 73 | 74 | /** 75 | * @brief Processes a frame. 76 | * @param config Pointer to the configuration to use. 77 | * @param h264_vaddr_inframe Input H264 frame. 78 | * @param h264_inframesize Size of the input frame. 79 | * @param h264_frameid ID of the input frame. 80 | */ 81 | Result mvdstdProcessFrame(MVDSTD_Config*config, u32 *h264_vaddr_inframe, u32 h264_inframesize, u32 h264_frameid); 82 | 83 | /** 84 | * @brief Sets the current configuration of MVDSTD. 85 | * @param config Pointer to the configuration to set. 86 | */ 87 | Result MVDSTD_SetConfig(MVDSTD_Config* config); 88 | 89 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/news.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file news.h 3 | * @brief NEWS (Notification) service. 4 | */ 5 | #pragma once 6 | 7 | /// Initializes NEWS. 8 | Result newsInit(void); 9 | 10 | /// Exits NEWS. 11 | void newsExit(void); 12 | 13 | /** 14 | * @brief Adds a notification to the home menu Notifications applet. 15 | * @param title UTF-16 title of the notification. 16 | * @param titleLength Number of characters in the title, not including the null-terminator. 17 | * @param message UTF-16 message of the notification, or NULL for no message. 18 | * @param messageLength Number of characters in the message, not including the null-terminator. 19 | * @param image Data of the image to show in the notification, or NULL for no image. 20 | * @param imageSize Size of the image data in bytes. 21 | * @param jpeg Whether the image is a JPEG or not. 22 | */ 23 | Result NEWS_AddNotification(const u16* title, u32 titleLength, const u16* message, u32 messageLength, const void* imageData, u32 imageSize, bool jpeg); 24 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/ns.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ns.h 3 | * @brief NS (Nintendo Shell) service. 4 | */ 5 | #pragma once 6 | 7 | /// Initializes NS. 8 | Result nsInit(void); 9 | 10 | /// Exits NS. 11 | void nsExit(void); 12 | 13 | /** 14 | * @brief Launches a title. 15 | * @param titleid ID of the title to launch, or 0 for gamecard. 16 | * @param launch_flags Flags used when launching the title. 17 | * @param procid Pointer to write the process ID of the launched title to. 18 | */ 19 | Result NS_LaunchTitle(u64 titleid, u32 launch_flags, u32 *procid); 20 | 21 | /** 22 | * @brief Reboots to a title. 23 | * @param mediatype Mediatype of the title. 24 | * @param titleid ID of the title to launch. 25 | */ 26 | Result NS_RebootToTitle(u8 mediatype, u64 titleid); 27 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/pm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file pm.h 3 | * @brief PM (Process Manager) service. 4 | */ 5 | #pragma once 6 | 7 | /// Initializes PM. 8 | Result pmInit(void); 9 | 10 | /// Exits PM. 11 | void pmExit(void); 12 | 13 | /** 14 | * @brief Launches a title. 15 | * @param mediatype Mediatype of the title. 16 | * @param titleid ID of the title. 17 | * @param launch_flags Flags to launch the title with. 18 | */ 19 | Result PM_LaunchTitle(u8 mediatype, u64 titleid, u32 launch_flags); 20 | 21 | /** 22 | * @brief Gets launch flags from a title's exheader. 23 | * @param mediatype Mediatype of the title. 24 | * @param titleid ID of the title. 25 | * @param out Pointer to write the launch flags to. 26 | */ 27 | Result PM_GetTitleExheaderFlags(u8 mediatype, u64 titleid, u8* out); 28 | 29 | /** 30 | * @brief Sets the current FIRM launch parameters. 31 | * @param size Size of the FIRM launch parameter buffer. 32 | * @param in Buffer to retrieve the launch parameters from. 33 | */ 34 | Result PM_SetFIRMLaunchParams(u32 size, u8* in); 35 | 36 | /** 37 | * @brief Gets the current FIRM launch parameters. 38 | * @param size Size of the FIRM launch parameter buffer. 39 | * @param out Buffer to write the launch parameters to. 40 | */ 41 | Result PM_GetFIRMLaunchParams(u32 size, u8* out); 42 | 43 | /** 44 | * @brief Sets the current FIRM launch parameters. 45 | * @param firm_titleid_low Low Title ID of the FIRM title to launch. 46 | * @param size Size of the FIRM launch parameter buffer. 47 | * @param in Buffer to retrieve the launch parameters from. 48 | */ 49 | Result PM_LaunchFIRMSetParams(u32 firm_titleid_low, u32 size, u8* in); 50 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/ps.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ps.h 3 | * @brief PS service. 4 | */ 5 | #pragma once 6 | 7 | /// PS AES algorithms. 8 | typedef enum 9 | { 10 | PS_ALGORITHM_CBC_ENC, ///< CBC encoding. 11 | PS_ALGORITHM_CBC_DEC, ///< CBC decoding. 12 | PS_ALGORITHM_CTR_ENC, ///< CTR encoding. 13 | PS_ALGORITHM_CTR_DEC, ///< CTR decoding. 14 | PS_ALGORITHM_CCM_ENC, ///< CCM encoding. 15 | PS_ALGORITHM_CCM_DEC, ///< CCM decoding. 16 | } PS_AESAlgorithm; 17 | 18 | /// PS key slots. 19 | typedef enum 20 | { 21 | PS_KEYSLOT_0D, ///< Key slot 0x0D. 22 | PS_KEYSLOT_2D, ///< Key slot 0x2D. 23 | PS_KEYSLOT_31, ///< Key slot 0x31. 24 | PS_KEYSLOT_38, ///< Key slot 0x38. 25 | PS_KEYSLOT_32, ///< Key slot 0x32. 26 | PS_KEYSLOT_39_DLP, ///< Key slot 0x39. (DLP) 27 | PS_KEYSLOT_2E, ///< Key slot 0x2E. 28 | PS_KEYSLOT_INVALID, ///< Invalid key slot. 29 | PS_KEYSLOT_36, ///< Key slot 0x36. 30 | PS_KEYSLOT_39_NFC ///< Key slot 0x39. (NFC) 31 | } PS_AESKeyType; 32 | 33 | /// Initializes PS. 34 | Result psInit(void); 35 | 36 | /// Exits PS. 37 | void psExit(void); 38 | 39 | /** 40 | * @brief Encrypts/Decrypts AES data. Does not support AES CCM. 41 | * @param size Size of the data. 42 | * @param in Input buffer. 43 | * @param out Output buffer. 44 | * @param aes_algo AES algorithm to use. 45 | * @param key_type Key type to use. 46 | * @param iv Pointer to the CTR/IV. 47 | */ 48 | Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, PS_AESAlgorithm aes_algo, PS_AESKeyType key_type, u8* iv); 49 | 50 | /** 51 | * @brief Encrypts/Decrypts signed AES CCM data. 52 | * When decrypting, if the MAC is invalid, 0xC9010401 is returned. After encrypting the MAC is located at inputbufptr. 53 | * @param in Input buffer. 54 | * @param in_size Size of the input buffer. Must include MAC size when decrypting. 55 | * @param out Output buffer. 56 | * @param out_size Size of the output buffer. Must include MAC size when encrypting. 57 | * @param data_len Length of the data to be encrypted/decrypted. 58 | * @param mac_data_len Length of the MAC data. 59 | * @param mac_len Length of the MAC. 60 | * @param aes_algo AES algorithm to use. 61 | * @param key_type Key type to use. 62 | * @param nonce Pointer to the nonce. 63 | */ 64 | Result PS_EncryptSignDecryptVerifyAesCcm(u8* in, u32 in_size, u8* out, u32 out_size, u32 data_len, u32 mac_data_len, u32 mac_len, PS_AESAlgorithm aes_algo, PS_AESKeyType key_type, u8* nonce); 65 | 66 | /** 67 | * @brief Gets the 64-bit console friend code seed. 68 | * @param seed Pointer to write the friend code seed to. 69 | */ 70 | Result PS_GetLocalFriendCodeSeed(u64* seed); 71 | 72 | /** 73 | * @brief Gets the 32-bit device ID. 74 | * @param device_id Pointer to write the device ID to. 75 | */ 76 | Result PS_GetDeviceId(u32* device_id); 77 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/ptm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | Result ptmInit(); 4 | Result ptmExit(); 5 | 6 | Result ptmSysmInit(void); 7 | Result ptmSysmExit(void); 8 | 9 | Result PTMU_GetShellState(Handle* servhandle, u8 *out); 10 | Result PTMU_GetBatteryLevel(Handle* servhandle, u8 *out); 11 | Result PTMU_GetBatteryChargeState(Handle* servhandle, u8 *out); 12 | Result PTMU_GetPedometerState(Handle* servhandle, u8 *out); 13 | Result PTMU_GetTotalStepCount(Handle* servhandle, u32 *steps); 14 | 15 | Result PTMSYSM_ConfigureNew3DSCPU(u8 value); 16 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/ptmsysm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ptmsysm.h 3 | * @brief PTMSYSM service. 4 | */ 5 | #pragma once 6 | 7 | /// Initializes ptm:sysm. 8 | Result ptmSysmInit(void); 9 | 10 | /// Exits ptm:sysm. 11 | void ptmSysmExit(void); 12 | 13 | /** 14 | * @brief Configures the New 3DS' CPU clock speed and L2 cache. 15 | * @param value Bit0: enable higher clock, Bit1: enable L2 cache. 16 | */ 17 | Result PTMSYSM_ConfigureNew3DSCPU(u8 value); 18 | 19 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/ptmu.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ptmu.h 3 | * @brief PTMU service. 4 | */ 5 | #pragma once 6 | 7 | /// Initializes PTMU. 8 | Result ptmuInit(void); 9 | 10 | /// Exits PTMU. 11 | void ptmuExit(void); 12 | 13 | /** 14 | * @brief Gets the system's current shell state. 15 | * @param out Pointer to write the current shell state to. (0 = closed, 1 = open) 16 | */ 17 | Result PTMU_GetShellState(u8 *out); 18 | 19 | /** 20 | * @brief Gets the system's current battery level. 21 | * @param out Pointer to write the current battery level to. (0-5) 22 | */ 23 | Result PTMU_GetBatteryLevel(u8 *out); 24 | 25 | /** 26 | * @brief Gets the system's current battery charge state. 27 | * @param out Pointer to write the current battery charge state to. (0 = not charging, 1 = charging) 28 | */ 29 | Result PTMU_GetBatteryChargeState(u8 *out); 30 | 31 | /** 32 | * @brief Gets the system's current pedometer state. 33 | * @param out Pointer to write the current pedometer state to. (0 = not counting, 1 = counting) 34 | */ 35 | Result PTMU_GetPedometerState(u8 *out); 36 | 37 | /** 38 | * @brief Gets the pedometer's total step count. 39 | * @param steps Pointer to write the total step count to. 40 | */ 41 | Result PTMU_GetTotalStepCount(u32 *steps); 42 | 43 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/qtm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file qtm.h 3 | * @brief QTM service. 4 | */ 5 | #pragma once 6 | 7 | //See also: http://3dbrew.org/wiki/QTM_Services 8 | 9 | /// Head tracking coordinate pair. 10 | typedef struct { 11 | float x; ///< X coordinate. 12 | float y; ///< Y coordinate. 13 | } QTM_HeadTrackingInfoCoord; 14 | 15 | /// Head tracking info. 16 | typedef struct { 17 | u8 flags[5]; ///< Flags. 18 | u8 padding[3]; ///< Padding. 19 | float floatdata_x08; ///< Unknown. Not used by System_Settings. 20 | QTM_HeadTrackingInfoCoord coords0[4]; ///< Head coordinates. 21 | u32 unk_x2c[5]; ///< Unknown. Not used by System_Settings. 22 | } QTM_HeadTrackingInfo; 23 | 24 | /// Initializes QTM. 25 | Result qtmInit(void); 26 | 27 | /// Exits QTM. 28 | void qtmExit(void); 29 | 30 | /** 31 | * @brief Checks whether QTM is initialized. 32 | * @return Whether QTM is initialized. 33 | */ 34 | bool qtmCheckInitialized(void); 35 | 36 | /** 37 | * @brief Checks whether a head is fully detected. 38 | * @param info Tracking info to check. 39 | */ 40 | bool qtmCheckHeadFullyDetected(QTM_HeadTrackingInfo *info); 41 | 42 | /** 43 | * @brief Converts QTM coordinates to screen coordinates. 44 | * @param coord Coordinates to convert. 45 | * @param screen_width Width of the screen. Can be NULL to use the default value for the top screen. 46 | * @param screen_height Height of the screen. Can be NULL to use the default value for the top screen. 47 | * @param x Pointer to output the screen X coordinate to. 48 | * @param y Pointer to output the screen Y coordinate to. 49 | */ 50 | Result qtmConvertCoordToScreen(QTM_HeadTrackingInfoCoord *coord, float *screen_width, float *screen_height, u32 *x, u32 *y); 51 | 52 | /** 53 | * @brief Gets the current head tracking info. 54 | * @param val Normally 0. 55 | * @param out Pointer to write head tracking info to. 56 | */ 57 | Result QTM_GetHeadTrackingInfo(u64 val, QTM_HeadTrackingInfo* out); 58 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/soc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file soc.h 3 | * @brief SOC service for sockets communications 4 | * 5 | * After initializing this service you will be able to use system calls from netdb.h, sys/socket.h etc. 6 | */ 7 | #pragma once 8 | 9 | /** 10 | * @brief Initializes the SOC service. 11 | * @param context_addr Address of a page-aligned (0x1000) buffer to be used. 12 | * @param context_size Size of the buffer, a multiple of 0x1000. 13 | * @note 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. 14 | */ 15 | Result socInit(u32 *context_addr, u32 context_size); 16 | 17 | /** 18 | * @brief Closes the soc service. 19 | * @note You need to call this in order to be able to use the buffer again. 20 | */ 21 | Result socExit(void); 22 | 23 | // this is supposed to be in unistd.h but newlib only puts it for cygwin 24 | /** 25 | * @brief Gets the system's host ID. 26 | * @return The system's host ID. 27 | */ 28 | long gethostid(void); 29 | 30 | -------------------------------------------------------------------------------- /libctru/include/3ds/services/srvpm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file srvpm.h 3 | * @brief srv:pm service. 4 | */ 5 | #pragma once 6 | 7 | /// Initializes srv:pm. 8 | Result srvPmInit(void); 9 | 10 | /// Exits srv:pm. 11 | void srvPmExit(void); 12 | 13 | /** 14 | * @brief Publishes a notification to a process. 15 | * @param notificationId ID of the notification. 16 | * @param process Process to publish to. 17 | */ 18 | Result SRVPM_PublishToProcess(u32 notificationId, Handle process); 19 | 20 | /** 21 | * @brief Publishes a notification to all processes. 22 | * @param notificationId ID of the notification. 23 | */ 24 | Result SRVPM_PublishToAll(u32 notificationId); 25 | 26 | /** 27 | * @brief Registers a process with SRV. 28 | * @param procid ID of the process. 29 | * @param count Number of services within the service access control data. 30 | * @param serviceaccesscontrol Service Access Control list. 31 | */ 32 | Result SRVPM_RegisterProcess(u32 procid, u32 count, void* serviceaccesscontrol); 33 | 34 | /** 35 | * @brief Unregisters a process with SRV. 36 | * @param procid ID of the process. 37 | */ 38 | Result SRVPM_UnregisterProcess(u32 procid); 39 | 40 | -------------------------------------------------------------------------------- /libctru/include/3ds/srv.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file srv.h 3 | * @brief Service API. 4 | */ 5 | #pragma once 6 | 7 | /// Initializes the service API. 8 | Result srvInit(void); 9 | 10 | /// Exits the service API. 11 | void srvExit(void); 12 | 13 | /** 14 | * @brief Gets the current service API session handle. 15 | * @return The current service API session handle. 16 | */ 17 | Handle *srvGetSessionHandle(void); 18 | 19 | /** 20 | * @brief Retrieves a service handle, retrieving from the environment handle list if possible. 21 | * @param out Pointer to write the handle to. 22 | * @param name Name of the service. 23 | */ 24 | Result srvGetServiceHandle(Handle* out, const char* name); 25 | 26 | /// Registers the current process as a client to the service API. 27 | Result srvRegisterClient(void); 28 | 29 | /** 30 | * @brief Enables service notificatios, returning a notification semaphore. 31 | * @param semaphoreOut Pointer to output the notification semaphore to. 32 | */ 33 | Result srvEnableNotification(Handle* semaphoreOut); 34 | 35 | /** 36 | * @brief Registers the current process as a service. 37 | * @param out Pointer to write the service handle to. 38 | * @param name Name of the service. 39 | * @param maxSessions Maximum number of sessions the service can handle. 40 | */ 41 | Result srvRegisterService(Handle* out, const char* name, int maxSessions); 42 | 43 | /** 44 | * @brief Unregisters the current process as a service. 45 | * @param name Name of the service. 46 | */ 47 | Result srvUnregisterService(const char* name); 48 | 49 | /** 50 | * @brief Retrieves a service handle. 51 | * @param out Pointer to output the handle to. 52 | * @param name Name of the service. 53 | */ 54 | Result srvGetServiceHandleDirect(Handle* out, const char* name); 55 | 56 | /** 57 | * @brief Registers a port. 58 | * @param name Name of the port. 59 | * @param clientHandle Client handle of the port. 60 | */ 61 | Result srvRegisterPort(const char* name, Handle clientHandle); 62 | 63 | /** 64 | * @brief Unregisters a port. 65 | * @param name Name of the port. 66 | */ 67 | Result srvUnregisterPort(const char* name); 68 | 69 | /** 70 | * @brief Retrieves a port handle. 71 | * @param out Pointer to output the handle to. 72 | * @param name Name of the port. 73 | */ 74 | Result srvGetPort(Handle* out, const char* name); 75 | 76 | /** 77 | * @brief Subscribes to a notification. 78 | * @param notificationId ID of the notification. 79 | */ 80 | Result srvSubscribe(u32 notificationId); 81 | 82 | /** 83 | * @brief Unsubscribes from a notification. 84 | * @param notificationId ID of the notification. 85 | */ 86 | Result srvUnsubscribe(u32 notificationId); 87 | 88 | /** 89 | * @brief Receives a notification. 90 | * @param notificationIdOut Pointer to output the ID of the received notification to. 91 | */ 92 | Result srvReceiveNotification(u32* notificationIdOut); 93 | 94 | /** 95 | * @brief Publishes a notification to subscribers. 96 | * @param notificationId ID of the notification. 97 | * @param flags Flags to publish with. (bit 0 = only fire if not fired, bit 1 = report errors) 98 | */ 99 | Result srvPublishToSubscriber(u32 notificationId, u32 flags); 100 | 101 | /** 102 | * @brief Publishes a notification to subscribers and retrieves a list of all processes that were notified. 103 | * @param processIdCountOut Pointer to output the number of process IDs to. 104 | * @param processIdsOut Pointer to output the process IDs to. Should have size "60 * sizeof(u32)". 105 | * @param notificationId ID of the notification. 106 | */ 107 | Result srvPublishAndGetSubscriber(u32* processIdCountOut, u32* processIdsOut, u32 notificationId); 108 | 109 | /** 110 | * @brief Checks whether a service is registered. 111 | * @param registeredOut Pointer to output the registration status to. 112 | * @param name Name of the service to check. 113 | */ 114 | Result srvIsServiceRegistered(bool* registeredOut, const char* name); 115 | -------------------------------------------------------------------------------- /libctru/include/3ds/synchronization.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file synchronization.h 3 | * @brief Provides synchronization locks. 4 | */ 5 | #pragma once 6 | 7 | /// A light lock. 8 | typedef s32 LightLock; 9 | 10 | /// A recursive lock. 11 | typedef struct 12 | { 13 | LightLock lock; ///< Inner light lock. 14 | u32 thread_tag; ///< Tag of the thread that currently has the lock. 15 | u32 counter; ///< Lock count. 16 | } RecursiveLock; 17 | 18 | /// Performs a Data Synchronization Barrier operation. 19 | static inline void __dsb(void) 20 | { 21 | __asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 4" :: [val] "r" (0) : "memory"); 22 | } 23 | 24 | /// Performs a clrex operation. 25 | static inline void __clrex(void) 26 | { 27 | __asm__ __volatile__("clrex" ::: "memory"); 28 | } 29 | 30 | /** 31 | * @brief Performs a ldrex operation. 32 | * @param addr Address to perform the operation on. 33 | * @return The resulting value. 34 | */ 35 | static inline s32 __ldrex(s32* addr) 36 | { 37 | s32 val; 38 | __asm__ __volatile__("ldrex %[val], %[addr]" : [val] "=r" (val) : [addr] "Q" (*addr)); 39 | return val; 40 | } 41 | 42 | /** 43 | * @brief Performs a strex operation. 44 | * @param addr Address to perform the operation on. 45 | * @param val Value to store. 46 | * @return Whether the operation was successful. 47 | */ 48 | static inline bool __strex(s32* addr, s32 val) 49 | { 50 | bool res; 51 | __asm__ __volatile__("strex %[res], %[val], %[addr]" : [res] "=&r" (res) : [val] "r" (val), [addr] "Q" (*addr)); 52 | return res; 53 | } 54 | 55 | /// Performs an atomic pre-increment operation. 56 | #define AtomicIncrement(ptr) __atomic_add_fetch((u32*)(ptr), 1, __ATOMIC_SEQ_CST) 57 | /// Performs an atomic pre-decrement operation. 58 | #define AtomicDecrement(ptr) __atomic_sub_fetch((u32*)(ptr), 1, __ATOMIC_SEQ_CST) 59 | /// Performs an atomic post-increment operation. 60 | #define AtomicPostIncrement(ptr) __atomic_fetch_add((u32*)(ptr), 1, __ATOMIC_SEQ_CST) 61 | /// Performs an atomic post-decrement operation. 62 | #define AtomicPostDecrement(ptr) __atomic_fetch_sub((u32*)(ptr), 1, __ATOMIC_SEQ_CST) 63 | /// Performs an atomic swap operation. 64 | #define AtomicSwap(ptr, value) __atomic_exchange_n((u32*)(ptr), (value), __ATOMIC_SEQ_CST) 65 | 66 | /** 67 | * @brief Initializes a light lock. 68 | * @param lock Pointer to the lock. 69 | */ 70 | void LightLock_Init(LightLock* lock); 71 | 72 | /** 73 | * @brief Locks a light lock. 74 | * @param lock Pointer to the lock. 75 | */ 76 | void LightLock_Lock(LightLock* lock); 77 | 78 | /** 79 | * @brief Attempts to lock a light lock. 80 | * @param lock Pointer to the lock. 81 | * @return Zero on success, non-zero on failure. 82 | */ 83 | int LightLock_TryLock(LightLock* lock); 84 | 85 | /** 86 | * @brief Unlocks a light lock. 87 | * @param lock Pointer to the lock. 88 | */ 89 | void LightLock_Unlock(LightLock* lock); 90 | 91 | /** 92 | * @brief Initializes a recursive lock. 93 | * @param lock Pointer to the lock. 94 | */ 95 | void RecursiveLock_Init(RecursiveLock* lock); 96 | 97 | /** 98 | * @brief Locks a recursive lock. 99 | * @param lock Pointer to the lock. 100 | */ 101 | void RecursiveLock_Lock(RecursiveLock* lock); 102 | 103 | /** 104 | * @brief Attempts to lock a recursive lock. 105 | * @param lock Pointer to the lock. 106 | * @return Zero on success, non-zero on failure. 107 | */ 108 | int RecursiveLock_TryLock(RecursiveLock* lock); 109 | 110 | /** 111 | * @brief Unlocks a recursive lock. 112 | * @param lock Pointer to the lock. 113 | */ 114 | void RecursiveLock_Unlock(RecursiveLock* lock); 115 | -------------------------------------------------------------------------------- /libctru/include/3ds/types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file types.h 3 | * @brief Various system types. 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /// The maximum value of a u64. 12 | #define U64_MAX UINT64_MAX 13 | 14 | /// would be nice if newlib had this already 15 | #ifndef SSIZE_MAX 16 | #ifdef SIZE_MAX 17 | #define SSIZE_MAX ((SIZE_MAX) >> 1) 18 | #endif 19 | #endif 20 | 21 | typedef uint8_t u8; ///< 8-bit unsigned integer 22 | typedef uint16_t u16; ///< 16-bit unsigned integer 23 | typedef uint32_t u32; ///< 32-bit unsigned integer 24 | typedef uint64_t u64; ///< 64-bit unsigned integer 25 | 26 | typedef int8_t s8; ///< 8-bit signed integer 27 | typedef int16_t s16; ///< 16-bit signed integer 28 | typedef int32_t s32; ///< 32-bit signed integer 29 | typedef int64_t s64; ///< 64-bit signed integer 30 | 31 | typedef volatile u8 vu8; ///< 8-bit volatile unsigned integer. 32 | typedef volatile u16 vu16; ///< 16-bit volatile unsigned integer. 33 | typedef volatile u32 vu32; ///< 32-bit volatile unsigned integer. 34 | typedef volatile u64 vu64; ///< 64-bit volatile unsigned integer. 35 | 36 | typedef volatile s8 vs8; ///< 8-bit volatile signed integer. 37 | typedef volatile s16 vs16; ///< 16-bit volatile signed integer. 38 | typedef volatile s32 vs32; ///< 32-bit volatile signed integer. 39 | typedef volatile s64 vs64; ///< 64-bit volatile signed integer. 40 | 41 | typedef u32 Handle; ///< Resource handle. 42 | typedef s32 Result; ///< Function result. 43 | typedef void (*ThreadFunc)(void *); ///< Thread entrypoint function. 44 | 45 | /// Creates a bitmask from a bit number. 46 | #define BIT(n) (1U<<(n)) 47 | 48 | /// Aligns a struct (and other types?) to m, making sure that the size of the struct is a multiple of m. 49 | #define ALIGN(m) __attribute__((aligned(m))) 50 | /// Packs a struct (and other types?) so it won't include padding bytes. 51 | #define PACKED __attribute__((packed)) 52 | 53 | #ifndef LIBCTRU_NO_DEPRECATION 54 | /// Flags a function as deprecated. 55 | #define DEPRECATED __attribute__ ((deprecated)) 56 | #else 57 | /// Flags a function as deprecated. 58 | #define DEPRECATED 59 | #endif 60 | -------------------------------------------------------------------------------- /libctru/include/3ds/vram.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file vram.h 3 | * @brief VRAM allocator. 4 | */ 5 | #pragma once 6 | 7 | /** 8 | * @brief Allocates a 0x80-byte aligned buffer. 9 | * @param size Size of the buffer to allocate. 10 | * @return The allocated buffer. 11 | */ 12 | void* vramAlloc(size_t size); 13 | 14 | /** 15 | * @brief Allocates a buffer aligned to the given size. 16 | * @param size Size of the buffer to allocate. 17 | * @param alignment Alignment to use. 18 | * @return The allocated buffer. 19 | */ 20 | void* vramMemAlign(size_t size, size_t alignment); 21 | 22 | /** 23 | * @brief Reallocates a buffer. 24 | * Note: Not implemented yet. 25 | * @param mem Buffer to reallocate. 26 | * @param size Size of the buffer to allocate. 27 | * @return The reallocated buffer. 28 | */ 29 | void* vramRealloc(void* mem, size_t size); 30 | 31 | /** 32 | * @brief Frees a buffer. 33 | * @param mem Buffer to free. 34 | */ 35 | void vramFree(void* mem); 36 | 37 | /** 38 | * @brief Gets the current VRAM free space. 39 | * @return The current VRAM free space. 40 | */ 41 | u32 vramSpaceFree(void); 42 | -------------------------------------------------------------------------------- /libctru/include/arpa/inet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | static inline uint32_t htonl(uint32_t hostlong) 7 | { 8 | return __builtin_bswap32(hostlong); 9 | } 10 | 11 | static inline uint16_t htons(uint16_t hostshort) 12 | { 13 | return __builtin_bswap16(hostshort); 14 | } 15 | 16 | static inline uint32_t ntohl(uint32_t netlong) 17 | { 18 | return __builtin_bswap32(netlong); 19 | } 20 | 21 | static inline uint16_t ntohs(uint16_t netshort) 22 | { 23 | return __builtin_bswap16(netshort); 24 | } 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | in_addr_t inet_addr(const char *cp); 31 | int inet_aton(const char *cp, struct in_addr *inp); 32 | char* inet_ntoa(struct in_addr in); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | -------------------------------------------------------------------------------- /libctru/include/netdb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define HOST_NOT_FOUND 1 6 | #define NO_DATA 2 7 | #define NO_ADDRESS NO_DATA 8 | #define NO_RECOVERY 3 9 | #define TRY_AGAIN 4 10 | 11 | struct hostent { 12 | char *h_name; 13 | char **h_aliases; 14 | int h_addrtype; 15 | int h_length; 16 | char **h_addr_list; 17 | char *h_addr; 18 | }; 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | extern int h_errno; 25 | struct hostent* gethostbyname(const char *name); 26 | struct hostent* gethostbyaddr(const void *addr, socklen_t len, int type); 27 | void herror(const char *s); 28 | const char* hstrerror(int err); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | -------------------------------------------------------------------------------- /libctru/include/netinet/in.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define INADDR_LOOPBACK 0x7f000001 7 | #define INADDR_ANY 0x00000000 8 | #define INADDR_BROADCAST 0xFFFFFFFF 9 | #define INADDR_NONE 0xFFFFFFFF 10 | 11 | #define INET_ADDRSTRLEN 16 12 | 13 | /* 14 | * Protocols (See RFC 1700 and the IANA) 15 | */ 16 | #define IPPROTO_IP 0 /* dummy for IP */ 17 | #define IPPROTO_UDP 17 /* user datagram protocol */ 18 | #define IPPROTO_TCP 6 /* tcp */ 19 | 20 | #define IP_TOS 7 21 | #define IP_TTL 8 22 | #define IP_MULTICAST_LOOP 9 23 | #define IP_MULTICAST_TTL 10 24 | #define IP_ADD_MEMBERSHIP 11 25 | #define IP_DROP_MEMBERSHIP 12 26 | 27 | typedef uint16_t in_port_t; 28 | typedef uint32_t in_addr_t; 29 | 30 | struct in_addr { 31 | in_addr_t s_addr; 32 | }; 33 | 34 | struct sockaddr_in { 35 | sa_family_t sin_family; 36 | in_port_t sin_port; 37 | struct in_addr sin_addr; 38 | unsigned char sin_zero[8]; 39 | }; 40 | 41 | /* Request struct for multicast socket ops */ 42 | struct ip_mreq { 43 | struct in_addr imr_multiaddr; /* IP multicast address of group */ 44 | struct in_addr imr_interface; /* local IP address of interface */ 45 | }; 46 | -------------------------------------------------------------------------------- /libctru/include/netinet/tcp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SOL_TCP 6 /* TCP level */ 4 | 5 | enum{ 6 | _CTRU_TCP_OPT = 0x2000, /* Flag for tcp opt values */ 7 | TCP_NODELAY = 1 | _CTRU_TCP_OPT, /* Don't delay send to coalesce packets */ 8 | TCP_MAXSEG = 2 | _CTRU_TCP_OPT, 9 | }; 10 | -------------------------------------------------------------------------------- /libctru/include/poll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include <3ds/types.h> 4 | 5 | #define POLLIN 0x01 6 | #define POLLPRI 0x02 7 | #define POLLHUP 0x04 // unknown ??? 8 | #define POLLERR 0x08 // probably 9 | #define POLLOUT 0x10 10 | #define POLLNVAL 0x20 11 | 12 | typedef u32 nfds_t; 13 | 14 | struct pollfd 15 | { 16 | int fd; 17 | int events; 18 | int revents; 19 | }; 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | int poll(struct pollfd *fds, nfds_t nfsd, int timeout); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | -------------------------------------------------------------------------------- /libctru/include/sys/ioctl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define FIONBIO 1 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | int ioctl(int fd, int request, ...); 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /libctru/include/sys/select.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /libctru/include/sys/socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define SOL_SOCKET 0xFFFF 7 | 8 | #define PF_UNSPEC 0 9 | #define PF_INET 2 10 | #define PF_INET6 10 11 | 12 | #define AF_UNSPEC PF_UNSPEC 13 | #define AF_INET PF_INET 14 | #define AF_INET6 PF_INET6 15 | 16 | #define SOCK_STREAM 1 17 | #define SOCK_DGRAM 2 18 | 19 | #define MSG_CTRUNC 0x01000000 20 | #define MSG_DONTROUTE 0x02000000 21 | #define MSG_EOR 0x04000000 22 | #define MSG_OOB 0x08000000 23 | #define MSG_PEEK 0x10000000 24 | #define MSG_TRUNC 0x20000000 25 | #define MSG_WAITALL 0x40000000 26 | 27 | #define SHUT_RD 0 28 | #define SHUT_WR 1 29 | #define SHUT_RDWR 2 30 | 31 | //#define SO_DEBUG 0x0001 // not working 32 | //#define SO_ACCEPTCONN 0x0002 // not working 33 | #define SO_REUSEADDR 0x0004 34 | //#define SO_KEEPALIVE 0x0008 // not working 35 | //#define SO_DONTROUTE 0x0010 // not working 36 | //#define SO_BROADCAST 0x0020 // not working 37 | #define SO_USELOOPBACK 0x0040 38 | #define SO_LINGER 0x0080 39 | #define SO_OOBINLINE 0x0100 40 | //#define SO_REUSEPORT 0x0200 // not working 41 | 42 | /* 43 | * Additional options, not kept in so_options. 44 | */ 45 | #define SO_SNDBUF 0x1001 /* send buffer size */ 46 | #define SO_RCVBUF 0x1002 /* receive buffer size */ 47 | #define SO_SNDLOWAT 0x1003 /* send low-water mark */ 48 | #define SO_RCVLOWAT 0x1004 /* receive low-water mark */ 49 | //#define SO_SNDTIMEO 0x1005 /* send timeout */ // not working 50 | //#define SO_RCVTIMEO 0x1006 /* receive timeout */ // not working 51 | 52 | #define SO_TYPE 0x1008 /* get socket type */ 53 | #define SO_ERROR 0x1009 /* get error status and clear */ 54 | 55 | typedef uint32_t socklen_t; 56 | typedef uint16_t sa_family_t; 57 | 58 | struct sockaddr { 59 | sa_family_t sa_family; 60 | char sa_data[]; 61 | }; 62 | 63 | struct sockaddr_storage { 64 | sa_family_t ss_family; 65 | char __ss_padding[14]; 66 | }; 67 | 68 | struct linger { 69 | int l_onoff; 70 | int l_linger; 71 | }; 72 | 73 | #ifdef __cplusplus 74 | extern "C" { 75 | #endif 76 | 77 | int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 78 | int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 79 | int closesocket(int sockfd); 80 | int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 81 | int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 82 | int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 83 | int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); 84 | int listen(int sockfd, int backlog); 85 | ssize_t recv(int sockfd, void *buf, size_t len, int flags); 86 | ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); 87 | ssize_t send(int sockfd, const void *buf, size_t len, int flags); 88 | ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); 89 | int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); 90 | int shutdown(int sockfd, int how); 91 | int socket(int domain, int type, int protocol); 92 | int sockatmark(int sockfd); 93 | 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | -------------------------------------------------------------------------------- /libctru/lib/libctru.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rinnegatamante/ctrWolfen/f243d125d66f6ffea08f9580728075d6c36a3144/libctru/lib/libctru.a -------------------------------------------------------------------------------- /libctru/libctru.cppcheck: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /libctru/source/allocator/addrmap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | static rbtree_t sAddrMap; 4 | 5 | struct addrMapNode 6 | { 7 | rbtree_node node; 8 | MemChunk chunk; 9 | }; 10 | 11 | #define getAddrMapNode(x) rbtree_item((x), addrMapNode, node) 12 | 13 | static int addrMapNodeComparator(const rbtree_node_t* _lhs, const rbtree_node_t* _rhs) 14 | { 15 | auto lhs = getAddrMapNode(_lhs)->chunk.addr; 16 | auto rhs = getAddrMapNode(_rhs)->chunk.addr; 17 | if (lhs < rhs) 18 | return -1; 19 | if (lhs > rhs) 20 | return 1; 21 | return 0; 22 | } 23 | 24 | static void addrMapNodeDestructor(rbtree_node_t* a) 25 | { 26 | free(getAddrMapNode(a)); 27 | } 28 | 29 | static addrMapNode* getNode(void* addr) 30 | { 31 | addrMapNode n; 32 | n.chunk.addr = (u8*)addr; 33 | auto p = rbtree_find(&sAddrMap, &n.node); 34 | return p ? getAddrMapNode(p) : nullptr; 35 | } 36 | 37 | static addrMapNode* newNode(const MemChunk& chunk) 38 | { 39 | auto p = (addrMapNode*)malloc(sizeof(addrMapNode)); 40 | if (!p) return nullptr; 41 | p->chunk = chunk; 42 | return p; 43 | } 44 | 45 | static void delNode(addrMapNode* node) 46 | { 47 | rbtree_remove(&sAddrMap, &node->node, addrMapNodeDestructor); 48 | } 49 | -------------------------------------------------------------------------------- /libctru/source/allocator/linear.cpp: -------------------------------------------------------------------------------- 1 | extern "C" 2 | { 3 | #include <3ds/types.h> 4 | #include <3ds/allocator/linear.h> 5 | #include <3ds/util/rbtree.h> 6 | } 7 | 8 | #include "mem_pool.h" 9 | #include "addrmap.h" 10 | 11 | extern u32 __ctru_linear_heap; 12 | extern u32 __ctru_linear_heap_size; 13 | 14 | static MemPool sLinearPool; 15 | 16 | static bool linearInit() 17 | { 18 | auto blk = MemBlock::Create((u8*)__ctru_linear_heap, __ctru_linear_heap_size); 19 | if (blk) 20 | { 21 | sLinearPool.AddBlock(blk); 22 | rbtree_init(&sAddrMap, addrMapNodeComparator); 23 | return true; 24 | } 25 | return false; 26 | } 27 | 28 | void* linearMemAlign(size_t size, size_t alignment) 29 | { 30 | // Enforce minimum alignment 31 | if (alignment < 16) 32 | alignment = 16; 33 | 34 | // Convert alignment to shift amount 35 | int shift; 36 | for (shift = 4; shift < 32; shift ++) 37 | { 38 | if ((1U<node)); 60 | return chunk.addr; 61 | } 62 | 63 | void* linearAlloc(size_t size) 64 | { 65 | return linearMemAlign(size, 0x80); 66 | } 67 | 68 | void* linearRealloc(void* mem, size_t size) 69 | { 70 | // TODO 71 | return NULL; 72 | } 73 | 74 | void linearFree(void* mem) 75 | { 76 | auto node = getNode(mem); 77 | if (!node) return; 78 | 79 | // Free the chunk 80 | sLinearPool.Deallocate(node->chunk); 81 | 82 | // Free the node 83 | delNode(node); 84 | } 85 | 86 | u32 linearSpaceFree() 87 | { 88 | return sLinearPool.GetFreeSpace(); 89 | } 90 | -------------------------------------------------------------------------------- /libctru/source/allocator/mappable.cpp: -------------------------------------------------------------------------------- 1 | extern "C" 2 | { 3 | #include <3ds/types.h> 4 | #include <3ds/allocator/mappable.h> 5 | #include <3ds/util/rbtree.h> 6 | } 7 | 8 | #include "mem_pool.h" 9 | #include "addrmap.h" 10 | 11 | static MemPool sMappablePool; 12 | 13 | static bool mappableInit() 14 | { 15 | auto blk = MemBlock::Create((u8*)0x10000000, 0x04000000); 16 | if (blk) 17 | { 18 | sMappablePool.AddBlock(blk); 19 | rbtree_init(&sAddrMap, addrMapNodeComparator); 20 | return true; 21 | } 22 | return false; 23 | } 24 | 25 | void* mappableAlloc(size_t size) 26 | { 27 | // Initialize the pool if it is not ready 28 | if (!sMappablePool.Ready() && !mappableInit()) 29 | return nullptr; 30 | 31 | // Allocate the chunk 32 | MemChunk chunk; 33 | if (!sMappablePool.Allocate(chunk, size, 12)) 34 | return nullptr; 35 | 36 | auto node = newNode(chunk); 37 | if (!node) 38 | { 39 | sMappablePool.Deallocate(chunk); 40 | return nullptr; 41 | } 42 | if (rbtree_insert(&sAddrMap, &node->node)); 43 | return chunk.addr; 44 | } 45 | 46 | void mappableFree(void* mem) 47 | { 48 | auto node = getNode(mem); 49 | if (!node) return; 50 | 51 | // Free the chunk 52 | sMappablePool.Deallocate(node->chunk); 53 | 54 | // Free the node 55 | delNode(node); 56 | } 57 | 58 | u32 mappableSpaceFree() 59 | { 60 | return sMappablePool.GetFreeSpace(); 61 | } 62 | -------------------------------------------------------------------------------- /libctru/source/allocator/mem_pool.cpp: -------------------------------------------------------------------------------- 1 | #include "mem_pool.h" 2 | 3 | /* 4 | // This method is currently unused 5 | void MemPool::CoalesceLeft(MemBlock* b) 6 | { 7 | auto curPtr = b->base; 8 | for (auto p = b->prev; p; p = p->prev) 9 | { 10 | if ((p->base + p->size) != curPtr) break; 11 | curPtr = p->base; 12 | p->size += b->size; 13 | DelBlock(b); 14 | b = p; 15 | } 16 | } 17 | */ 18 | 19 | void MemPool::CoalesceRight(MemBlock* b) 20 | { 21 | auto curPtr = b->base + b->size; 22 | auto next = b->next; 23 | for (auto n = next; n; n = next) 24 | { 25 | next = n->next; 26 | if (n->base != curPtr) break; 27 | b->size += n->size; 28 | curPtr += n->size; 29 | DelBlock(n); 30 | } 31 | } 32 | 33 | bool MemPool::Allocate(MemChunk& chunk, u32 size, int align) 34 | { 35 | // Don't shift out of bounds (CERT INT34-C) 36 | if(align >= 32 || align < 0) 37 | return false; 38 | 39 | // Alignment must not be 0 40 | if(align == 0) 41 | return false; 42 | 43 | u32 alignMask = (1 << align) - 1; 44 | 45 | // Check if size doesn't fit neatly in alignment 46 | if(size & alignMask) 47 | { 48 | // Make sure addition won't overflow (CERT INT30-C) 49 | if(size > UINT32_MAX - alignMask) 50 | return false; 51 | 52 | // Pad size to next alignment 53 | size = (size + alignMask) &~ alignMask; 54 | } 55 | 56 | // Find the first suitable block 57 | for (auto b = first; b; b = b->next) 58 | { 59 | auto addr = b->base; 60 | u32 begWaste = (u32)addr & alignMask; 61 | if (begWaste > 0) begWaste = alignMask + 1 - begWaste; 62 | if (begWaste > b->size) continue; 63 | addr += begWaste; 64 | u32 bSize = b->size - begWaste; 65 | if (bSize < size) continue; 66 | 67 | // Found space! 68 | chunk.addr = addr; 69 | chunk.size = size; 70 | 71 | // Resize the block 72 | if (!begWaste) 73 | { 74 | b->base += size; 75 | b->size -= size; 76 | if (!b->size) 77 | DelBlock(b); 78 | } else 79 | { 80 | auto nAddr = addr + size; 81 | auto nSize = bSize - size; 82 | b->size = begWaste; 83 | if (nSize) 84 | { 85 | // We need to add the tail chunk that wasn't used to the list 86 | auto n = MemBlock::Create(nAddr, nSize); 87 | if (n) InsertAfter(b, n); 88 | else chunk.size += nSize; // we have no choice but to waste the space. 89 | } 90 | } 91 | return true; 92 | } 93 | 94 | return false; 95 | } 96 | 97 | void MemPool::Deallocate(const MemChunk& chunk) 98 | { 99 | u8* cAddr = chunk.addr; 100 | auto cSize = chunk.size; 101 | bool done = false; 102 | 103 | // Try to merge the chunk somewhere into the list 104 | for (auto b = first; !done && b; b = b->next) 105 | { 106 | auto addr = b->base; 107 | if (addr > cAddr) 108 | { 109 | if ((cAddr + cSize) == addr) 110 | { 111 | // Merge the chunk to the left of the block 112 | b->base = cAddr; 113 | b->size += cSize; 114 | } else 115 | { 116 | // We need to insert a new block 117 | auto c = MemBlock::Create(cAddr, cSize); 118 | if (c) InsertBefore(b, c); 119 | } 120 | done = true; 121 | } else if ((b->base + b->size) == cAddr) 122 | { 123 | // Coalesce to the right 124 | b->size += cSize; 125 | CoalesceRight(b); 126 | done = true; 127 | } 128 | } 129 | 130 | if (!done) 131 | { 132 | // Either the list is empty or the chunk address is past the end 133 | // address of the last block -- let's add a new block at the end 134 | auto b = MemBlock::Create(cAddr, cSize); 135 | if (b) AddBlock(b); 136 | } 137 | } 138 | 139 | /* 140 | void MemPool::Dump(const char* title) 141 | { 142 | printf("<%s> VRAM Pool Dump\n", title); 143 | for (auto b = first; b; b = b->next) 144 | printf(" - %p (%u bytes)\n", b->base, b->size); 145 | } 146 | */ 147 | 148 | u32 MemPool::GetFreeSpace() 149 | { 150 | u32 acc = 0; 151 | for (auto b = first; b; b = b->next) 152 | acc += b->size; 153 | return acc; 154 | } 155 | -------------------------------------------------------------------------------- /libctru/source/allocator/mem_pool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include <3ds/types.h> 3 | #include 4 | 5 | struct MemChunk 6 | { 7 | u8* addr; 8 | u32 size; 9 | }; 10 | 11 | struct MemBlock 12 | { 13 | MemBlock *prev, *next; 14 | u8* base; 15 | u32 size; 16 | 17 | static MemBlock* Create(u8* base, u32 size) 18 | { 19 | auto b = (MemBlock*)malloc(sizeof(MemBlock)); 20 | if (!b) return nullptr; 21 | b->prev = nullptr; 22 | b->next = nullptr; 23 | b->base = base; 24 | b->size = size; 25 | return b; 26 | } 27 | }; 28 | 29 | struct MemPool 30 | { 31 | MemBlock *first, *last; 32 | 33 | bool Ready() { return first != nullptr; } 34 | 35 | void AddBlock(MemBlock* blk) 36 | { 37 | blk->prev = last; 38 | if (last) last->next = blk; 39 | if (!first) first = blk; 40 | last = blk; 41 | } 42 | 43 | void DelBlock(MemBlock* b) 44 | { 45 | auto prev = b->prev, &pNext = prev ? prev->next : first; 46 | auto next = b->next, &nPrev = next ? next->prev : last; 47 | pNext = next; 48 | nPrev = prev; 49 | free(b); 50 | } 51 | 52 | void InsertBefore(MemBlock* b, MemBlock* p) 53 | { 54 | auto prev = b->prev, &pNext = prev ? prev->next : first; 55 | b->prev = p; 56 | p->next = b; 57 | p->prev = prev; 58 | pNext = p; 59 | } 60 | 61 | void InsertAfter(MemBlock* b, MemBlock* n) 62 | { 63 | auto next = b->next, &nPrev = next ? next->prev : last; 64 | b->next = n; 65 | n->prev = b; 66 | n->next = next; 67 | nPrev = n; 68 | } 69 | 70 | //void CoalesceLeft(MemBlock* b); 71 | void CoalesceRight(MemBlock* b); 72 | 73 | bool Allocate(MemChunk& chunk, u32 size, int align); 74 | void Deallocate(const MemChunk& chunk); 75 | 76 | void Destroy() 77 | { 78 | MemBlock* next = nullptr; 79 | for (auto b = first; b; b = next) 80 | { 81 | next = b->next; 82 | free(b); 83 | } 84 | first = nullptr; 85 | last = nullptr; 86 | } 87 | 88 | //void Dump(const char* title); 89 | u32 GetFreeSpace(); 90 | }; 91 | -------------------------------------------------------------------------------- /libctru/source/allocator/vram.cpp: -------------------------------------------------------------------------------- 1 | extern "C" 2 | { 3 | #include <3ds/types.h> 4 | #include <3ds/allocator/vram.h> 5 | #include <3ds/util/rbtree.h> 6 | } 7 | 8 | #include "mem_pool.h" 9 | #include "addrmap.h" 10 | 11 | static MemPool sVramPool; 12 | 13 | static bool vramInit() 14 | { 15 | auto blk = MemBlock::Create((u8*)0x1F000000, 0x00600000); 16 | if (blk) 17 | { 18 | sVramPool.AddBlock(blk); 19 | rbtree_init(&sAddrMap, addrMapNodeComparator); 20 | return true; 21 | } 22 | return false; 23 | } 24 | 25 | void* vramMemAlign(size_t size, size_t alignment) 26 | { 27 | // Enforce minimum alignment 28 | if (alignment < 16) 29 | alignment = 16; 30 | 31 | // Convert alignment to shift amount 32 | int shift; 33 | for (shift = 4; shift < 32; shift ++) 34 | { 35 | if ((1U<node)); 57 | return chunk.addr; 58 | } 59 | 60 | void* vramAlloc(size_t size) 61 | { 62 | return vramMemAlign(size, 0x80); 63 | } 64 | 65 | void* vramRealloc(void* mem, size_t size) 66 | { 67 | // TODO 68 | return NULL; 69 | } 70 | 71 | void vramFree(void* mem) 72 | { 73 | auto node = getNode(mem); 74 | if (!node) return; 75 | 76 | // Free the chunk 77 | sVramPool.Deallocate(node->chunk); 78 | 79 | // Free the node 80 | delNode(node); 81 | } 82 | 83 | u32 vramSpaceFree() 84 | { 85 | return sVramPool.GetFreeSpace(); 86 | } 87 | -------------------------------------------------------------------------------- /libctru/source/env.c: -------------------------------------------------------------------------------- 1 | #include <3ds/types.h> 2 | #include <3ds/svc.h> 3 | #include <3ds/env.h> 4 | 5 | /* 6 | The homebrew loader can choose to supply a list of service handles that have 7 | been "stolen" from other processes that have been compromised. This allows us 8 | to access services that are normally restricted from the current process. 9 | 10 | For every service requested by the application, we shall first check if the 11 | list given to us contains the requested service and if so use it. If we don't 12 | find the service in that list, we ask the service manager and hope for the 13 | best. 14 | */ 15 | 16 | typedef struct { 17 | u32 num; 18 | 19 | struct { 20 | char name[8]; 21 | Handle handle; 22 | } services[]; 23 | } service_list_t; 24 | 25 | extern void* __service_ptr; 26 | 27 | static int __name_cmp(const char* a, const char* b) { 28 | u32 i; 29 | 30 | for(i=0; i<8; i++) { 31 | if(a[i] != b[i]) 32 | return 1; 33 | if(a[i] == '\0') 34 | return 0; 35 | } 36 | 37 | return 0; 38 | } 39 | 40 | Handle envGetHandle(const char* name) { 41 | if(__service_ptr == NULL) 42 | return 0; 43 | 44 | service_list_t* service_list = (service_list_t*) __service_ptr; 45 | u32 i, num = service_list->num; 46 | 47 | for(i=0; iservices[i].name, name) == 0) 49 | return service_list->services[i].handle; 50 | } 51 | 52 | return 0; 53 | } 54 | 55 | void envDestroyHandles(void) { 56 | if(__service_ptr == NULL) 57 | return; 58 | 59 | service_list_t* service_list = (service_list_t*) __service_ptr; 60 | u32 i, num = service_list->num; 61 | 62 | for(i=0; iservices[i].handle); 64 | 65 | service_list->num = 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /libctru/source/gpu/gx.c: -------------------------------------------------------------------------------- 1 | /* 2 | gx.c _ Sending GPU requests via GSP shared memory. 3 | */ 4 | 5 | #include 6 | #include <3ds/types.h> 7 | #include <3ds/svc.h> 8 | #include <3ds/srv.h> 9 | #include <3ds/gpu/gx.h> 10 | #include <3ds/services/gspgpu.h> 11 | 12 | u32* gxCmdBuf; 13 | 14 | Result GX_RequestDma(u32* src, u32* dst, u32 length) 15 | { 16 | u32 gxCommand[0x8]; 17 | gxCommand[0]=0x00; //CommandID 18 | gxCommand[1]=(u32)src; //source address 19 | gxCommand[2]=(u32)dst; //destination address 20 | gxCommand[3]=length; //size 21 | gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0; 22 | 23 | return gspSubmitGxCommand(gxCmdBuf, gxCommand); 24 | } 25 | 26 | Result GX_ProcessCommandList(u32* buf0a, u32 buf0s, u8 flags) 27 | { 28 | u32 gxCommand[0x8]; 29 | gxCommand[0]=0x01; //CommandID 30 | gxCommand[1]=(u32)buf0a; //buf0 address 31 | gxCommand[2]=(u32)buf0s; //buf0 size 32 | gxCommand[3]=flags&1; //written to GSP module state 33 | gxCommand[4]=gxCommand[5]=gxCommand[6]=0x0; 34 | gxCommand[7]=(flags>>1)&1; //when non-zero, call svcFlushProcessDataCache() with the specified buffer 35 | 36 | return gspSubmitGxCommand(gxCmdBuf, gxCommand); 37 | } 38 | 39 | Result GX_MemoryFill(u32* buf0a, u32 buf0v, u32* buf0e, u16 control0, u32* buf1a, u32 buf1v, u32* buf1e, u16 control1) 40 | { 41 | u32 gxCommand[0x8]; 42 | // gxCommand[0]=0x02; //CommandID 43 | gxCommand[0]=0x01000102; //CommandID 44 | gxCommand[1]=(u32)buf0a; //buf0 address 45 | gxCommand[2]=buf0v; //buf0 value 46 | gxCommand[3]=(u32)buf0e; //buf0 end addr 47 | gxCommand[4]=(u32)buf1a; //buf1 address 48 | gxCommand[5]=buf1v; //buf1 value 49 | gxCommand[6]=(u32)buf1e; //buf1 end addr 50 | gxCommand[7]=(control0)|(control1<<16); 51 | 52 | return gspSubmitGxCommand(gxCmdBuf, gxCommand); 53 | } 54 | 55 | // Flags, for applications this is 0x1001000 for the main screen, and 0x1000 for the sub screen. 56 | Result GX_DisplayTransfer(u32* inadr, u32 indim, u32* outadr, u32 outdim, u32 flags) 57 | { 58 | u32 gxCommand[0x8]; 59 | gxCommand[0]=0x03; //CommandID 60 | gxCommand[1]=(u32)inadr; 61 | gxCommand[2]=(u32)outadr; 62 | gxCommand[3]=indim; 63 | gxCommand[4]=outdim; 64 | gxCommand[5]=flags; 65 | gxCommand[6]=gxCommand[7]=0x0; 66 | 67 | return gspSubmitGxCommand(gxCmdBuf, gxCommand); 68 | } 69 | 70 | Result GX_TextureCopy(u32* inadr, u32 indim, u32* outadr, u32 outdim, u32 size, u32 flags) 71 | { 72 | u32 gxCommand[0x8]; 73 | gxCommand[0]=0x04; //CommandID 74 | gxCommand[1]=(u32)inadr; 75 | gxCommand[2]=(u32)outadr; 76 | gxCommand[3]=size; 77 | gxCommand[4]=indim; 78 | gxCommand[5]=outdim; 79 | gxCommand[6]=flags; 80 | gxCommand[7]=0x0; 81 | 82 | return gspSubmitGxCommand(gxCmdBuf, gxCommand); 83 | } 84 | 85 | Result GX_FlushCacheRegions(u32* buf0a, u32 buf0s, u32* buf1a, u32 buf1s, u32* buf2a, u32 buf2s) 86 | { 87 | u32 gxCommand[0x8]; 88 | gxCommand[0]=0x05; //CommandID 89 | gxCommand[1]=(u32)buf0a; //buf0 address 90 | gxCommand[2]=(u32)buf0s; //buf0 size 91 | gxCommand[3]=(u32)buf1a; //buf1 address 92 | gxCommand[4]=(u32)buf1s; //buf1 size 93 | gxCommand[5]=(u32)buf2a; //buf2 address 94 | gxCommand[6]=(u32)buf2s; //buf2 size 95 | gxCommand[7]=0x0; 96 | 97 | return gspSubmitGxCommand(gxCmdBuf, gxCommand); 98 | } 99 | -------------------------------------------------------------------------------- /libctru/source/gpu/shbin.c: -------------------------------------------------------------------------------- 1 | /* 2 | shdr.c _ Shader loader. 3 | */ 4 | 5 | #include 6 | #include 7 | #include <3ds/types.h> 8 | #include <3ds/gpu/gpu.h> 9 | #include <3ds/gpu/shbin.h> 10 | 11 | //please don't feed this an invalid SHBIN 12 | DVLB_s* DVLB_ParseFile(u32* shbinData, u32 shbinSize) 13 | { 14 | if(!shbinData)return NULL; 15 | DVLB_s* ret=malloc(sizeof(DVLB_s)); 16 | if(!ret)goto exit; 17 | 18 | //parse DVLB 19 | ret->numDVLE=shbinData[1]; 20 | ret->DVLE=malloc(sizeof(DVLE_s)*ret->numDVLE); 21 | if(!ret->DVLE)goto clean1; 22 | 23 | //parse DVLP 24 | u32* dvlpData=&shbinData[2+ret->numDVLE]; 25 | ret->DVLP.codeSize=dvlpData[3]; 26 | ret->DVLP.codeData=&dvlpData[dvlpData[2]/4]; 27 | ret->DVLP.opdescSize=dvlpData[5]; 28 | ret->DVLP.opcdescData=(u32*)malloc(sizeof(u32)*ret->DVLP.opdescSize); 29 | if(!ret->DVLP.opcdescData)goto clean2; 30 | int i; for(i=0;iDVLP.opdescSize;i++)ret->DVLP.opcdescData[i]=dvlpData[dvlpData[4]/4+i*2]; 31 | 32 | //parse DVLE 33 | for(i=0;inumDVLE;i++) 34 | { 35 | DVLE_s* dvle=&ret->DVLE[i]; 36 | u32* dvleData=&shbinData[shbinData[2+i]/4]; 37 | 38 | dvle->dvlp=&ret->DVLP; 39 | 40 | dvle->type=(dvleData[1]>>16)&0xFF; 41 | dvle->mainOffset=dvleData[2]; 42 | dvle->endmainOffset=dvleData[3]; 43 | 44 | dvle->constTableSize=dvleData[7]; 45 | dvle->constTableData=(DVLE_constEntry_s*)&dvleData[dvleData[6]/4]; 46 | 47 | dvle->outTableSize=dvleData[11]; 48 | dvle->outTableData=(DVLE_outEntry_s*)&dvleData[dvleData[10]/4]; 49 | 50 | dvle->uniformTableSize=dvleData[13]; 51 | dvle->uniformTableData=(DVLE_uniformEntry_s*)&dvleData[dvleData[12]/4]; 52 | 53 | dvle->symbolTableData=(char*)&dvleData[dvleData[14]/4]; 54 | 55 | DVLE_GenerateOutmap(dvle); 56 | } 57 | 58 | goto exit; 59 | clean2: 60 | free(ret->DVLE); 61 | clean1: 62 | free(ret); 63 | ret=NULL; 64 | exit: 65 | return ret; 66 | } 67 | 68 | //TODO 69 | void DVLB_Free(DVLB_s* dvlb) 70 | { 71 | if(!dvlb)return; 72 | if(dvlb->DVLP.opcdescData)free(dvlb->DVLP.opcdescData); 73 | if(dvlb->DVLE)free(dvlb->DVLE); 74 | free(dvlb); 75 | } 76 | 77 | s8 DVLE_GetUniformRegister(DVLE_s* dvle, const char* name) 78 | { 79 | if(!dvle || !name)return -1; 80 | 81 | int i; DVLE_uniformEntry_s* u=dvle->uniformTableData; 82 | for(i=0;iuniformTableSize;i++) 83 | { 84 | if(!strcmp(&dvle->symbolTableData[u->symbolOffset],name))return (s8)u->startReg-0x10; 85 | u++; 86 | } 87 | return -1; 88 | } 89 | 90 | void DVLE_GenerateOutmap(DVLE_s* dvle) 91 | { 92 | if(!dvle)return; 93 | 94 | memset(dvle->outmapData, 0x1F, sizeof(dvle->outmapData)); 95 | 96 | int i; 97 | u8 numAttr=0; 98 | u8 maxAttr=0; 99 | u8 attrMask=0; 100 | 101 | for(i=0;ioutTableSize;i++) 102 | { 103 | u32* out=&dvle->outmapData[dvle->outTableData[i].regID+1]; 104 | u32 mask=0x00000000; 105 | u8 tmpmask=dvle->outTableData[i].mask; 106 | mask=(mask<<8)|((tmpmask&8)?0xFF:0x00);tmpmask<<=1; 107 | mask=(mask<<8)|((tmpmask&8)?0xFF:0x00);tmpmask<<=1; 108 | mask=(mask<<8)|((tmpmask&8)?0xFF:0x00);tmpmask<<=1; 109 | mask=(mask<<8)|((tmpmask&8)?0xFF:0x00);tmpmask<<=1; 110 | 111 | if(*out==0x1F1F1F1F)numAttr++; 112 | 113 | u32 val=0x1F1F1F1F; 114 | switch(dvle->outTableData[i].type) 115 | { 116 | case RESULT_POSITION: val=0x03020100; break; 117 | case RESULT_NORMALQUAT: val=0x07060504; break; 118 | case RESULT_COLOR: val=0x0B0A0908; break; 119 | case RESULT_TEXCOORD0: val=0x1F1F0D0C; break; 120 | case RESULT_TEXCOORD0W: val=0x10101010; break; 121 | case RESULT_TEXCOORD1: val=0x1F1F0F0E; break; 122 | case RESULT_TEXCOORD2: val=0x1F1F1716; break; 123 | case RESULT_VIEW: val=0x1F141312; break; 124 | } 125 | *out=((*out)&~mask)|(val&mask); 126 | 127 | attrMask|=1<outTableData[i].regID; 128 | if(dvle->outTableData[i].regID+1>maxAttr)maxAttr=dvle->outTableData[i].regID+1; 129 | } 130 | 131 | dvle->outmapData[0]=numAttr; 132 | dvle->outmapMask=attrMask; 133 | } 134 | -------------------------------------------------------------------------------- /libctru/source/internal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include <3ds/types.h> 3 | #include <3ds/result.h> 4 | #include <3ds/svc.h> 5 | #include 6 | 7 | #define FS_OVERRIDE_MAGIC 0x21465324 // !FS$ 8 | 9 | typedef struct 10 | { 11 | // Pointer to this thread's newlib state 12 | struct _reent* reent; 13 | 14 | // FS session override 15 | u32 fs_magic; 16 | Handle fs_session; 17 | bool fs_sdmc; 18 | } ThreadVars; 19 | 20 | static inline ThreadVars* getThreadVars(void) 21 | { 22 | return (ThreadVars*)getThreadLocalStorage(); 23 | } 24 | -------------------------------------------------------------------------------- /libctru/source/ndsp/ndsp-internal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include <3ds/types.h> 5 | #include <3ds/result.h> 6 | #include <3ds/svc.h> 7 | #include <3ds/os.h> 8 | #include <3ds/synchronization.h> 9 | #include <3ds/services/dsp.h> 10 | #include <3ds/services/apt.h> 11 | #include <3ds/ndsp/ndsp.h> 12 | 13 | extern u16 ndspFrameId, ndspBufferCurId, ndspBufferId; 14 | extern void* ndspVars[16][2]; 15 | 16 | typedef struct 17 | { 18 | u32 paddr, sampleCount; 19 | ndspAdpcmData adpcmData; 20 | u8 hasAdpcmData, looping; 21 | u16 seqId, padding; 22 | } DspChnBuf; 23 | 24 | typedef struct 25 | { 26 | u32 flags; 27 | float mix[12]; 28 | float rate; 29 | u8 rim[2]; 30 | u16 iirFilterType; 31 | u16 iirFilter_mono[2]; 32 | u16 iirFilter_biquad[5]; 33 | u16 activeBuffers; 34 | DspChnBuf buffers[4]; 35 | u32 _pad0; 36 | u16 playStatus, syncCount; 37 | u32 unknown; 38 | u32 _pad1; 39 | 40 | u32 paddr, sampleCount; 41 | u16 cntFlags; 42 | ndspAdpcmData adpcmData; 43 | u16 moreFlags; 44 | u16 seqId; 45 | } DspChnStruct; 46 | 47 | typedef struct 48 | { 49 | u16 flags, syncCount; 50 | u32 samplePos; 51 | u16 curSeqId, lastSeqId; 52 | } DspChnStatus; 53 | 54 | typedef struct 55 | { 56 | u32 flags; 57 | float masterVol; 58 | float auxReturnVol[2]; 59 | u16 outBufCount; 60 | u16 _pad0[2]; 61 | u16 outputMode; 62 | u16 clippingMode; 63 | u16 headsetConnected; 64 | u16 surroundDepth; 65 | u16 surroundSpeakerPos; 66 | u16 _pad1; 67 | u16 rearRatio; 68 | u16 auxFrontBypass[2]; 69 | u16 auxBusEnable[2]; 70 | u16 dspDelayEffect[2][10]; 71 | u16 dspReverbEffect[2][26]; 72 | u16 syncMode; 73 | u16 _pad2; 74 | u32 unknown; 75 | } DspMasterStatus; 76 | 77 | static inline u32 ndspiRotateVal(u32 x) 78 | { 79 | return (x << 16) | (x >> 16); 80 | } 81 | 82 | static inline DspChnStruct* ndspiGetChnStruct(int id) 83 | { 84 | DspChnStruct* them = (DspChnStruct*)ndspVars[1][ndspFrameId&1]; 85 | return &them[id]; 86 | } 87 | 88 | static inline DspChnStatus* ndspiGetChnStatus(int id) 89 | { 90 | DspChnStatus* them = (DspChnStatus*)ndspVars[2][ndspBufferId]; 91 | return &them[id]; 92 | } 93 | 94 | static inline u16* ndspiGetChnAdpcmCoefs(int id) 95 | { 96 | u16* them = (u16*)ndspVars[3][ndspBufferId]; 97 | return &them[id*16]; 98 | } 99 | 100 | static inline DspMasterStatus* ndspiGetMasterStatus(void) 101 | { 102 | return (DspMasterStatus*)ndspVars[4][ndspBufferCurId]; 103 | } 104 | 105 | void ndspiInitChn(void); 106 | void ndspiDirtyChn(void); 107 | void ndspiUpdateChn(void); 108 | void ndspiReadChnState(void); 109 | -------------------------------------------------------------------------------- /libctru/source/os-versionbin.c: -------------------------------------------------------------------------------- 1 | #include <3ds/types.h> 2 | #include <3ds/result.h> 3 | #include <3ds/os.h> 4 | #include <3ds/svc.h> 5 | #include <3ds/romfs.h> 6 | #include <3ds/services/ptmsysm.h> 7 | #include <3ds/services/fs.h> 8 | #include <3ds/services/cfgu.h> 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | //See here regarding regions: http://3dbrew.org/wiki/Nandrw/sys/SecureInfo_A 17 | 18 | static u32 __NVer_tidlow_regionarray[7] = { 19 | 0x00016202, //JPN 20 | 0x00016302, //USA 21 | 0x00016102, //EUR 22 | 0x00016202, //"AUS" 23 | 0x00016402, //CHN 24 | 0x00016502, //KOR 25 | 0x00016602, //TWN 26 | }; 27 | 28 | static u32 __CVer_tidlow_regionarray[7] = { 29 | 0x00017202, //JPN 30 | 0x00017302, //USA 31 | 0x00017102, //EUR 32 | 0x00017202, //"AUS" 33 | 0x00017402, //CHN 34 | 0x00017502, //KOR 35 | 0x00017602 //TWN 36 | }; 37 | 38 | 39 | static Result __read_versionbin(FS_Archive archive, FS_Path fileLowPath, OS_VersionBin *versionbin) 40 | { 41 | Result ret = 0; 42 | Handle filehandle = 0; 43 | FILE *f = NULL; 44 | 45 | ret = FSUSER_OpenFileDirectly(&filehandle, archive, fileLowPath, FS_OPEN_READ, 0x0); 46 | if(R_FAILED(ret))return ret; 47 | 48 | ret = romfsInitFromFile(filehandle, 0x0); 49 | if(R_FAILED(ret))return ret; 50 | 51 | f = fopen("romfs:/version.bin", "r"); 52 | if(f==NULL) 53 | { 54 | ret = errno; 55 | } 56 | else 57 | { 58 | if(fread(versionbin, 1, sizeof(OS_VersionBin), f) != sizeof(OS_VersionBin))ret = -10; 59 | fclose(f); 60 | } 61 | 62 | romfsExit(); 63 | 64 | return ret; 65 | } 66 | 67 | Result osGetSystemVersionData(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin) 68 | { 69 | Result ret=0; 70 | u8 region=0; 71 | 72 | u32 archive_lowpath_data[0x10>>2]; 73 | u32 file_lowpath_data[0x14>>2]; 74 | 75 | FS_Archive archive; 76 | FS_Path fileLowPath; 77 | 78 | memset(archive_lowpath_data, 0, sizeof(archive_lowpath_data)); 79 | memset(file_lowpath_data, 0, sizeof(file_lowpath_data)); 80 | 81 | archive.id = 0x2345678a; 82 | archive.lowPath.type = PATH_BINARY; 83 | archive.lowPath.size = 0x10; 84 | archive.lowPath.data = archive_lowpath_data; 85 | 86 | fileLowPath.type = PATH_BINARY; 87 | fileLowPath.size = 0x14; 88 | fileLowPath.data = file_lowpath_data; 89 | 90 | archive_lowpath_data[1] = 0x000400DB; 91 | 92 | ret = cfguInit(); 93 | if(R_FAILED(ret))return ret; 94 | 95 | ret = CFGU_SecureInfoGetRegion(®ion); 96 | if(R_FAILED(ret))return ret; 97 | 98 | if(region>=7)return -9; 99 | 100 | cfguExit(); 101 | 102 | archive_lowpath_data[0] = __NVer_tidlow_regionarray[region]; 103 | ret = __read_versionbin(archive, fileLowPath, nver_versionbin); 104 | if(R_FAILED(ret))return ret; 105 | 106 | archive_lowpath_data[0] = __CVer_tidlow_regionarray[region]; 107 | ret = __read_versionbin(archive, fileLowPath, cver_versionbin); 108 | return ret; 109 | } 110 | 111 | Result osGetSystemVersionDataString(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin, char *sysverstr, u32 sysverstr_maxsize) 112 | { 113 | Result ret=0; 114 | OS_VersionBin nver_versionbin_tmp, cver_versionbin_tmp; 115 | 116 | if(nver_versionbin==NULL)nver_versionbin = &nver_versionbin_tmp; 117 | if(cver_versionbin==NULL)cver_versionbin = &cver_versionbin_tmp; 118 | 119 | ret = osGetSystemVersionData(nver_versionbin, cver_versionbin); 120 | if(R_FAILED(ret))return ret; 121 | 122 | snprintf(sysverstr, sysverstr_maxsize, "%u.%u.%u-%u%c\n", cver_versionbin->mainver, cver_versionbin->minor, cver_versionbin->build, nver_versionbin->mainver, nver_versionbin->region); 123 | 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /libctru/source/services/ac.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/result.h> 4 | #include <3ds/svc.h> 5 | #include <3ds/srv.h> 6 | #include <3ds/synchronization.h> 7 | #include <3ds/services/ac.h> 8 | #include <3ds/ipc.h> 9 | 10 | static Handle acHandle; 11 | static int acRefCount; 12 | 13 | Result acInit(void) 14 | { 15 | Result ret; 16 | 17 | if (AtomicPostIncrement(&acRefCount)) return 0; 18 | 19 | ret = srvGetServiceHandle(&acHandle, "ac:u"); 20 | if(R_FAILED(ret)) ret = srvGetServiceHandle(&acHandle, "ac:i"); 21 | if(R_FAILED(ret)) AtomicDecrement(&acRefCount); 22 | 23 | return ret; 24 | } 25 | 26 | void acExit(void) 27 | { 28 | if (AtomicDecrement(&acRefCount)) return; 29 | svcCloseHandle(acHandle); 30 | } 31 | 32 | Result acWaitInternetConnection(void) 33 | { 34 | Result ret = 0; 35 | u32 status = 0; 36 | while(R_SUCCEEDED(ret = ACU_GetWifiStatus(&status)) && status == 0); 37 | return ret; 38 | } 39 | 40 | Result ACU_GetWifiStatus(u32 *out) 41 | { 42 | Result ret=0; 43 | u32 *cmdbuf = getThreadCommandBuffer(); 44 | 45 | cmdbuf[0] = IPC_MakeHeader(0xD,0,0); // 0x000D0000 46 | 47 | if(R_FAILED(ret = svcSendSyncRequest(acHandle)))return ret; 48 | 49 | *out = cmdbuf[2]; 50 | 51 | return (Result)cmdbuf[1]; 52 | } 53 | -------------------------------------------------------------------------------- /libctru/source/services/cfgnor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/result.h> 4 | #include <3ds/svc.h> 5 | #include <3ds/srv.h> 6 | #include <3ds/services/cfgnor.h> 7 | #include <3ds/ipc.h> 8 | 9 | Handle cfgnorHandle; 10 | 11 | Result cfgnorInit(u8 value) 12 | { 13 | Result ret = 0; 14 | if(R_FAILED(ret = srvGetServiceHandle(&cfgnorHandle, "cfg:nor")))return ret; 15 | if(R_FAILED(ret = CFGNOR_Initialize(value))) svcCloseHandle(cfgnorHandle); 16 | return ret; 17 | } 18 | 19 | void cfgnorExit(void) 20 | { 21 | if(cfgnorHandle != 0) 22 | { 23 | CFGNOR_Shutdown(); 24 | svcCloseHandle(cfgnorHandle); 25 | cfgnorHandle = 0; 26 | } 27 | } 28 | 29 | Result cfgnorDumpFlash(u32 *buf, u32 size) 30 | { 31 | Result ret = 0; 32 | u32 pos=0; 33 | u32 chunksize = 0x100; 34 | 35 | for(pos=0; pos>2], chunksize); 40 | if(R_FAILED(ret))break; 41 | } 42 | 43 | return ret; 44 | } 45 | 46 | Result cfgnorWriteFlash(u32 *buf, u32 size) 47 | { 48 | Result ret = 0; 49 | u32 pos=0; 50 | u32 chunksize = 0x100; 51 | 52 | for(pos=0; pos>2], chunksize); 57 | if(ret!=0)break; 58 | } 59 | 60 | return ret; 61 | } 62 | 63 | Result CFGNOR_Initialize(u8 value) 64 | { 65 | Result ret = 0; 66 | u32 *cmdbuf = getThreadCommandBuffer(); 67 | 68 | cmdbuf[0] = IPC_MakeHeader(0x1,1,0); // 0x10040 69 | cmdbuf[1] = (u32)value; 70 | 71 | if(R_FAILED(ret = svcSendSyncRequest(cfgnorHandle)))return ret; 72 | 73 | return cmdbuf[1]; 74 | } 75 | 76 | Result CFGNOR_Shutdown(void) 77 | { 78 | Result ret = 0; 79 | u32 *cmdbuf = getThreadCommandBuffer(); 80 | 81 | cmdbuf[0] = IPC_MakeHeader(0x2,0,0); // 0x20000 82 | 83 | if(R_FAILED(ret = svcSendSyncRequest(cfgnorHandle)))return ret; 84 | 85 | return cmdbuf[1]; 86 | } 87 | 88 | Result CFGNOR_ReadData(u32 offset, u32 *buf, u32 size) 89 | { 90 | Result ret = 0; 91 | u32 *cmdbuf = getThreadCommandBuffer(); 92 | 93 | cmdbuf[0] = IPC_MakeHeader(0x5,2,2); // 0x50082 94 | cmdbuf[1] = offset; 95 | cmdbuf[2] = size; 96 | cmdbuf[3] = IPC_Desc_Buffer(size,IPC_BUFFER_W); 97 | cmdbuf[4] = (u32)buf; 98 | 99 | if(R_FAILED(ret = svcSendSyncRequest(cfgnorHandle)))return ret; 100 | 101 | return cmdbuf[1]; 102 | } 103 | 104 | Result CFGNOR_WriteData(u32 offset, u32 *buf, u32 size) 105 | { 106 | u32 ret = 0; 107 | u32 *cmdbuf = getThreadCommandBuffer(); 108 | 109 | cmdbuf[0] = IPC_MakeHeader(0x6,2,2); // 0x60082 110 | cmdbuf[1] = offset; 111 | cmdbuf[2] = size; 112 | cmdbuf[3] = IPC_Desc_Buffer(size,IPC_BUFFER_R); 113 | cmdbuf[4] = (u32)buf; 114 | 115 | if(R_FAILED(ret = svcSendSyncRequest(cfgnorHandle)))return ret; 116 | 117 | return cmdbuf[1]; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /libctru/source/services/gsplcd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds/types.h> 4 | #include <3ds/ipc.h> 5 | #include <3ds/result.h> 6 | #include <3ds/svc.h> 7 | #include <3ds/srv.h> 8 | #include <3ds/synchronization.h> 9 | #include <3ds/services/gsplcd.h> 10 | 11 | Handle gspLcdHandle; 12 | static int gspLcdRefCount; 13 | 14 | Result gspLcdInit(void) 15 | { 16 | Result res=0; 17 | if (AtomicPostIncrement(&gspLcdRefCount)) return 0; 18 | res = srvGetServiceHandle(&gspLcdHandle, "gsp::Lcd"); 19 | if (R_FAILED(res)) AtomicDecrement(&gspLcdRefCount); 20 | return res; 21 | } 22 | 23 | void gspLcdExit(void) 24 | { 25 | if (AtomicDecrement(&gspLcdRefCount)) return; 26 | svcCloseHandle(gspLcdHandle); 27 | } 28 | 29 | Result GSPLCD_PowerOnBacklight(u32 screen) 30 | { 31 | u32 *cmdbuf = getThreadCommandBuffer(); 32 | 33 | cmdbuf[0] = IPC_MakeHeader(0x11,1,0); // 0x110040 34 | cmdbuf[1] = screen; 35 | 36 | Result ret=0; 37 | if (R_FAILED(ret = svcSendSyncRequest(gspLcdHandle))) return ret; 38 | 39 | return cmdbuf[1]; 40 | } 41 | 42 | Result GSPLCD_PowerOffBacklight(u32 screen) 43 | { 44 | u32 *cmdbuf = getThreadCommandBuffer(); 45 | 46 | cmdbuf[0] = IPC_MakeHeader(0x12,1,0); // 0x120040 47 | cmdbuf[1] = screen; 48 | 49 | Result ret=0; 50 | if (R_FAILED(ret = svcSendSyncRequest(gspLcdHandle))) return ret; 51 | 52 | return cmdbuf[1]; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /libctru/source/services/gx.c: -------------------------------------------------------------------------------- 1 | /* 2 | gx.c _ Sending GPU requests via GSP shared memory. 3 | */ 4 | 5 | #include 6 | #include <3ds/types.h> 7 | #include <3ds/svc.h> 8 | #include <3ds/srv.h> 9 | #include <3ds/gpu/gx.h> 10 | #include <3ds/services/gsp.h> 11 | 12 | u32* gxCmdBuf; 13 | 14 | Result GX_RequestDma(u32* gxbuf, u32* src, u32* dst, u32 length) 15 | { 16 | if(!gxbuf)gxbuf=gxCmdBuf; 17 | 18 | u32 gxCommand[0x8]; 19 | gxCommand[0]=0x00; //CommandID 20 | gxCommand[1]=(u32)src; //source address 21 | gxCommand[2]=(u32)dst; //destination address 22 | gxCommand[3]=length; //size 23 | gxCommand[4]=gxCommand[5]=gxCommand[6]=gxCommand[7]=0x0; 24 | 25 | return GSPGPU_SubmitGxCommand(gxbuf, gxCommand, NULL); 26 | } 27 | 28 | Result GX_SetCommandList_Last(u32* gxbuf, u32* buf0a, u32 buf0s, u8 flags) 29 | { 30 | if(!gxbuf)gxbuf=gxCmdBuf; 31 | 32 | u32 gxCommand[0x8]; 33 | gxCommand[0]=0x01; //CommandID 34 | gxCommand[1]=(u32)buf0a; //buf0 address 35 | gxCommand[2]=(u32)buf0s; //buf0 size 36 | gxCommand[3]=flags&1; //written to GSP module state 37 | gxCommand[4]=gxCommand[5]=gxCommand[6]=0x0; 38 | gxCommand[7]=(flags>>1)&1; //when non-zero, call svcFlushProcessDataCache() with the specified buffer 39 | 40 | return GSPGPU_SubmitGxCommand(gxbuf, gxCommand, NULL); 41 | } 42 | 43 | Result GX_SetMemoryFill(u32* gxbuf, u32* buf0a, u32 buf0v, u32* buf0e, u16 control0, u32* buf1a, u32 buf1v, u32* buf1e, u16 control1) 44 | { 45 | if(!gxbuf)gxbuf=gxCmdBuf; 46 | 47 | u32 gxCommand[0x8]; 48 | // gxCommand[0]=0x02; //CommandID 49 | gxCommand[0]=0x01000102; //CommandID 50 | gxCommand[1]=(u32)buf0a; //buf0 address 51 | gxCommand[2]=buf0v; //buf0 value 52 | gxCommand[3]=(u32)buf0e; //buf0 end addr 53 | gxCommand[4]=(u32)buf1a; //buf1 address 54 | gxCommand[5]=buf1v; //buf1 value 55 | gxCommand[6]=(u32)buf1e; //buf1 end addr 56 | gxCommand[7]=(control0)|(control1<<16); 57 | 58 | return GSPGPU_SubmitGxCommand(gxbuf, gxCommand, NULL); 59 | } 60 | 61 | // Flags, for applications this is 0x1001000 for the main screen, and 0x1000 for the sub screen. 62 | Result GX_SetDisplayTransfer(u32* gxbuf, u32* inadr, u32 indim, u32* outadr, u32 outdim, u32 flags) 63 | { 64 | if(!gxbuf)gxbuf=gxCmdBuf; 65 | 66 | u32 gxCommand[0x8]; 67 | gxCommand[0]=0x03; //CommandID 68 | gxCommand[1]=(u32)inadr; 69 | gxCommand[2]=(u32)outadr; 70 | gxCommand[3]=indim; 71 | gxCommand[4]=outdim; 72 | gxCommand[5]=flags; 73 | gxCommand[6]=gxCommand[7]=0x0; 74 | 75 | return GSPGPU_SubmitGxCommand(gxbuf, gxCommand, NULL); 76 | } 77 | 78 | Result GX_SetTextureCopy(u32* gxbuf, u32* inadr, u32 indim, u32* outadr, u32 outdim, u32 size, u32 flags) 79 | { 80 | if(!gxbuf)gxbuf=gxCmdBuf; 81 | 82 | u32 gxCommand[0x8]; 83 | gxCommand[0]=0x04; //CommandID 84 | gxCommand[1]=(u32)inadr; 85 | gxCommand[2]=(u32)outadr; 86 | gxCommand[3]=size; 87 | gxCommand[4]=indim; 88 | gxCommand[5]=outdim; 89 | gxCommand[6]=flags; 90 | gxCommand[7]=0x0; 91 | 92 | return GSPGPU_SubmitGxCommand(gxbuf, gxCommand, NULL); 93 | } 94 | 95 | Result GX_SetCommandList_First(u32* gxbuf, u32* buf0a, u32 buf0s, u32* buf1a, u32 buf1s, u32* buf2a, u32 buf2s) 96 | { 97 | if(!gxbuf)gxbuf=gxCmdBuf; 98 | 99 | u32 gxCommand[0x8]; 100 | gxCommand[0]=0x05; //CommandID 101 | gxCommand[1]=(u32)buf0a; //buf0 address 102 | gxCommand[2]=(u32)buf0s; //buf0 size 103 | gxCommand[3]=(u32)buf1a; //buf1 address 104 | gxCommand[4]=(u32)buf1s; //buf1 size 105 | gxCommand[5]=(u32)buf2a; //buf2 address 106 | gxCommand[6]=(u32)buf2s; //buf2 size 107 | gxCommand[7]=0x0; 108 | 109 | return GSPGPU_SubmitGxCommand(gxbuf, gxCommand, NULL); 110 | } 111 | -------------------------------------------------------------------------------- /libctru/source/services/hb.c: -------------------------------------------------------------------------------- 1 | #include <3ds/types.h> 2 | #include <3ds/result.h> 3 | #include <3ds/svc.h> 4 | #include <3ds/srv.h> 5 | #include <3ds/synchronization.h> 6 | #include <3ds/services/hb.h> 7 | #include <3ds/ipc.h> 8 | 9 | static Handle hbHandle; 10 | static int hbRefCount; 11 | 12 | Result hbInit(void) 13 | { 14 | Result res=0; 15 | if (AtomicPostIncrement(&hbRefCount)) return 0; 16 | res = srvGetServiceHandle(&hbHandle, "hb:HB"); 17 | if (R_FAILED(res)) AtomicDecrement(&hbRefCount); 18 | return res; 19 | } 20 | 21 | void hbExit(void) 22 | { 23 | if (AtomicDecrement(&hbRefCount)) return; 24 | svcCloseHandle(hbHandle); 25 | } 26 | 27 | Result HB_FlushInvalidateCache(void) 28 | { 29 | Result ret = 0; 30 | u32 *cmdbuf = getThreadCommandBuffer(); 31 | 32 | cmdbuf[0] = IPC_MakeHeader(0x1,1,2); // 0x10042 33 | cmdbuf[1] = 0x00000000; 34 | cmdbuf[2] = IPC_Desc_SharedHandles(1); 35 | cmdbuf[3] = CUR_PROCESS_HANDLE; 36 | 37 | if(R_FAILED(ret = svcSendSyncRequest(hbHandle))) return ret; 38 | 39 | return (Result)cmdbuf[1]; 40 | } 41 | 42 | Result HB_GetBootloaderAddresses(void** load3dsx, void** setArgv) 43 | { 44 | Result ret = 0; 45 | u32 *cmdbuf = getThreadCommandBuffer(); 46 | 47 | cmdbuf[0] = IPC_MakeHeader(0x6,0,0); // 0x60000 48 | 49 | if(R_FAILED(ret = svcSendSyncRequest(hbHandle))) return ret; 50 | 51 | if(load3dsx)*load3dsx=(void*)cmdbuf[2]; 52 | if(setArgv)*setArgv=(void*)cmdbuf[3]; 53 | 54 | return (Result)cmdbuf[1]; 55 | } 56 | 57 | Result HB_ReprotectMemory(u32* addr, u32 pages, u32 mode, u32* reprotectedPages) 58 | { 59 | Result ret = 0; 60 | u32 *cmdbuf = getThreadCommandBuffer(); 61 | 62 | cmdbuf[0] = IPC_MakeHeader(0x9,3,0); // 0x900C0 63 | cmdbuf[1] = (u32)addr; 64 | cmdbuf[2] = pages; 65 | cmdbuf[3] = mode; 66 | 67 | if(R_FAILED(ret = svcSendSyncRequest(hbHandle))) return ret; 68 | 69 | if(reprotectedPages) 70 | { 71 | if(R_SUCCEEDED(ret))*reprotectedPages=(u32)cmdbuf[2]; 72 | else *reprotectedPages=0; 73 | } 74 | 75 | return (Result)cmdbuf[1]; 76 | } 77 | -------------------------------------------------------------------------------- /libctru/source/services/news.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/result.h> 4 | #include <3ds/os.h> 5 | #include <3ds/svc.h> 6 | #include <3ds/srv.h> 7 | #include <3ds/synchronization.h> 8 | #include <3ds/services/news.h> 9 | #include <3ds/ipc.h> 10 | 11 | typedef struct { 12 | bool dataSet; 13 | bool unread; 14 | bool enableJPEG; 15 | u8 unkFlag1; 16 | u8 unkFlag2; 17 | u64 processID; 18 | u8 unkData[24]; 19 | u64 time; 20 | u16 title[32]; 21 | } NotificationHeader; 22 | 23 | static Handle newsHandle; 24 | static int newsRefCount; 25 | static bool useNewsS; 26 | 27 | Result newsInit(void) { 28 | Result res; 29 | if (AtomicPostIncrement(&newsRefCount)) return 0; 30 | res = srvGetServiceHandle(&newsHandle, "news:u"); 31 | useNewsS = R_FAILED(res); 32 | if (useNewsS) res = srvGetServiceHandle(&newsHandle, "news:s"); 33 | if (R_FAILED(res)) AtomicDecrement(&newsRefCount); 34 | return res; 35 | } 36 | 37 | void newsExit(void) { 38 | if (AtomicDecrement(&newsRefCount)) return; 39 | svcCloseHandle(newsHandle); 40 | } 41 | 42 | Result NEWS_AddNotification(const u16* title, u32 titleLength, const u16* message, u32 messageLength, const void* imageData, u32 imageSize, bool jpeg) 43 | { 44 | NotificationHeader header = { 0 }; 45 | header.dataSet = true; 46 | header.unread = true; 47 | header.enableJPEG = jpeg; 48 | header.processID = 0; // Filled automatically from FS:GetProgramLaunchInfo 49 | header.time = osGetTime(); 50 | memcpy(header.title, title, (titleLength < 32 ? titleLength + 1 : 32) * sizeof(u16)); 51 | 52 | Result ret = 0; 53 | u32 *cmdbuf = getThreadCommandBuffer(); 54 | 55 | cmdbuf[0] = IPC_MakeHeader(0x1,3,8); // 0x100C8 56 | cmdbuf[1] = sizeof(NotificationHeader); 57 | cmdbuf[2] = (messageLength + 1) * sizeof(u16); 58 | cmdbuf[3] = imageSize; 59 | 60 | u32 baseIndex = 4; 61 | if (!useNewsS) { 62 | cmdbuf[baseIndex] = IPC_Desc_CurProcessHandle(); 63 | cmdbuf[baseIndex + 1] = 0; // Process ID, Filled automatically by the ARM11 kernel. 64 | baseIndex += 2; 65 | } 66 | 67 | cmdbuf[baseIndex] = IPC_Desc_Buffer(sizeof(NotificationHeader),IPC_BUFFER_R); 68 | cmdbuf[baseIndex + 1] = (u32) &header; 69 | cmdbuf[baseIndex + 2] = IPC_Desc_Buffer((messageLength + 1) * sizeof(u16),IPC_BUFFER_R); 70 | cmdbuf[baseIndex + 3] = (u32) message; 71 | cmdbuf[baseIndex + 4] = IPC_Desc_Buffer(imageSize,IPC_BUFFER_R); 72 | cmdbuf[baseIndex + 5] = (u32) imageData; 73 | 74 | if(R_FAILED(ret = svcSendSyncRequest(newsHandle))) return ret; 75 | 76 | return (Result)cmdbuf[1]; 77 | } 78 | -------------------------------------------------------------------------------- /libctru/source/services/ns.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/result.h> 4 | #include <3ds/svc.h> 5 | #include <3ds/srv.h> 6 | #include <3ds/synchronization.h> 7 | #include <3ds/services/ns.h> 8 | #include <3ds/ipc.h> 9 | 10 | static Handle nsHandle; 11 | static int nsRefCount; 12 | 13 | Result nsInit(void) 14 | { 15 | Result res; 16 | if (AtomicPostIncrement(&nsRefCount)) return 0; 17 | res = srvGetServiceHandle(&nsHandle, "ns:s"); 18 | if (R_FAILED(res)) AtomicDecrement(&nsRefCount); 19 | return res; 20 | } 21 | 22 | void nsExit(void) 23 | { 24 | if (AtomicDecrement(&nsRefCount)) return; 25 | svcCloseHandle(nsHandle); 26 | } 27 | 28 | Result NS_LaunchTitle(u64 titleid, u32 launch_flags, u32 *procid) 29 | { 30 | Result ret = 0; 31 | u32 *cmdbuf = getThreadCommandBuffer(); 32 | 33 | cmdbuf[0] = IPC_MakeHeader(0x2,3,0); // 0x200C0 34 | cmdbuf[1] = titleid & 0xffffffff; 35 | cmdbuf[2] = (titleid >> 32) & 0xffffffff; 36 | cmdbuf[3] = launch_flags; 37 | 38 | if(R_FAILED(ret = svcSendSyncRequest(nsHandle)))return ret; 39 | 40 | if(procid != NULL) *procid = cmdbuf[2]; 41 | 42 | return (Result)cmdbuf[1]; 43 | } 44 | 45 | Result NS_RebootToTitle(u8 mediatype, u64 titleid) 46 | { 47 | Result ret = 0; 48 | u32 *cmdbuf = getThreadCommandBuffer(); 49 | 50 | cmdbuf[0] = IPC_MakeHeader(0x10,6,0); // 0x100180 51 | cmdbuf[1] = 0x1; 52 | cmdbuf[2] = titleid & 0xffffffff; 53 | cmdbuf[3] = (titleid >> 32) & 0xffffffff; 54 | cmdbuf[4] = mediatype; 55 | cmdbuf[5] = 0x0; // reserved 56 | cmdbuf[6] = 0x0; 57 | 58 | if(R_FAILED(ret = svcSendSyncRequest(nsHandle)))return ret; 59 | 60 | return (Result)cmdbuf[1]; 61 | } 62 | -------------------------------------------------------------------------------- /libctru/source/services/pm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds/types.h> 4 | #include <3ds/result.h> 5 | #include <3ds/svc.h> 6 | #include <3ds/srv.h> 7 | #include <3ds/synchronization.h> 8 | #include <3ds/services/pm.h> 9 | #include <3ds/ipc.h> 10 | 11 | static Handle pmHandle; 12 | static int pmRefCount; 13 | 14 | Result pmInit(void) 15 | { 16 | Result res; 17 | if (AtomicPostIncrement(&pmRefCount)) return 0; 18 | res = srvGetServiceHandle(&pmHandle, "pm:app"); 19 | if (R_FAILED(res)) AtomicDecrement(&pmRefCount); 20 | return res; 21 | } 22 | 23 | void pmExit(void) 24 | { 25 | if (AtomicDecrement(&pmRefCount)) return; 26 | svcCloseHandle(pmHandle); 27 | } 28 | 29 | Result PM_LaunchTitle(u8 mediatype, u64 titleid, u32 launch_flags) 30 | { 31 | Result ret = 0; 32 | u32 *cmdbuf = getThreadCommandBuffer(); 33 | 34 | cmdbuf[0] = IPC_MakeHeader(0x1,5,0); // 0x10140 35 | cmdbuf[1] = titleid & 0xffffffff; 36 | cmdbuf[2] = (titleid >> 32) & 0xffffffff; 37 | cmdbuf[3] = mediatype; 38 | cmdbuf[4] = 0x0; 39 | cmdbuf[5] = launch_flags; 40 | 41 | if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret; 42 | 43 | return (Result)cmdbuf[1]; 44 | } 45 | 46 | Result PM_GetTitleExheaderFlags(u8 mediatype, u64 titleid, u8* out) 47 | { 48 | Result ret = 0; 49 | u32 *cmdbuf = getThreadCommandBuffer(); 50 | 51 | cmdbuf[0] = IPC_MakeHeader(0x8,4,0); // 0x80100 52 | cmdbuf[1] = titleid & 0xffffffff; 53 | cmdbuf[2] = (titleid >> 32) & 0xffffffff; 54 | cmdbuf[3] = mediatype; 55 | cmdbuf[4] = 0x0; 56 | 57 | if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret; 58 | 59 | memcpy(out, (u8*)(&cmdbuf[2]), 8); 60 | 61 | return (Result)cmdbuf[1]; 62 | } 63 | 64 | Result PM_SetFIRMLaunchParams(u32 size, u8* in) 65 | { 66 | Result ret = 0; 67 | u32 *cmdbuf = getThreadCommandBuffer(); 68 | 69 | cmdbuf[0] = IPC_MakeHeader(0x9,1,2); // 0x90042 70 | cmdbuf[1] = size; 71 | cmdbuf[2] = IPC_Desc_Buffer(size,IPC_BUFFER_R); 72 | cmdbuf[3] = (u32)in; 73 | 74 | if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret; 75 | 76 | return (Result)cmdbuf[1]; 77 | } 78 | 79 | Result PM_GetFIRMLaunchParams(u32 size, u8* out) 80 | { 81 | Result ret = 0; 82 | u32 *cmdbuf = getThreadCommandBuffer(); 83 | 84 | cmdbuf[0] = IPC_MakeHeader(0x7,1,2); // 0x70042 85 | cmdbuf[1] = size; 86 | cmdbuf[2] = IPC_Desc_Buffer(size,IPC_BUFFER_W); 87 | cmdbuf[3] = (u32)out; 88 | 89 | if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret; 90 | 91 | return (Result)cmdbuf[1]; 92 | } 93 | 94 | Result PM_LaunchFIRMSetParams(u32 firm_titleid_low, u32 size, u8* in) 95 | { 96 | Result ret = 0; 97 | u32 *cmdbuf = getThreadCommandBuffer(); 98 | 99 | cmdbuf[0] = IPC_MakeHeader(0x2,2,2); // 0x20082 100 | cmdbuf[1] = firm_titleid_low; 101 | cmdbuf[2] = size; 102 | cmdbuf[3] = IPC_Desc_Buffer(size,IPC_BUFFER_R); 103 | cmdbuf[4] = (u32)in; 104 | 105 | if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret; 106 | 107 | return (Result)cmdbuf[1]; 108 | } -------------------------------------------------------------------------------- /libctru/source/services/ps.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/result.h> 4 | #include <3ds/svc.h> 5 | #include <3ds/srv.h> 6 | #include <3ds/synchronization.h> 7 | #include <3ds/services/ps.h> 8 | #include <3ds/ipc.h> 9 | 10 | static Handle psHandle; 11 | static int psRefCount; 12 | 13 | Result psInit(void) 14 | { 15 | Result res; 16 | if (AtomicPostIncrement(&psRefCount)) return 0; 17 | res = srvGetServiceHandle(&psHandle, "ps:ps"); 18 | if (R_FAILED(res)) AtomicDecrement(&psRefCount); 19 | return res; 20 | } 21 | 22 | void psExit(void) 23 | { 24 | if (AtomicDecrement(&psRefCount)) return; 25 | svcCloseHandle(psHandle); 26 | } 27 | 28 | Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, PS_AESAlgorithm aes_algo, PS_AESKeyType key_type, u8* iv) 29 | { 30 | Result ret = 0; 31 | u32 *cmdbuf = getThreadCommandBuffer(); 32 | 33 | u32 *_iv = (u32*)iv; 34 | 35 | cmdbuf[0] = IPC_MakeHeader(0x4,7,4); // 0x401C4 36 | cmdbuf[1] = size; 37 | cmdbuf[2] = _iv[0]; 38 | cmdbuf[3] = _iv[1]; 39 | cmdbuf[4] = _iv[2]; 40 | cmdbuf[5] = _iv[3]; 41 | cmdbuf[6] = aes_algo; 42 | cmdbuf[7] = key_type; 43 | cmdbuf[8] = IPC_Desc_PXIBuffer(size,0,false); 44 | cmdbuf[9] = (u32)in; 45 | cmdbuf[10] = IPC_Desc_PXIBuffer(size,1,false); 46 | cmdbuf[11] = (u32)out; 47 | 48 | if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret; 49 | 50 | _iv[0] = cmdbuf[2] & 0xFF; 51 | _iv[1] = cmdbuf[3] & 0xFF; 52 | _iv[2] = cmdbuf[4] & 0xFF; 53 | _iv[3] = cmdbuf[5] & 0xFF; 54 | 55 | return (Result)cmdbuf[1]; 56 | } 57 | 58 | Result PS_EncryptSignDecryptVerifyAesCcm(u8* in, u32 in_size, u8* out, u32 out_size, u32 data_len, u32 mac_data_len, u32 mac_len, PS_AESAlgorithm aes_algo, PS_AESKeyType key_type, u8* nonce) 59 | { 60 | Result ret = 0; 61 | u32 *cmdbuf = getThreadCommandBuffer(); 62 | 63 | u32 *_nonce = (u32*)nonce; 64 | 65 | cmdbuf[0] = IPC_MakeHeader(0x5,10,4); // 0x50284 66 | cmdbuf[1] = in_size; 67 | cmdbuf[2] = out_size; 68 | cmdbuf[3] = mac_data_len; 69 | cmdbuf[4] = data_len; 70 | cmdbuf[5] = mac_len; 71 | cmdbuf[6] = _nonce[0]; 72 | cmdbuf[7] = _nonce[1]; 73 | cmdbuf[8] = _nonce[2]; 74 | cmdbuf[9] = aes_algo; 75 | cmdbuf[10] = key_type; 76 | cmdbuf[8] = IPC_Desc_PXIBuffer(in_size,0,false); 77 | cmdbuf[9] = (u32)in; 78 | cmdbuf[10] = IPC_Desc_PXIBuffer(out_size,1,false); 79 | cmdbuf[11] = (u32)out; 80 | 81 | if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret; 82 | 83 | return (Result)cmdbuf[1]; 84 | } 85 | 86 | Result PS_GetLocalFriendCodeSeed(u64* seed) 87 | { 88 | Result ret = 0; 89 | u32 *cmdbuf = getThreadCommandBuffer(); 90 | 91 | cmdbuf[0] = IPC_MakeHeader(0xA,0,0); // 0xA0000 92 | 93 | if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret; 94 | 95 | *seed = (u64)cmdbuf[2] | (u64)cmdbuf[3] << 32; 96 | 97 | return (Result)cmdbuf[1]; 98 | } 99 | 100 | Result PS_GetDeviceId(u32* device_id) 101 | { 102 | Result ret = 0; 103 | u32 *cmdbuf = getThreadCommandBuffer(); 104 | 105 | cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000 106 | 107 | if(R_FAILED(ret = svcSendSyncRequest(psHandle)))return ret; 108 | 109 | *device_id = cmdbuf[2]; 110 | 111 | return (Result)cmdbuf[1]; 112 | } 113 | -------------------------------------------------------------------------------- /libctru/source/services/ptm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/svc.h> 4 | #include <3ds/srv.h> 5 | #include <3ds/services/ptm.h> 6 | 7 | 8 | static Handle ptmHandle, ptmSysmHandle; 9 | 10 | Result ptmInit() 11 | { 12 | return srvGetServiceHandle(&ptmHandle, "ptm:u"); 13 | } 14 | 15 | Result ptmExit() 16 | { 17 | return svcCloseHandle(ptmHandle); 18 | } 19 | 20 | Result ptmSysmInit(void) 21 | { 22 | return srvGetServiceHandle(&ptmSysmHandle, "ptm:sysm"); 23 | } 24 | 25 | Result ptmSysmExit(void) 26 | { 27 | return svcCloseHandle(ptmSysmHandle); 28 | } 29 | 30 | Result PTMU_GetShellState(Handle* servhandle, u8 *out) 31 | { 32 | if(!servhandle)servhandle=&ptmHandle; 33 | Result ret=0; 34 | u32 *cmdbuf = getThreadCommandBuffer(); 35 | 36 | cmdbuf[0] = 0x00060000; 37 | 38 | if((ret = svcSendSyncRequest(*servhandle))!=0)return ret; 39 | 40 | *out = (u8)cmdbuf[2]; 41 | 42 | return (Result)cmdbuf[1]; 43 | } 44 | 45 | Result PTMU_GetBatteryLevel(Handle* servhandle, u8 *out) 46 | { 47 | if(!servhandle)servhandle=&ptmHandle; 48 | Result ret=0; 49 | u32 *cmdbuf = getThreadCommandBuffer(); 50 | 51 | cmdbuf[0] = 0x00070000; 52 | 53 | if((ret = svcSendSyncRequest(*servhandle))!=0)return ret; 54 | 55 | *out = (u8)cmdbuf[2]; 56 | 57 | return (Result)cmdbuf[1]; 58 | } 59 | 60 | Result PTMU_GetBatteryChargeState(Handle* servhandle, u8 *out) 61 | { 62 | if(!servhandle)servhandle=&ptmHandle; 63 | Result ret=0; 64 | u32 *cmdbuf = getThreadCommandBuffer(); 65 | 66 | cmdbuf[0] = 0x00080000; 67 | 68 | if((ret = svcSendSyncRequest(*servhandle))!=0)return ret; 69 | 70 | *out = (u8)cmdbuf[2]; 71 | 72 | return (Result)cmdbuf[1]; 73 | } 74 | 75 | Result PTMU_GetPedometerState(Handle* servhandle, u8 *out) 76 | { 77 | if(!servhandle)servhandle=&ptmHandle; 78 | Result ret=0; 79 | u32 *cmdbuf = getThreadCommandBuffer(); 80 | 81 | cmdbuf[0] = 0x00090000; 82 | 83 | if((ret = svcSendSyncRequest(*servhandle))!=0)return ret; 84 | 85 | *out = (u8)cmdbuf[2]; 86 | 87 | return (Result)cmdbuf[1]; 88 | } 89 | 90 | Result PTMU_GetTotalStepCount(Handle* servhandle, u32 *steps) 91 | { 92 | if(!servhandle)servhandle=&ptmHandle; 93 | Result ret=0; 94 | u32 *cmdbuf = getThreadCommandBuffer(); 95 | 96 | cmdbuf[0] = 0x000C0000; 97 | 98 | if((ret = svcSendSyncRequest(*servhandle))!=0)return ret; 99 | 100 | *steps = cmdbuf[2]; 101 | 102 | return (Result)cmdbuf[1]; 103 | } 104 | 105 | Result PTMSYSM_ConfigureNew3DSCPU(u8 value) 106 | { 107 | Result ret; 108 | u32 *cmdbuf = getThreadCommandBuffer(); 109 | 110 | cmdbuf[0] = 0x08180040; 111 | cmdbuf[1] = value; 112 | 113 | if((ret = svcSendSyncRequest(ptmSysmHandle))!=0)return ret; 114 | 115 | return (Result)cmdbuf[1]; 116 | } 117 | -------------------------------------------------------------------------------- /libctru/source/services/ptmsysm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/result.h> 4 | #include <3ds/svc.h> 5 | #include <3ds/srv.h> 6 | #include <3ds/synchronization.h> 7 | #include <3ds/services/ptmsysm.h> 8 | #include <3ds/ipc.h> 9 | 10 | static Handle ptmSysmHandle; 11 | static int ptmSysmRefCount; 12 | 13 | Result ptmSysmInit(void) 14 | { 15 | if (AtomicPostIncrement(&ptmSysmRefCount)) return 0; 16 | Result res = srvGetServiceHandle(&ptmSysmHandle, "ptm:sysm"); 17 | if (R_FAILED(res)) AtomicDecrement(&ptmSysmRefCount); 18 | return res; 19 | } 20 | 21 | void ptmSysmExit(void) 22 | { 23 | if (AtomicDecrement(&ptmSysmRefCount)) return; 24 | svcCloseHandle(ptmSysmHandle); 25 | } 26 | 27 | Result PTMSYSM_ConfigureNew3DSCPU(u8 value) 28 | { 29 | Result ret; 30 | u32 *cmdbuf = getThreadCommandBuffer(); 31 | 32 | cmdbuf[0] = IPC_MakeHeader(0x818,1,0); // 0x08180040 33 | cmdbuf[1] = value; 34 | 35 | if(R_FAILED(ret = svcSendSyncRequest(ptmSysmHandle)))return ret; 36 | 37 | return (Result)cmdbuf[1]; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /libctru/source/services/ptmu.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/result.h> 4 | #include <3ds/svc.h> 5 | #include <3ds/srv.h> 6 | #include <3ds/synchronization.h> 7 | #include <3ds/services/ptmu.h> 8 | #include <3ds/ipc.h> 9 | 10 | static Handle ptmuHandle; 11 | static int ptmuRefCount; 12 | 13 | Result ptmuInit(void) 14 | { 15 | if (AtomicPostIncrement(&ptmuRefCount)) return 0; 16 | Result res = srvGetServiceHandle(&ptmuHandle, "ptm:u"); 17 | if (R_FAILED(res)) AtomicDecrement(&ptmuRefCount); 18 | return res; 19 | } 20 | 21 | void ptmuExit(void) 22 | { 23 | if (AtomicDecrement(&ptmuRefCount)) return; 24 | svcCloseHandle(ptmuHandle); 25 | } 26 | 27 | Result PTMU_GetShellState(u8 *out) 28 | { 29 | Result ret=0; 30 | u32 *cmdbuf = getThreadCommandBuffer(); 31 | 32 | cmdbuf[0] = IPC_MakeHeader(0x6,0,0); // 0x60000 33 | 34 | if(R_FAILED(ret = svcSendSyncRequest(ptmuHandle)))return ret; 35 | 36 | *out = (u8)cmdbuf[2] & 0xFF; 37 | 38 | return (Result)cmdbuf[1]; 39 | } 40 | 41 | Result PTMU_GetBatteryLevel(u8 *out) 42 | { 43 | Result ret=0; 44 | u32 *cmdbuf = getThreadCommandBuffer(); 45 | 46 | cmdbuf[0] = IPC_MakeHeader(0x7,0,0); // 0x70000 47 | 48 | if(R_FAILED(ret = svcSendSyncRequest(ptmuHandle)))return ret; 49 | 50 | *out = (u8)cmdbuf[2] & 0xFF; 51 | 52 | return (Result)cmdbuf[1]; 53 | } 54 | 55 | Result PTMU_GetBatteryChargeState(u8 *out) 56 | { 57 | Result ret=0; 58 | u32 *cmdbuf = getThreadCommandBuffer(); 59 | 60 | cmdbuf[0] = IPC_MakeHeader(0x8,0,0); // 0x80000 61 | 62 | if(R_FAILED(ret = svcSendSyncRequest(ptmuHandle)))return ret; 63 | 64 | *out = (u8)cmdbuf[2] & 0xFF; 65 | 66 | return (Result)cmdbuf[1]; 67 | } 68 | 69 | Result PTMU_GetPedometerState(u8 *out) 70 | { 71 | Result ret=0; 72 | u32 *cmdbuf = getThreadCommandBuffer(); 73 | 74 | cmdbuf[0] = IPC_MakeHeader(0x9,0,0); // 0x90000 75 | 76 | if(R_FAILED(ret = svcSendSyncRequest(ptmuHandle)))return ret; 77 | 78 | *out = (u8)cmdbuf[2] & 0xFF; 79 | 80 | return (Result)cmdbuf[1]; 81 | } 82 | 83 | Result PTMU_GetTotalStepCount(u32 *steps) 84 | { 85 | Result ret=0; 86 | u32 *cmdbuf = getThreadCommandBuffer(); 87 | 88 | cmdbuf[0] = IPC_MakeHeader(0xC,0,0); // 0xC0000 89 | 90 | if(R_FAILED(ret = svcSendSyncRequest(ptmuHandle)))return ret; 91 | 92 | *steps = cmdbuf[2]; 93 | 94 | return (Result)cmdbuf[1]; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /libctru/source/services/qtm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <3ds/types.h> 4 | #include <3ds/result.h> 5 | #include <3ds/svc.h> 6 | #include <3ds/srv.h> 7 | #include <3ds/synchronization.h> 8 | #include <3ds/services/qtm.h> 9 | #include <3ds/ipc.h> 10 | 11 | Handle qtmHandle; 12 | static int qtmRefCount; 13 | 14 | Result qtmInit(void) 15 | { 16 | Result ret=0; 17 | 18 | if (AtomicPostIncrement(&qtmRefCount)) return 0; 19 | 20 | ret = srvGetServiceHandle(&qtmHandle, "qtm:u"); 21 | if (R_FAILED(ret)) ret = srvGetServiceHandle(&qtmHandle, "qtm:s"); 22 | if (R_FAILED(ret)) ret = srvGetServiceHandle(&qtmHandle, "qtm:sp"); 23 | if (R_FAILED(ret)) AtomicDecrement(&qtmRefCount); 24 | return ret; 25 | } 26 | 27 | void qtmExit(void) 28 | { 29 | if (AtomicDecrement(&qtmRefCount)) return; 30 | svcCloseHandle(qtmHandle); 31 | } 32 | 33 | bool qtmCheckInitialized(void) 34 | { 35 | return qtmRefCount>0; 36 | } 37 | 38 | bool qtmCheckHeadFullyDetected(QTM_HeadTrackingInfo *info) 39 | { 40 | if(info==NULL)return false; 41 | 42 | if(info->flags[0] && info->flags[1] && info->flags[2])return true; 43 | return false; 44 | } 45 | 46 | Result qtmConvertCoordToScreen(QTM_HeadTrackingInfoCoord *coord, float *screen_width, float *screen_height, u32 *x, u32 *y) 47 | { 48 | float width = 200.0f; 49 | float height = 160.0f; 50 | 51 | if(coord==NULL || x==NULL || y==NULL)return -1; 52 | 53 | if(screen_width)width = (*screen_width) / 2; 54 | if(screen_height)height = (*screen_height) / 2; 55 | 56 | if(coord->x > 1.0f || coord->x < -1.0f)return -2; 57 | if(coord->y > 1.0f || coord->y < -1.0f)return -2; 58 | 59 | *x = (u32)((coord->x * width) + width); 60 | *y = (u32)((coord->y * height) + height); 61 | 62 | return 0; 63 | } 64 | 65 | Result QTM_GetHeadTrackingInfo(u64 val, QTM_HeadTrackingInfo* out) 66 | { 67 | if(!qtmCheckInitialized())return -1; 68 | 69 | Result ret = 0; 70 | u32* cmdbuf = getThreadCommandBuffer(); 71 | 72 | cmdbuf[0] = IPC_MakeHeader(0x2,2,0); // 0x20080 73 | cmdbuf[1] = val&0xFFFFFFFF; 74 | cmdbuf[2] = val>>32; 75 | 76 | if(R_FAILED(ret=svcSendSyncRequest(qtmHandle)))return ret; 77 | 78 | if(out) memcpy(out, &cmdbuf[2], sizeof(QTM_HeadTrackingInfo)); 79 | 80 | return cmdbuf[1]; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_accept.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) 7 | { 8 | int ret = 0; 9 | int tmp_addrlen = 0x1c; 10 | int fd, dev; 11 | __handle *handle; 12 | u32 *cmdbuf = getThreadCommandBuffer(); 13 | u8 tmpaddr[0x1c]; 14 | u32 saved_threadstorage[2]; 15 | 16 | sockfd = soc_get_fd(sockfd); 17 | if(sockfd < 0) { 18 | errno = -sockfd; 19 | return -1; 20 | } 21 | 22 | dev = FindDevice("soc:"); 23 | if(dev < 0) { 24 | errno = ENODEV; 25 | return -1; 26 | } 27 | 28 | fd = __alloc_handle(sizeof(__handle) + sizeof(Handle)); 29 | if(fd < 0) { 30 | errno = ENOMEM; 31 | return -1; 32 | } 33 | 34 | handle = __get_handle(fd); 35 | handle->device = dev; 36 | handle->fileStruct = ((void *)handle) + sizeof(__handle); 37 | 38 | memset(tmpaddr, 0, 0x1c); 39 | 40 | cmdbuf[0] = IPC_MakeHeader(0x4,2,2); // 0x40082 41 | cmdbuf[1] = (u32)sockfd; 42 | cmdbuf[2] = (u32)tmp_addrlen; 43 | cmdbuf[3] = IPC_Desc_CurProcessHandle(); 44 | 45 | u32 * staticbufs = getThreadStaticBuffers(); 46 | saved_threadstorage[0] = staticbufs[0]; 47 | saved_threadstorage[1] = staticbufs[1]; 48 | 49 | staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0); 50 | staticbufs[1] = (u32)tmpaddr; 51 | 52 | ret = svcSendSyncRequest(SOCU_handle); 53 | if(ret != 0) { 54 | __release_handle(fd); 55 | errno = SYNC_ERROR; 56 | return ret; 57 | } 58 | 59 | staticbufs[0] = saved_threadstorage[0]; 60 | staticbufs[1] = saved_threadstorage[1]; 61 | 62 | ret = (int)cmdbuf[1]; 63 | if(ret == 0) 64 | ret = _net_convert_error(cmdbuf[2]); 65 | 66 | if(ret < 0) 67 | errno = -ret; 68 | 69 | if(ret >= 0 && addr != NULL) { 70 | addr->sa_family = tmpaddr[1]; 71 | if(*addrlen > tmpaddr[0]) 72 | *addrlen = tmpaddr[0]; 73 | memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2); 74 | } 75 | 76 | if(ret < 0) { 77 | __release_handle(fd); 78 | return -1; 79 | } 80 | else 81 | *(Handle*)handle->fileStruct = ret; 82 | 83 | return fd; 84 | } 85 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_bind.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) 7 | { 8 | int ret = 0; 9 | int tmp_addrlen = 0; 10 | u32 *cmdbuf = getThreadCommandBuffer(); 11 | u8 tmpaddr[0x1c]; 12 | 13 | sockfd = soc_get_fd(sockfd); 14 | if(sockfd < 0) { 15 | errno = -sockfd; 16 | return -1; 17 | } 18 | 19 | memset(tmpaddr, 0, 0x1c); 20 | 21 | if(addr->sa_family == AF_INET) 22 | tmp_addrlen = 8; 23 | else 24 | tmp_addrlen = 0x1c; 25 | 26 | if(addrlen < tmp_addrlen) { 27 | errno = EINVAL; 28 | return -1; 29 | } 30 | 31 | tmpaddr[0] = tmp_addrlen; 32 | tmpaddr[1] = addr->sa_family; 33 | memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2); 34 | 35 | cmdbuf[0] = IPC_MakeHeader(0x5,2,4); // 0x50084 36 | cmdbuf[1] = (u32)sockfd; 37 | cmdbuf[2] = (u32)tmp_addrlen; 38 | cmdbuf[3] = IPC_Desc_CurProcessHandle(); 39 | cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0); 40 | cmdbuf[6] = (u32)tmpaddr; 41 | 42 | ret = svcSendSyncRequest(SOCU_handle); 43 | if(ret != 0) { 44 | errno = SYNC_ERROR; 45 | return ret; 46 | } 47 | 48 | ret = (int)cmdbuf[1]; 49 | if(ret == 0) 50 | ret = _net_convert_error(cmdbuf[2]); 51 | 52 | if(ret < 0) { 53 | errno = -ret; 54 | return -1; 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_closesocket.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include 5 | 6 | int closesocket(int sockfd) 7 | { 8 | int fd = soc_get_fd(sockfd); 9 | if(fd < 0) { 10 | errno = -fd; 11 | return -1; 12 | } 13 | 14 | return close(sockfd); 15 | } 16 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_common.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | 5 | Handle SOCU_handle = 0; 6 | Handle socMemhandle = 0; 7 | int h_errno = 0; 8 | 9 | //This is based on the array from libogc network_wii.c. 10 | static u8 _net_error_code_map[] = { 11 | 0, // 0 12 | E2BIG, 13 | EACCES, 14 | EADDRINUSE, 15 | EADDRNOTAVAIL, 16 | EAFNOSUPPORT, // 5 17 | EAGAIN, 18 | EALREADY, 19 | EBADF, 20 | EBADMSG, 21 | EBUSY, // 10 22 | ECANCELED, 23 | ECHILD, 24 | ECONNABORTED, 25 | ECONNREFUSED, 26 | ECONNRESET, // 15 27 | EDEADLK, 28 | EDESTADDRREQ, 29 | EDOM, 30 | EDQUOT, 31 | EEXIST, // 20 32 | EFAULT, 33 | EFBIG, 34 | EHOSTUNREACH, 35 | EIDRM, 36 | EILSEQ, // 25 37 | EINPROGRESS, 38 | EINTR, 39 | EINVAL, 40 | EIO, 41 | EISCONN, // 30 42 | EISDIR, 43 | ELOOP, 44 | EMFILE, 45 | EMLINK, 46 | EMSGSIZE, // 35 47 | EMULTIHOP, 48 | ENAMETOOLONG, 49 | ENETDOWN, 50 | ENETRESET, 51 | ENETUNREACH, // 40 52 | ENFILE, 53 | ENOBUFS, 54 | ENODATA, 55 | ENODEV, 56 | ENOENT, // 45 57 | ENOEXEC, 58 | ENOLCK, 59 | ENOLINK, 60 | ENOMEM, 61 | ENOMSG, // 50 62 | ENOPROTOOPT, 63 | ENOSPC, 64 | ENOSR, 65 | ENOSTR, 66 | ENOSYS, // 55 67 | ENOTCONN, 68 | ENOTDIR, 69 | ENOTEMPTY, 70 | ENOTSOCK, 71 | ENOTSUP, // 60 72 | ENOTTY, 73 | ENXIO, 74 | EOPNOTSUPP, 75 | EOVERFLOW, 76 | EPERM, // 65 77 | EPIPE, 78 | EPROTO, 79 | EPROTONOSUPPORT, 80 | EPROTOTYPE, 81 | ERANGE, // 70 82 | EROFS, 83 | ESPIPE, 84 | ESRCH, 85 | ESTALE, 86 | ETIME, // 75 87 | ETIMEDOUT, 88 | }; 89 | 90 | #define NET_UNKNOWN_ERROR_OFFSET -10000//This is from libogc network_wii.c. 91 | 92 | //This is based on the function from libogc network_wii.c. 93 | s32 _net_convert_error(s32 sock_retval) 94 | { 95 | if(sock_retval >= 0) 96 | return sock_retval; 97 | 98 | if(sock_retval < -sizeof(_net_error_code_map) 99 | || !_net_error_code_map[-sock_retval]) 100 | return NET_UNKNOWN_ERROR_OFFSET + sock_retval; 101 | return -_net_error_code_map[-sock_retval]; 102 | } 103 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include <3ds/types.h> 8 | #include <3ds/svc.h> 9 | #include <3ds/srv.h> 10 | #include <3ds/services/soc.h> 11 | 12 | #define SYNC_ERROR ENODEV 13 | 14 | int __alloc_handle(size_t size); 15 | __handle *__get_handle(int fd); 16 | void __release_handle(int fd); 17 | 18 | extern Handle SOCU_handle; 19 | extern Handle socMemhandle; 20 | 21 | static inline int 22 | soc_get_fd(int fd) 23 | { 24 | __handle *handle = __get_handle(fd); 25 | if(handle == NULL) 26 | return -ENODEV; 27 | if(strcmp(devoptab_list[handle->device]->name, "soc") != 0) 28 | return -ENOTSOCK; 29 | return *(Handle*)handle->fileStruct; 30 | } 31 | 32 | s32 _net_convert_error(s32 sock_retval); 33 | 34 | ssize_t soc_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); 35 | 36 | ssize_t soc_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); 37 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_connect.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) 7 | { 8 | int ret = 0; 9 | int tmp_addrlen = 0; 10 | u32 *cmdbuf = getThreadCommandBuffer(); 11 | u8 tmpaddr[0x1c]; 12 | 13 | sockfd = soc_get_fd(sockfd); 14 | if(sockfd < 0) { 15 | errno = -sockfd; 16 | return -1; 17 | } 18 | 19 | memset(tmpaddr, 0, 0x1c); 20 | 21 | if(addr->sa_family == AF_INET) 22 | tmp_addrlen = 8; 23 | else 24 | tmp_addrlen = 0x1c; 25 | 26 | if(addrlen < tmp_addrlen) { 27 | errno = EINVAL; 28 | return -1; 29 | } 30 | 31 | tmpaddr[0] = tmp_addrlen; 32 | tmpaddr[1] = addr->sa_family; 33 | memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2); 34 | 35 | cmdbuf[0] = IPC_MakeHeader(0x6,2,4); // 0x60084 36 | cmdbuf[1] = (u32)sockfd; 37 | cmdbuf[2] = (u32)addrlen; 38 | cmdbuf[3] = IPC_Desc_CurProcessHandle(); 39 | cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0); 40 | cmdbuf[6] = (u32)tmpaddr; 41 | 42 | ret = svcSendSyncRequest(SOCU_handle); 43 | if(ret != 0) { 44 | errno = SYNC_ERROR; 45 | return ret; 46 | } 47 | 48 | ret = (int)cmdbuf[1]; 49 | if(ret == 0) 50 | ret = _net_convert_error(cmdbuf[2]); 51 | 52 | if(ret < 0) { 53 | errno = -ret; 54 | return -1; 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_fcntl.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include 5 | #include <3ds/ipc.h> 6 | 7 | #define O_NONBLOCK_3DS 0x4 8 | 9 | #define ALL_3DS (O_NONBLOCK_3DS) 10 | #define ALL_FLAGS (O_NONBLOCK) 11 | 12 | static int from_3ds(int flags) 13 | { 14 | int newflags = 0; 15 | 16 | if(flags & O_NONBLOCK_3DS) 17 | newflags |= O_NONBLOCK; 18 | /* add other flag translations here, but I have only seen O_NONBLOCK */ 19 | 20 | return newflags; 21 | } 22 | 23 | static int to_3ds(int flags) 24 | { 25 | int newflags = 0; 26 | 27 | if(flags & O_NONBLOCK) 28 | newflags |= O_NONBLOCK_3DS; 29 | /* add other flag translations here, but I have only seen O_NONBLOCK */ 30 | 31 | return newflags; 32 | } 33 | 34 | int fcntl(int sockfd, int cmd, ...) 35 | { 36 | int ret = 0; 37 | int arg = 0; 38 | u32 *cmdbuf = getThreadCommandBuffer(); 39 | 40 | va_list args; 41 | 42 | sockfd = soc_get_fd(sockfd); 43 | if(sockfd < 0) { 44 | errno = -sockfd; 45 | return -1; 46 | } 47 | 48 | if(cmd != F_GETFL && cmd != F_SETFL) { 49 | errno = EINVAL; 50 | return -1; 51 | } 52 | 53 | if(cmd == F_SETFL) { 54 | va_start(args, cmd); 55 | arg = va_arg(args, int); 56 | va_end(args); 57 | 58 | /* make sure they only used known flags */ 59 | if(arg & ~ALL_FLAGS) { 60 | errno = EINVAL; 61 | return -1; 62 | } 63 | 64 | arg = to_3ds(arg); 65 | } 66 | 67 | cmdbuf[0] = IPC_MakeHeader(0x13,3,2); // 0x1300C2 68 | cmdbuf[1] = (u32)sockfd; 69 | cmdbuf[2] = (u32)cmd; 70 | cmdbuf[3] = (u32)arg; 71 | cmdbuf[4] = IPC_Desc_CurProcessHandle(); 72 | 73 | ret = svcSendSyncRequest(SOCU_handle); 74 | if(ret != 0) { 75 | errno = SYNC_ERROR; 76 | return ret; 77 | } 78 | 79 | ret = (int)cmdbuf[1]; 80 | if(ret == 0) 81 | ret = _net_convert_error(cmdbuf[2]); 82 | 83 | if(ret < 0) { 84 | errno = ret; 85 | return -1; 86 | } 87 | 88 | if(ret & ~ALL_3DS) { 89 | /* somehow report unknown flags */ 90 | } 91 | 92 | return from_3ds(ret); 93 | } 94 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_gethostbyaddr.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | 4 | #define MAX_HOSTENT_RESULTS 16 5 | static struct hostent SOC_hostent; 6 | static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1]; 7 | static char *SOC_hostent_alias = NULL; 8 | 9 | struct hostent* gethostbyaddr(const void *addr, socklen_t len, int type) 10 | { 11 | int ret = 0; 12 | u32 *cmdbuf = getThreadCommandBuffer(); 13 | u32 saved_threadstorage[2]; 14 | static u8 outbuf[0x1A88]; 15 | 16 | h_errno = 0; 17 | 18 | cmdbuf[0] = 0x000E00C2; 19 | cmdbuf[1] = len; 20 | cmdbuf[2] = type; 21 | cmdbuf[3] = sizeof(outbuf); 22 | cmdbuf[4] = (len << 14) | 0x1002; 23 | cmdbuf[5] = (u32)addr; 24 | 25 | saved_threadstorage[0] = cmdbuf[0x100>>2]; 26 | saved_threadstorage[1] = cmdbuf[0x104>>2]; 27 | 28 | cmdbuf[0x100>>2] = (sizeof(outbuf) << 14) | 2; 29 | cmdbuf[0x104>>2] = (u32)outbuf; 30 | 31 | ret = svcSendSyncRequest(SOCU_handle); 32 | if(ret != 0) { 33 | h_errno = NO_RECOVERY; 34 | return NULL; 35 | } 36 | 37 | 38 | cmdbuf[0x100>>2] = saved_threadstorage[0]; 39 | cmdbuf[0x104>>2] = saved_threadstorage[1]; 40 | 41 | ret = (int)cmdbuf[1]; 42 | if(ret == 0) 43 | ret = _net_convert_error(cmdbuf[2]); 44 | 45 | if(ret < 0) { 46 | /* TODO: set h_errno based on ret */ 47 | h_errno = HOST_NOT_FOUND; 48 | return NULL; 49 | } 50 | 51 | u32 num_results, i; 52 | memcpy(&num_results, (char*)outbuf+4, sizeof(num_results)); 53 | if(num_results > MAX_HOSTENT_RESULTS) 54 | num_results = MAX_HOSTENT_RESULTS; 55 | 56 | SOC_hostent.h_name = (char*)outbuf + 8; 57 | SOC_hostent.h_aliases = &SOC_hostent_alias; 58 | SOC_hostent.h_addrtype = AF_INET; 59 | SOC_hostent.h_length = 4; 60 | SOC_hostent.h_addr_list = SOC_hostent_results; 61 | 62 | SOC_hostent_alias = NULL; 63 | 64 | for(i = 0; i < num_results; ++i) 65 | SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10; 66 | SOC_hostent_results[num_results] = NULL; 67 | 68 | SOC_hostent.h_addr = SOC_hostent.h_addr_list[0]; 69 | 70 | return &SOC_hostent; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_gethostbyname.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include <3ds/ipc.h> 4 | 5 | #define MAX_HOSTENT_RESULTS 16 6 | static struct hostent SOC_hostent; 7 | static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1]; 8 | static char *SOC_hostent_alias = NULL; 9 | 10 | struct hostent* gethostbyname(const char *name) 11 | { 12 | int ret = 0; 13 | u32 *cmdbuf = getThreadCommandBuffer(); 14 | u32 saved_threadstorage[2]; 15 | static u8 outbuf[0x1A88]; 16 | 17 | h_errno = 0; 18 | 19 | cmdbuf[0] = IPC_MakeHeader(0xD,2,2); // 0xD0082 20 | cmdbuf[1] = strlen(name)+1; 21 | cmdbuf[2] = sizeof(outbuf); 22 | cmdbuf[3] = ((strlen(name)+1) << 14) | 0xC02; 23 | cmdbuf[4] = (u32)name; 24 | 25 | u32 * staticbufs = getThreadStaticBuffers(); 26 | saved_threadstorage[0] = staticbufs[0]; 27 | saved_threadstorage[1] = staticbufs[1]; 28 | 29 | staticbufs[0] = IPC_Desc_StaticBuffer(sizeof(outbuf),0); 30 | staticbufs[1] = (u32)outbuf; 31 | 32 | ret = svcSendSyncRequest(SOCU_handle); 33 | if(ret != 0) { 34 | h_errno = NO_RECOVERY; 35 | return NULL; 36 | } 37 | 38 | staticbufs[0] = saved_threadstorage[0]; 39 | staticbufs[1] = saved_threadstorage[1]; 40 | 41 | ret = (int)cmdbuf[1]; 42 | if(ret == 0) 43 | ret = _net_convert_error(cmdbuf[2]); 44 | 45 | if(ret < 0) { 46 | /* TODO: set h_errno based on ret */ 47 | h_errno = HOST_NOT_FOUND; 48 | return NULL; 49 | } 50 | 51 | u32 num_results, i; 52 | memcpy(&num_results, (char*)outbuf+4, sizeof(num_results)); 53 | if(num_results > MAX_HOSTENT_RESULTS) 54 | num_results = MAX_HOSTENT_RESULTS; 55 | 56 | SOC_hostent.h_name = (char*)outbuf + 8; 57 | SOC_hostent.h_aliases = &SOC_hostent_alias; 58 | SOC_hostent.h_addrtype = AF_INET; 59 | SOC_hostent.h_length = 4; 60 | SOC_hostent.h_addr_list = SOC_hostent_results; 61 | 62 | SOC_hostent_alias = NULL; 63 | 64 | for(i = 0; i < num_results; ++i) 65 | SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10; 66 | SOC_hostent_results[num_results] = NULL; 67 | 68 | SOC_hostent.h_addr = SOC_hostent.h_addr_list[0]; 69 | 70 | return &SOC_hostent; 71 | } 72 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_gethostid.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include <3ds/ipc.h> 4 | 5 | long gethostid(void) 6 | { 7 | int ret = 0; 8 | u32 *cmdbuf = getThreadCommandBuffer(); 9 | 10 | cmdbuf[0] = IPC_MakeHeader(0x16,0,0); // 0x160000 11 | 12 | ret = svcSendSyncRequest(SOCU_handle); 13 | if(ret != 0) { 14 | errno = SYNC_ERROR; 15 | return -1; 16 | } 17 | 18 | ret = (int)cmdbuf[1]; 19 | if(ret == 0) 20 | ret = cmdbuf[2]; 21 | 22 | return ret; 23 | } 24 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_getpeername.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen) 7 | { 8 | int ret = 0; 9 | u32 *cmdbuf = getThreadCommandBuffer(); 10 | u32 saved_threadstorage[2]; 11 | u8 tmpaddr[0x1c]; 12 | 13 | sockfd = soc_get_fd(sockfd); 14 | if(sockfd < 0) { 15 | errno = -sockfd; 16 | return -1; 17 | } 18 | 19 | cmdbuf[0] = IPC_MakeHeader(0x18,2,2); // 0x180082 20 | cmdbuf[1] = (u32)sockfd; 21 | cmdbuf[2] = 0x1c; 22 | cmdbuf[3] = IPC_Desc_CurProcessHandle(); 23 | 24 | u32 * staticbufs = getThreadStaticBuffers(); 25 | saved_threadstorage[0] = staticbufs[0]; 26 | saved_threadstorage[1] = staticbufs[1]; 27 | 28 | staticbufs[0] = IPC_Desc_StaticBuffer(0x1c,0); 29 | staticbufs[1] = (u32)tmpaddr; 30 | 31 | ret = svcSendSyncRequest(SOCU_handle); 32 | if(ret != 0) { 33 | errno = SYNC_ERROR; 34 | return ret; 35 | } 36 | 37 | staticbufs[0] = saved_threadstorage[0]; 38 | staticbufs[1] = saved_threadstorage[1]; 39 | 40 | ret = (int)cmdbuf[1]; 41 | if(ret == 0) 42 | ret = _net_convert_error(cmdbuf[2]); 43 | 44 | if(ret < 0) { 45 | errno = -ret; 46 | return -1; 47 | } 48 | 49 | if(*addrlen > tmpaddr[0]) 50 | *addrlen = tmpaddr[0]; 51 | memset(addr, 0, sizeof(struct sockaddr)); 52 | addr->sa_family = tmpaddr[1]; 53 | memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2); 54 | 55 | return ret; 56 | } 57 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_getsockname.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) 7 | { 8 | int ret = 0; 9 | u32 *cmdbuf = getThreadCommandBuffer(); 10 | u32 saved_threadstorage[2]; 11 | u8 tmpaddr[0x1c]; 12 | 13 | sockfd = soc_get_fd(sockfd); 14 | if(sockfd < 0) { 15 | errno = -sockfd; 16 | return -1; 17 | } 18 | 19 | cmdbuf[0] = IPC_MakeHeader(0x17,2,2); // 0x170082 20 | cmdbuf[1] = (u32)sockfd; 21 | cmdbuf[2] = 0x1c; 22 | cmdbuf[3] = IPC_Desc_CurProcessHandle(); 23 | 24 | u32 * staticbufs = getThreadStaticBuffers(); 25 | saved_threadstorage[0] = staticbufs[0]; 26 | saved_threadstorage[1] = staticbufs[1]; 27 | 28 | staticbufs[0] = IPC_Desc_StaticBuffer(0x1c,0); 29 | staticbufs[1] = (u32)tmpaddr; 30 | 31 | ret = svcSendSyncRequest(SOCU_handle); 32 | if(ret != 0) { 33 | errno = SYNC_ERROR; 34 | return ret; 35 | } 36 | 37 | staticbufs[0] = saved_threadstorage[0]; 38 | staticbufs[1] = saved_threadstorage[1]; 39 | 40 | ret = (int)cmdbuf[1]; 41 | if(ret == 0) 42 | ret = _net_convert_error(cmdbuf[2]); 43 | 44 | if(ret < 0) { 45 | errno = -ret; 46 | return -1; 47 | } 48 | 49 | if(*addrlen > tmpaddr[0]) 50 | *addrlen = tmpaddr[0]; 51 | memset(addr, 0, sizeof(struct sockaddr)); 52 | addr->sa_family = tmpaddr[1]; 53 | memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2); 54 | 55 | return ret; 56 | } 57 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_getsockopt.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) 7 | { 8 | int ret = 0; 9 | u32 *cmdbuf = getThreadCommandBuffer(); 10 | u32 saved_threadstorage[2]; 11 | 12 | sockfd = soc_get_fd(sockfd); 13 | if(sockfd < 0) { 14 | errno = -sockfd; 15 | return -1; 16 | } 17 | 18 | cmdbuf[0] = IPC_MakeHeader(0x11,4,2); // 0x110102 19 | cmdbuf[1] = (u32)sockfd; 20 | cmdbuf[2] = (u32)level; 21 | cmdbuf[3] = (u32)optname; 22 | cmdbuf[4] = (u32)*optlen; 23 | cmdbuf[5] = IPC_Desc_CurProcessHandle(); 24 | 25 | u32 * staticbufs = getThreadStaticBuffers(); 26 | saved_threadstorage[0] = staticbufs[0]; 27 | saved_threadstorage[1] = staticbufs[1]; 28 | 29 | staticbufs[0] = IPC_Desc_StaticBuffer(*optlen,0); 30 | staticbufs[1] = (u32)optval; 31 | 32 | ret = svcSendSyncRequest(SOCU_handle); 33 | if(ret != 0) { 34 | errno = SYNC_ERROR; 35 | return ret; 36 | } 37 | 38 | staticbufs[0] = saved_threadstorage[0]; 39 | staticbufs[1] = saved_threadstorage[1]; 40 | 41 | ret = (int)cmdbuf[1]; 42 | if(ret == 0) 43 | ret = _net_convert_error(cmdbuf[2]); 44 | 45 | if(ret < 0) { 46 | errno = -ret; 47 | return -1; 48 | } 49 | 50 | *optlen = cmdbuf[3]; 51 | 52 | return ret; 53 | } 54 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_herror.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | 5 | void herror(const char *s) { 6 | if(s) 7 | fiprintf(stderr, "%s\n", hstrerror(h_errno)); 8 | else 9 | fiprintf(stderr, "%s: %s\n", s, hstrerror(h_errno)); 10 | } 11 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_hstrerror.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | 4 | static const struct 5 | { 6 | int err; 7 | const char *str; 8 | } error_strings[] = 9 | { 10 | { 0, "Resolver Error 0 (no error)", }, 11 | { HOST_NOT_FOUND, "Unknown host", }, 12 | { NO_DATA, "No address associated with name", }, 13 | { NO_RECOVERY, "Unknown server error", }, 14 | { TRY_AGAIN, "Host name lookup failure", }, 15 | }; 16 | static const size_t num_error_strings = sizeof(error_strings)/sizeof(error_strings[0]); 17 | 18 | const char* hstrerror(int err) { 19 | size_t i; 20 | for(i = 0; i < num_error_strings; ++i) { 21 | if(error_strings[i].err == err) 22 | return error_strings[i].str; 23 | } 24 | 25 | return "Unknown resolver error"; 26 | } 27 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_inet_addr.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | 4 | in_addr_t inet_addr(const char *cp) 5 | { 6 | struct in_addr addr = { .s_addr = INADDR_BROADCAST }; 7 | inet_aton(cp, &addr); 8 | return addr.s_addr; 9 | } 10 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_inet_aton.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include 5 | 6 | int inet_aton(const char *cp, struct in_addr *inp) 7 | { 8 | int base; 9 | uint32_t val; 10 | int c; 11 | char bytes[4]; 12 | size_t num_bytes = 0; 13 | 14 | c = *cp; 15 | for(;;) { 16 | if(!isdigit(c)) return 0; 17 | 18 | val = 0; 19 | base = 10; 20 | if(c == '0') { 21 | c = *++cp; 22 | if(c == 'x' || c == 'X') { 23 | base = 16; 24 | c = *++cp; 25 | } 26 | else base = 8; 27 | } 28 | 29 | for(;;) { 30 | if(isdigit(c)) { 31 | if(base == 8 && c >= '8') return 0; 32 | val *= base; 33 | val += c - '0'; 34 | c = *++cp; 35 | } 36 | else if(base == 16 && isxdigit(c)) { 37 | val *= base; 38 | val += c + 10 - (islower(c) ? 'a' : 'A'); 39 | c = *++cp; 40 | } 41 | else break; 42 | } 43 | 44 | if(c == '.') { 45 | if(num_bytes > 3) return 0; 46 | if(val > 0xFF) return 0; 47 | bytes[num_bytes++] = val; 48 | c = *++cp; 49 | } 50 | else break; 51 | } 52 | 53 | if(c != 0) return 0; 54 | 55 | switch(num_bytes) { 56 | case 0: 57 | break; 58 | 59 | case 1: 60 | if(val > 0xFFFFFF) return 0; 61 | val |= bytes[0] << 24; 62 | break; 63 | 64 | case 2: 65 | if(val > 0xFFFF) return 0; 66 | val |= bytes[0] << 24; 67 | val |= bytes[1] << 16; 68 | break; 69 | 70 | case 3: 71 | if(val > 0xFF) return 0; 72 | val |= bytes[0] << 24; 73 | val |= bytes[1] << 16; 74 | val |= bytes[2] << 8; 75 | break; 76 | } 77 | 78 | if(inp) 79 | inp->s_addr = htonl(val); 80 | 81 | return 1; 82 | } 83 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_inet_ntoa.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | 5 | static char buffer[INET_ADDRSTRLEN]; 6 | 7 | char* inet_ntoa(struct in_addr in) 8 | { 9 | unsigned char *addrbuf = (unsigned char*)∈ 10 | char *p; 11 | size_t i; 12 | unsigned int n; 13 | 14 | memset(buffer, 0, sizeof(buffer)); 15 | for(p = buffer, i = 0; i < 4; ++i) { 16 | if(i > 0) *p++ = '.'; 17 | 18 | n = addrbuf[i]; 19 | if(n >= 100) { 20 | *p++ = n/100 + '0'; 21 | n %= 100; 22 | } 23 | if(n >= 10 || addrbuf[i] >= 100) { 24 | *p++ = n/10 + '0'; 25 | n %= 10; 26 | } 27 | *p++ = n + '0'; 28 | } 29 | *p = 0; 30 | 31 | return buffer; 32 | } 33 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_ioctl.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int ioctl(int sockfd, int request, ...) 8 | { 9 | int ret; 10 | int flags; 11 | int *value; 12 | va_list ap; 13 | 14 | sockfd = soc_get_fd(sockfd); 15 | if(sockfd < 0) { 16 | errno = -sockfd; 17 | return -1; 18 | } 19 | 20 | switch(request) { 21 | case FIONBIO: 22 | va_start(ap, request); 23 | value = va_arg(ap, int*); 24 | va_end(ap); 25 | 26 | if(value == NULL) { 27 | errno = EFAULT; 28 | return -1; 29 | } 30 | 31 | flags = fcntl(sockfd, F_GETFL, 0); 32 | if(flags == -1) 33 | return -1; 34 | 35 | if(*value) 36 | ret = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); 37 | else 38 | ret = fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK); 39 | 40 | break; 41 | 42 | default: 43 | errno = ENOTTY; 44 | ret = -1; 45 | break; 46 | } 47 | 48 | return ret; 49 | } 50 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_listen.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int listen(int sockfd, int max_connections) 7 | { 8 | int ret = 0; 9 | u32 *cmdbuf = getThreadCommandBuffer(); 10 | 11 | sockfd = soc_get_fd(sockfd); 12 | if(sockfd < 0) { 13 | errno = -sockfd; 14 | return -1; 15 | } 16 | 17 | cmdbuf[0] = IPC_MakeHeader(0x3,2,2); // 0x30082 18 | cmdbuf[1] = (u32)sockfd; 19 | cmdbuf[2] = (u32)max_connections; 20 | cmdbuf[3] = IPC_Desc_CurProcessHandle(); 21 | 22 | ret = svcSendSyncRequest(SOCU_handle); 23 | if(ret != 0) { 24 | errno = SYNC_ERROR; 25 | return ret; 26 | } 27 | 28 | ret = (int)cmdbuf[1]; 29 | if(ret == 0) 30 | ret = _net_convert_error(cmdbuf[2]); 31 | 32 | if(ret < 0) { 33 | errno = -ret; 34 | return -1; 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_poll.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include <3ds/ipc.h> 7 | 8 | int poll(struct pollfd *fds, nfds_t nfds, int timeout) 9 | { 10 | int ret = 0; 11 | nfds_t i; 12 | u32 size = sizeof(struct pollfd)*nfds; 13 | u32 *cmdbuf = getThreadCommandBuffer(); 14 | u32 saved_threadstorage[2]; 15 | 16 | if(nfds == 0) { 17 | errno = EINVAL; 18 | return -1; 19 | } 20 | 21 | struct pollfd *tmp_fds = (struct pollfd*)malloc(sizeof(struct pollfd) * nfds); 22 | if(tmp_fds == NULL) { 23 | errno = ENOMEM; 24 | return -1; 25 | } 26 | 27 | memcpy(tmp_fds, fds, sizeof(struct pollfd) * nfds); 28 | 29 | for(i = 0; i < nfds; ++i) { 30 | tmp_fds[i].fd = soc_get_fd(fds[i].fd); 31 | if(tmp_fds[i].fd < 0) { 32 | errno = -tmp_fds[i].fd; 33 | free(tmp_fds); 34 | return -1; 35 | } 36 | tmp_fds[i].revents = 0; 37 | } 38 | 39 | cmdbuf[0] = IPC_MakeHeader(0x14,2,4); // 0x140084 40 | cmdbuf[1] = (u32)nfds; 41 | cmdbuf[2] = (u32)timeout; 42 | cmdbuf[3] = IPC_Desc_CurProcessHandle(); 43 | cmdbuf[5] = IPC_Desc_StaticBuffer(size,10); 44 | cmdbuf[6] = (u32)tmp_fds; 45 | 46 | u32 * staticbufs = getThreadStaticBuffers(); 47 | saved_threadstorage[0] = staticbufs[0]; 48 | saved_threadstorage[1] = staticbufs[1]; 49 | 50 | staticbufs[0] = IPC_Desc_StaticBuffer(size,0); 51 | staticbufs[1] = (u32)tmp_fds; 52 | 53 | ret = svcSendSyncRequest(SOCU_handle); 54 | if(ret != 0) { 55 | free(tmp_fds); 56 | errno = SYNC_ERROR; 57 | return ret; 58 | } 59 | 60 | staticbufs[0] = saved_threadstorage[0]; 61 | staticbufs[1] = saved_threadstorage[1]; 62 | 63 | ret = (int)cmdbuf[1]; 64 | if(ret == 0) 65 | ret = _net_convert_error(cmdbuf[2]); 66 | 67 | if(ret < 0) { 68 | free(tmp_fds); 69 | errno = -ret; 70 | return -1; 71 | } 72 | 73 | for(i = 0; i < nfds; ++i) 74 | fds[i].revents = tmp_fds[i].revents; 75 | 76 | free(tmp_fds); 77 | 78 | return ret; 79 | } 80 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_recv.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | 4 | ssize_t recv(int sockfd, void *buf, size_t len, int flags) 5 | { 6 | return recvfrom(sockfd, buf, len, flags, NULL, 0); 7 | } 8 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_recvfrom.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | ssize_t socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) 7 | { 8 | int ret = 0; 9 | u32 *cmdbuf = getThreadCommandBuffer(); 10 | u32 tmp_addrlen = 0; 11 | u8 tmpaddr[0x1c]; 12 | u32 saved_threadstorage[2]; 13 | 14 | memset(tmpaddr, 0, 0x1c); 15 | 16 | if(src_addr) 17 | tmp_addrlen = 0x1c; 18 | 19 | cmdbuf[0] = IPC_MakeHeader(0x7,4,4); // 0x70104 20 | cmdbuf[1] = (u32)sockfd; 21 | cmdbuf[2] = (u32)len; 22 | cmdbuf[3] = (u32)flags; 23 | cmdbuf[4] = (u32)tmp_addrlen; 24 | cmdbuf[5] = IPC_Desc_CurProcessHandle(); 25 | cmdbuf[7] = IPC_Desc_Buffer(len,IPC_BUFFER_W); 26 | cmdbuf[8] = (u32)buf; 27 | 28 | u32 * staticbufs = getThreadStaticBuffers(); 29 | saved_threadstorage[0] = staticbufs[0]; 30 | saved_threadstorage[1] = staticbufs[1]; 31 | 32 | staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0); 33 | staticbufs[1] = (u32)tmpaddr; 34 | 35 | ret = svcSendSyncRequest(SOCU_handle); 36 | if(ret != 0) { 37 | errno = SYNC_ERROR; 38 | return -1; 39 | } 40 | 41 | staticbufs[0] = saved_threadstorage[0]; 42 | staticbufs[1] = saved_threadstorage[1]; 43 | 44 | ret = (int)cmdbuf[1]; 45 | if(ret == 0) 46 | ret = _net_convert_error(cmdbuf[2]); 47 | 48 | if(ret < 0) { 49 | errno = -ret; 50 | return -1; 51 | } 52 | 53 | if(src_addr != NULL) { 54 | src_addr->sa_family = tmpaddr[1]; 55 | if(*addrlen > tmpaddr[0]) 56 | *addrlen = tmpaddr[0]; 57 | memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2); 58 | } 59 | 60 | return ret; 61 | } 62 | 63 | ssize_t socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) 64 | { 65 | int ret = 0; 66 | u32 *cmdbuf = getThreadCommandBuffer(); 67 | u32 tmp_addrlen = 0; 68 | u8 tmpaddr[0x1c]; 69 | u32 saved_threadstorage[4]; 70 | 71 | if(src_addr) 72 | tmp_addrlen = 0x1c; 73 | 74 | memset(tmpaddr, 0, 0x1c); 75 | 76 | cmdbuf[0] = 0x00080102; 77 | cmdbuf[1] = (u32)sockfd; 78 | cmdbuf[2] = (u32)len; 79 | cmdbuf[3] = (u32)flags; 80 | cmdbuf[4] = (u32)tmp_addrlen; 81 | cmdbuf[5] = 0x20; 82 | 83 | saved_threadstorage[0] = cmdbuf[0x100>>2]; 84 | saved_threadstorage[1] = cmdbuf[0x104>>2]; 85 | saved_threadstorage[2] = cmdbuf[0x108>>2]; 86 | saved_threadstorage[3] = cmdbuf[0x10c>>2]; 87 | 88 | cmdbuf[0x100>>2] = (((u32)len)<<14) | 2; 89 | cmdbuf[0x104>>2] = (u32)buf; 90 | cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2; 91 | cmdbuf[0x10c>>2] = (u32)tmpaddr; 92 | 93 | ret = svcSendSyncRequest(SOCU_handle); 94 | if(ret != 0) { 95 | errno = SYNC_ERROR; 96 | return ret; 97 | } 98 | 99 | cmdbuf[0x100>>2] = saved_threadstorage[0]; 100 | cmdbuf[0x104>>2] = saved_threadstorage[1]; 101 | cmdbuf[0x108>>2] = saved_threadstorage[2]; 102 | cmdbuf[0x10c>>2] = saved_threadstorage[3]; 103 | 104 | ret = (int)cmdbuf[1]; 105 | if(ret == 0) 106 | ret = _net_convert_error(cmdbuf[2]); 107 | 108 | if(ret < 0) { 109 | errno = -ret; 110 | return -1; 111 | } 112 | 113 | if(src_addr != NULL) { 114 | src_addr->sa_family = tmpaddr[1]; 115 | if(*addrlen > tmpaddr[0]) 116 | *addrlen = tmpaddr[0]; 117 | memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2); 118 | } 119 | 120 | return ret; 121 | } 122 | 123 | ssize_t soc_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) 124 | { 125 | if(len < 0x2000) 126 | return socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen); 127 | return socuipc_cmd7(sockfd, buf, len, flags, src_addr, addrlen); 128 | } 129 | 130 | ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) 131 | { 132 | sockfd = soc_get_fd(sockfd); 133 | if(sockfd < 0) { 134 | errno = -sockfd; 135 | return -1; 136 | } 137 | 138 | return soc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen); 139 | } 140 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_select.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) 8 | { 9 | struct pollfd *pollinfo; 10 | nfds_t numfds = 0; 11 | size_t i, j; 12 | int rc, found; 13 | 14 | for(i = 0; i < nfds; ++i) { 15 | if((readfds && FD_ISSET(i, readfds)) 16 | || (writefds && FD_ISSET(i, writefds)) 17 | || (exceptfds && FD_ISSET(i, exceptfds))) 18 | ++numfds; 19 | } 20 | 21 | pollinfo = (struct pollfd*)calloc(numfds, sizeof(struct pollfd)); 22 | if(pollinfo == NULL) { 23 | errno = ENOMEM; 24 | return -1; 25 | } 26 | 27 | for(i = 0, j = 0; i < nfds; ++i) { 28 | if((readfds && FD_ISSET(i, readfds)) 29 | || (writefds && FD_ISSET(i, writefds)) 30 | || (exceptfds && FD_ISSET(i, exceptfds))) { 31 | pollinfo[j].fd = i; 32 | pollinfo[j].events = 0; 33 | pollinfo[j].revents = 0; 34 | 35 | if(readfds && FD_ISSET(i, readfds)) 36 | pollinfo[j].events |= POLLIN; 37 | if(writefds && FD_ISSET(i, writefds)) 38 | pollinfo[j].events |= POLLOUT; 39 | 40 | ++j; 41 | } 42 | } 43 | 44 | if(timeout) 45 | rc = poll(pollinfo, numfds, timeout->tv_sec*1000 + timeout->tv_usec/1000); 46 | else 47 | rc = poll(pollinfo, numfds, -1); 48 | 49 | if(rc < 0) { 50 | free(pollinfo); 51 | return rc; 52 | } 53 | 54 | for(i = 0, j = 0, rc = 0; i < nfds; ++i) { 55 | found = 0; 56 | 57 | if((readfds && FD_ISSET(i, readfds)) 58 | || (writefds && FD_ISSET(i, writefds)) 59 | || (exceptfds && FD_ISSET(i, exceptfds))) { 60 | 61 | if(readfds && FD_ISSET(i, readfds)) { 62 | if(pollinfo[j].events & (POLLIN|POLLHUP)) 63 | found = 1; 64 | else 65 | FD_CLR(i, readfds); 66 | } 67 | 68 | if(writefds && FD_ISSET(i, writefds)) { 69 | if(pollinfo[j].events & (POLLOUT|POLLHUP)) 70 | found = 1; 71 | else 72 | FD_CLR(i, writefds); 73 | } 74 | 75 | if(exceptfds && FD_ISSET(i, exceptfds)) { 76 | if(pollinfo[j].events & POLLERR) 77 | found = 1; 78 | else 79 | FD_CLR(i, exceptfds); 80 | } 81 | 82 | if(found) 83 | ++rc; 84 | ++j; 85 | } 86 | } 87 | 88 | free(pollinfo); 89 | 90 | return rc; 91 | } 92 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_send.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | 4 | ssize_t send(int sockfd, const void *buf, size_t len, int flags) 5 | { 6 | return sendto(sockfd, buf, len, flags, NULL, 0); 7 | } 8 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_sendto.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | ssize_t socuipc_cmd9(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) 7 | { 8 | int ret = 0; 9 | u32 *cmdbuf = getThreadCommandBuffer(); 10 | u32 tmp_addrlen = 0; 11 | u8 tmpaddr[0x1c]; 12 | 13 | memset(tmpaddr, 0, 0x1c); 14 | 15 | if(dest_addr) { 16 | if(dest_addr->sa_family == AF_INET) 17 | tmp_addrlen = 8; 18 | else 19 | tmp_addrlen = 0x1c; 20 | 21 | if(addrlen < tmp_addrlen) { 22 | errno = EINVAL; 23 | return -1; 24 | } 25 | 26 | tmpaddr[0] = tmp_addrlen; 27 | tmpaddr[1] = dest_addr->sa_family; 28 | memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2); 29 | } 30 | 31 | cmdbuf[0] = IPC_MakeHeader(0x9,4,6); // 0x90106 32 | cmdbuf[1] = (u32)sockfd; 33 | cmdbuf[2] = (u32)len; 34 | cmdbuf[3] = (u32)flags; 35 | cmdbuf[4] = (u32)tmp_addrlen; 36 | cmdbuf[5] = IPC_Desc_CurProcessHandle(); 37 | cmdbuf[7] = IPC_Desc_StaticBuffer(tmp_addrlen,1); 38 | cmdbuf[8] = (u32)tmpaddr; 39 | cmdbuf[9] = IPC_Desc_Buffer(len,IPC_BUFFER_R); 40 | cmdbuf[10] = (u32)buf; 41 | 42 | ret = svcSendSyncRequest(SOCU_handle); 43 | if(ret != 0) { 44 | errno = SYNC_ERROR; 45 | return ret; 46 | } 47 | 48 | ret = (int)cmdbuf[1]; 49 | if(ret == 0) 50 | ret = _net_convert_error(cmdbuf[2]); 51 | 52 | if(ret < 0) { 53 | errno = -ret; 54 | return -1; 55 | } 56 | 57 | return ret; 58 | } 59 | 60 | ssize_t socuipc_cmda(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) 61 | { 62 | int ret = 0; 63 | u32 *cmdbuf = getThreadCommandBuffer(); 64 | u32 tmp_addrlen = 0; 65 | u8 tmpaddr[0x1c]; 66 | 67 | memset(tmpaddr, 0, 0x1c); 68 | 69 | if(dest_addr) { 70 | if(dest_addr->sa_family == AF_INET) 71 | tmp_addrlen = 8; 72 | else 73 | tmp_addrlen = 0x1c; 74 | 75 | if(addrlen < tmp_addrlen) { 76 | errno = EINVAL; 77 | return -1; 78 | } 79 | 80 | tmpaddr[0] = tmp_addrlen; 81 | tmpaddr[1] = dest_addr->sa_family; 82 | memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2); 83 | } 84 | 85 | cmdbuf[0] = IPC_MakeHeader(0xA,4,6); // 0xA0106 86 | cmdbuf[1] = (u32)sockfd; 87 | cmdbuf[2] = (u32)len; 88 | cmdbuf[3] = (u32)flags; 89 | cmdbuf[4] = (u32)tmp_addrlen; 90 | cmdbuf[5] = IPC_Desc_CurProcessHandle(); 91 | cmdbuf[7] = IPC_Desc_StaticBuffer(len,2); 92 | cmdbuf[8] = (u32)buf; 93 | cmdbuf[9] = IPC_Desc_StaticBuffer(tmp_addrlen,1); 94 | cmdbuf[10] = (u32)tmpaddr; 95 | 96 | ret = svcSendSyncRequest(SOCU_handle); 97 | if(ret != 0) { 98 | errno = SYNC_ERROR; 99 | return ret; 100 | } 101 | 102 | ret = (int)cmdbuf[1]; 103 | if(ret == 0) 104 | ret = _net_convert_error(cmdbuf[2]); 105 | 106 | if(ret < 0) { 107 | errno = -ret; 108 | return -1; 109 | } 110 | 111 | return ret; 112 | } 113 | 114 | ssize_t soc_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) 115 | { 116 | if(len < 0x2000) 117 | return socuipc_cmda(sockfd, buf, len, flags, dest_addr, addrlen); 118 | return socuipc_cmd9(sockfd, buf, len, flags, dest_addr, addrlen); 119 | } 120 | 121 | ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) 122 | { 123 | sockfd = soc_get_fd(sockfd); 124 | if(sockfd < 0) { 125 | errno = -sockfd; 126 | return -1; 127 | } 128 | 129 | return soc_sendto(sockfd, buf, len, flags, dest_addr, addrlen); 130 | } 131 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_setsockopt.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) 7 | { 8 | int ret = 0; 9 | u32 *cmdbuf = getThreadCommandBuffer(); 10 | 11 | sockfd = soc_get_fd(sockfd); 12 | if(sockfd < 0) { 13 | errno = -sockfd; 14 | return -1; 15 | } 16 | 17 | cmdbuf[0] = IPC_MakeHeader(0x12,4,4); // 0x120104 18 | cmdbuf[1] = (u32)sockfd; 19 | cmdbuf[2] = (u32)level; 20 | cmdbuf[3] = (u32)optname; 21 | cmdbuf[4] = (u32)optlen; 22 | cmdbuf[5] = IPC_Desc_CurProcessHandle(); 23 | cmdbuf[7] = IPC_Desc_StaticBuffer(optlen,9); 24 | cmdbuf[8] = (u32)optval; 25 | 26 | ret = svcSendSyncRequest(SOCU_handle); 27 | if(ret != 0) { 28 | errno = SYNC_ERROR; 29 | return ret; 30 | } 31 | 32 | ret = (int)cmdbuf[1]; 33 | if(ret == 0) 34 | ret = _net_convert_error(cmdbuf[2]); 35 | 36 | if(ret < 0) { 37 | errno = -ret; 38 | return -1; 39 | } 40 | 41 | return ret; 42 | } 43 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_shutdown.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int shutdown(int sockfd, int shutdown_type) 7 | { 8 | int ret = 0; 9 | u32 *cmdbuf = getThreadCommandBuffer(); 10 | 11 | sockfd = soc_get_fd(sockfd); 12 | if(sockfd < 0) { 13 | errno = -sockfd; 14 | return -1; 15 | } 16 | 17 | cmdbuf[0] = IPC_MakeHeader(0xC,2,2); // 0xC0082 18 | cmdbuf[1] = (u32)sockfd; 19 | cmdbuf[2] = (u32)shutdown_type; 20 | cmdbuf[3] = IPC_Desc_CurProcessHandle(); 21 | 22 | ret = svcSendSyncRequest(SOCU_handle); 23 | if(ret != 0) { 24 | errno = SYNC_ERROR; 25 | return ret; 26 | } 27 | 28 | ret = (int)cmdbuf[1]; 29 | if(ret == 0) 30 | ret = _net_convert_error(cmdbuf[2]); 31 | 32 | if(ret < 0) { 33 | errno = -ret; 34 | return -1; 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_sockatmark.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include <3ds/ipc.h> 5 | 6 | int sockatmark(int sockfd) 7 | { 8 | int ret = 0; 9 | u32 *cmdbuf = getThreadCommandBuffer(); 10 | 11 | sockfd = soc_get_fd(sockfd); 12 | if(sockfd < 0) { 13 | errno = -sockfd; 14 | return -1; 15 | } 16 | 17 | cmdbuf[0] = IPC_MakeHeader(0x15,1,2); // 0x150042 18 | cmdbuf[1] = (u32)sockfd; 19 | cmdbuf[2] = IPC_Desc_CurProcessHandle(); 20 | 21 | ret = svcSendSyncRequest(SOCU_handle); 22 | if(ret != 0) { 23 | errno = SYNC_ERROR; 24 | return -1; 25 | } 26 | 27 | ret = (int)cmdbuf[1]; 28 | if(ret == 0) 29 | ret = _net_convert_error(cmdbuf[2]); 30 | 31 | if(ret < 0) { 32 | errno = -ret; 33 | return -1; 34 | } 35 | 36 | return ret; 37 | } 38 | -------------------------------------------------------------------------------- /libctru/source/services/soc/soc_socket.c: -------------------------------------------------------------------------------- 1 | #include "soc_common.h" 2 | #include 3 | #include 4 | #include 5 | #include <3ds/ipc.h> 6 | 7 | int socket(int domain, int type, int protocol) 8 | { 9 | int ret = 0; 10 | int fd, dev; 11 | __handle *handle; 12 | u32 *cmdbuf = getThreadCommandBuffer(); 13 | 14 | cmdbuf[0] = IPC_MakeHeader(0x2,3,2); // 0x200C2 15 | cmdbuf[1] = domain; 16 | cmdbuf[2] = type; 17 | cmdbuf[3] = protocol; 18 | cmdbuf[4] = IPC_Desc_CurProcessHandle(); 19 | 20 | dev = FindDevice("soc:"); 21 | if(dev < 0) { 22 | errno = ENODEV; 23 | return -1; 24 | } 25 | 26 | fd = __alloc_handle(sizeof(__handle) + sizeof(Handle)); 27 | if(fd < 0) { 28 | errno = ENOMEM; 29 | return -1; 30 | } 31 | 32 | handle = __get_handle(fd); 33 | handle->device = dev; 34 | handle->fileStruct = ((void *)handle) + sizeof(__handle); 35 | 36 | ret = svcSendSyncRequest(SOCU_handle); 37 | if(ret != 0) 38 | { 39 | __release_handle(fd); 40 | errno = SYNC_ERROR; 41 | return ret; 42 | } 43 | 44 | ret = (int)cmdbuf[1]; 45 | if(ret == 0)ret = cmdbuf[2]; 46 | if(ret < 0) { 47 | __release_handle(fd); 48 | if(cmdbuf[1] == 0)errno = _net_convert_error(ret); 49 | if(cmdbuf[1] != 0)errno = SYNC_ERROR; 50 | return -1; 51 | } 52 | 53 | *(Handle*)handle->fileStruct = cmdbuf[2]; 54 | return fd; 55 | } 56 | -------------------------------------------------------------------------------- /libctru/source/services/srvpm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/result.h> 4 | #include <3ds/svc.h> 5 | #include <3ds/srv.h> 6 | #include <3ds/synchronization.h> 7 | #include <3ds/services/srvpm.h> 8 | #include <3ds/ipc.h> 9 | 10 | static Handle srvPmHandle; 11 | static int srvPmRefCount; 12 | 13 | Result srvPmInit(void) 14 | { 15 | if (AtomicPostIncrement(&srvPmRefCount)) return 0; 16 | Result res = srvGetServiceHandle(&srvPmHandle, "srv:pm"); 17 | if (R_FAILED(res)) AtomicDecrement(&srvPmRefCount); 18 | return res; 19 | } 20 | 21 | void srvPmExit(void) 22 | { 23 | if (AtomicDecrement(&srvPmRefCount)) return; 24 | svcCloseHandle(srvPmHandle); 25 | } 26 | 27 | Result SRVPM_PublishToProcess(u32 notificationId, Handle process) 28 | { 29 | Result rc = 0; 30 | u32* cmdbuf = getThreadCommandBuffer(); 31 | 32 | cmdbuf[0] = IPC_MakeHeader(0x1,1,2); // 0x10042 33 | cmdbuf[1] = notificationId; 34 | cmdbuf[2] = IPC_Desc_SharedHandles(1); 35 | cmdbuf[3] = process; 36 | 37 | if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle)))return rc; 38 | 39 | return cmdbuf[1]; 40 | } 41 | 42 | Result SRVPM_PublishToAll(u32 notificationId) 43 | { 44 | Result rc = 0; 45 | u32* cmdbuf = getThreadCommandBuffer(); 46 | 47 | cmdbuf[0] = IPC_MakeHeader(0x2,1,0); // 0x20040 48 | cmdbuf[1] = notificationId; 49 | 50 | if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle)))return rc; 51 | 52 | return cmdbuf[1]; 53 | } 54 | 55 | Result SRVPM_RegisterProcess(u32 procid, u32 count, void* serviceaccesscontrol) 56 | { 57 | Result rc = 0; 58 | u32 *cmdbuf = getThreadCommandBuffer(); 59 | 60 | cmdbuf[0] = IPC_MakeHeader(0x3,2,2); // 0x30082 61 | cmdbuf[1] = procid; 62 | cmdbuf[2] = count; 63 | cmdbuf[3] = IPC_Desc_StaticBuffer(count*4,0); 64 | cmdbuf[4] = (u32)serviceaccesscontrol; 65 | 66 | if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle))) return rc; 67 | 68 | return cmdbuf[1]; 69 | } 70 | 71 | Result SRVPM_UnregisterProcess(u32 procid) 72 | { 73 | Result rc = 0; 74 | u32 *cmdbuf = getThreadCommandBuffer(); 75 | 76 | cmdbuf[0] = IPC_MakeHeader(0x4,1,0); // 0x40040 77 | cmdbuf[1] = procid; 78 | 79 | if(R_FAILED(rc = svcSendSyncRequest(srvPmHandle))) return rc; 80 | 81 | return cmdbuf[1]; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /libctru/source/synchronization.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3ds/types.h> 3 | #include <3ds/svc.h> 4 | #include <3ds/synchronization.h> 5 | 6 | static Handle arbiter; 7 | 8 | Result __sync_init(void) 9 | { 10 | return svcCreateAddressArbiter(&arbiter); 11 | } 12 | 13 | void __sync_fini(void) 14 | { 15 | if (arbiter) 16 | svcCloseHandle(arbiter); 17 | } 18 | 19 | void LightLock_Init(LightLock* lock) 20 | { 21 | do 22 | __ldrex(lock); 23 | while (__strex(lock, 1)); 24 | } 25 | 26 | void LightLock_Lock(LightLock* lock) 27 | { 28 | s32 val; 29 | _begin: 30 | do 31 | { 32 | val = __ldrex(lock); 33 | if (val < 0) 34 | { 35 | // Add ourselves to the list of threads blocked on this lock 36 | if (__strex(lock, val-1)) 37 | goto _begin; // strex failed, try to lock again 38 | 39 | _wait: 40 | // Wait for a thread to wake us up 41 | svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0); 42 | 43 | // Try to lock again 44 | do 45 | { 46 | val = __ldrex(lock); 47 | if (val < 0) 48 | { 49 | // Lock is still locked - keep waiting 50 | __clrex(); 51 | goto _wait; 52 | } 53 | } while (__strex(lock, -(val-1))); 54 | return; 55 | } 56 | } while (__strex(lock, -val)); 57 | } 58 | 59 | int LightLock_TryLock(LightLock* lock) 60 | { 61 | s32 val; 62 | do 63 | { 64 | val = __ldrex(lock); 65 | if (val < 0) 66 | { 67 | __clrex(); 68 | return 1; // Failure 69 | } 70 | } while (__strex(lock, -val)); 71 | return 0; // Success 72 | } 73 | 74 | void LightLock_Unlock(LightLock* lock) 75 | { 76 | s32 val; 77 | do 78 | val = -__ldrex(lock); 79 | while (__strex(lock, val)); 80 | 81 | if (val > 1) 82 | // Wake up exactly one thread 83 | svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_SIGNAL, 1, 0); 84 | } 85 | 86 | void RecursiveLock_Init(RecursiveLock* lock) 87 | { 88 | LightLock_Init(&lock->lock); 89 | lock->thread_tag = 0; 90 | lock->counter = 0; 91 | } 92 | 93 | void RecursiveLock_Lock(RecursiveLock* lock) 94 | { 95 | u32 tag = (u32)getThreadLocalStorage(); 96 | if (lock->thread_tag != tag) 97 | { 98 | LightLock_Lock(&lock->lock); 99 | lock->thread_tag = tag; 100 | } 101 | lock->counter ++; 102 | } 103 | 104 | int RecursiveLock_TryLock(RecursiveLock* lock) 105 | { 106 | u32 tag = (u32)getThreadLocalStorage(); 107 | if (lock->thread_tag != tag) 108 | { 109 | if (LightLock_TryLock(&lock->lock)) 110 | return 1; // Failure 111 | lock->thread_tag = tag; 112 | } 113 | lock->counter ++; 114 | return 0; // Success 115 | } 116 | 117 | void RecursiveLock_Unlock(RecursiveLock* lock) 118 | { 119 | if (!--lock->counter) 120 | { 121 | lock->thread_tag = 0; 122 | LightLock_Unlock(&lock->lock); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /libctru/source/system/allocateHeaps.c: -------------------------------------------------------------------------------- 1 | #include <3ds/types.h> 2 | #include <3ds/svc.h> 3 | #include <3ds/env.h> 4 | 5 | extern char* fake_heap_start; 6 | extern char* fake_heap_end; 7 | 8 | u32 __ctru_heap; 9 | u32 __ctru_heap_size; 10 | u32 __ctru_linear_heap; 11 | u32 __ctru_linear_heap_size; 12 | 13 | void __attribute__((weak)) __system_allocateHeaps() { 14 | u32 tmp=0; 15 | 16 | // Retrieve heap sizes. 17 | __ctru_heap_size = envGetHeapSize(); 18 | __ctru_linear_heap_size = envGetLinearHeapSize(); 19 | 20 | // Allocate the application heap 21 | __ctru_heap = 0x08000000; 22 | svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE); 23 | 24 | // Allocate the linear heap 25 | svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); 26 | 27 | // Set up newlib heap 28 | fake_heap_start = (char*)__ctru_heap; 29 | fake_heap_end = fake_heap_start + __ctru_heap_size; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /libctru/source/system/appExit.c: -------------------------------------------------------------------------------- 1 | #include <3ds/types.h> 2 | #include <3ds/srv.h> 3 | #include <3ds/gfx.h> 4 | #include <3ds/sdmc.h> 5 | #include <3ds/services/apt.h> 6 | #include <3ds/services/fs.h> 7 | #include <3ds/services/hid.h> 8 | 9 | void __attribute__((weak)) __appExit() { 10 | // Exit services 11 | sdmcExit(); 12 | fsExit(); 13 | 14 | hidExit(); 15 | aptExit(); 16 | srvExit(); 17 | } 18 | -------------------------------------------------------------------------------- /libctru/source/system/appInit.c: -------------------------------------------------------------------------------- 1 | #include <3ds/types.h> 2 | #include <3ds/srv.h> 3 | #include <3ds/gfx.h> 4 | #include <3ds/sdmc.h> 5 | #include <3ds/services/apt.h> 6 | #include <3ds/services/fs.h> 7 | #include <3ds/services/hid.h> 8 | 9 | void __attribute__((weak)) __appInit() { 10 | // Initialize services 11 | srvInit(); 12 | aptInit(); 13 | hidInit(); 14 | 15 | fsInit(); 16 | sdmcInit(); 17 | } 18 | -------------------------------------------------------------------------------- /libctru/source/system/ctru_exit.c: -------------------------------------------------------------------------------- 1 | #include <3ds/types.h> 2 | #include <3ds/svc.h> 3 | #include <3ds/env.h> 4 | 5 | extern u32 __ctru_heap; 6 | extern u32 __ctru_heap_size; 7 | extern u32 __ctru_linear_heap; 8 | extern u32 __ctru_linear_heap_size; 9 | 10 | extern void (*__system_retAddr)(void); 11 | 12 | void envDestroyHandles(void); 13 | 14 | void __appExit(); 15 | 16 | void __libc_fini_array(void); 17 | 18 | Result __sync_fini(void) __attribute__((weak)); 19 | 20 | void __attribute__((weak)) __attribute__((noreturn)) __libctru_exit(int rc) 21 | { 22 | u32 tmp=0; 23 | 24 | // Unmap the linear heap 25 | svcControlMemory(&tmp, __ctru_linear_heap, 0x0, __ctru_linear_heap_size, MEMOP_FREE, 0x0); 26 | 27 | // Unmap the application heap 28 | svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_FREE, 0x0); 29 | 30 | // Close some handles 31 | envDestroyHandles(); 32 | 33 | if (__sync_fini) 34 | __sync_fini(); 35 | 36 | // Jump to the loader if it provided a callback 37 | if (__system_retAddr) 38 | __system_retAddr(); 39 | 40 | // Since above did not jump, end this process 41 | svcExitProcess(); 42 | } 43 | -------------------------------------------------------------------------------- /libctru/source/system/initArgv.c: -------------------------------------------------------------------------------- 1 | #include <3ds/types.h> 2 | #include <3ds/env.h> 3 | 4 | #include 5 | 6 | // System globals we define here 7 | int __system_argc; 8 | char** __system_argv; 9 | 10 | extern char* fake_heap_start; 11 | extern char* fake_heap_end; 12 | 13 | void __system_initArgv() 14 | { 15 | int i; 16 | const char* arglist = envGetSystemArgList(); 17 | const char* temp = arglist; 18 | 19 | // Check if the argument list is present 20 | if (!temp) 21 | return; 22 | 23 | // Retrieve argc 24 | __system_argc = *(u32*)temp; 25 | temp += sizeof(u32); 26 | 27 | // Find the end of the argument data 28 | for (i = 0; i < __system_argc; i ++) 29 | { 30 | for (; *temp; temp ++); 31 | temp ++; 32 | } 33 | 34 | // Reserve heap memory for argv data 35 | u32 argSize = temp - arglist - sizeof(u32); 36 | __system_argv = (char**)fake_heap_start; 37 | fake_heap_start += sizeof(char**)*(__system_argc + 1); 38 | char* argCopy = fake_heap_start; 39 | fake_heap_start += argSize; 40 | 41 | // Fill argv array 42 | memcpy(argCopy, &arglist[4], argSize); 43 | temp = argCopy; 44 | for (i = 0; i < __system_argc; i ++) 45 | { 46 | __system_argv[i] = (char*)temp; 47 | for (; *temp; temp ++); 48 | temp ++; 49 | } 50 | __system_argv[__system_argc] = NULL; 51 | } 52 | -------------------------------------------------------------------------------- /libctru/source/system/initSystem.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include <3ds/types.h> 6 | #include <3ds/svc.h> 7 | #include <3ds/env.h> 8 | 9 | void (*__system_retAddr)(void); 10 | 11 | void __system_allocateHeaps(); 12 | void __system_initArgv(); 13 | void __appInit(); 14 | 15 | 16 | void __ctru_exit(int rc); 17 | int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz); 18 | 19 | Result __sync_init(void) __attribute__((weak)); 20 | 21 | void __attribute__((weak)) __libctru_init(void (*retAddr)(void)) 22 | { 23 | 24 | // Register newlib exit() syscall 25 | __syscalls.exit = __ctru_exit; 26 | __syscalls.gettod_r = __libctru_gtod; 27 | 28 | __system_retAddr = envIsHomebrew() ? retAddr : NULL; 29 | 30 | if (__sync_init) 31 | __sync_init(); 32 | 33 | __system_allocateHeaps(); 34 | 35 | // Build argc/argv if present 36 | __system_initArgv(); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /libctru/source/system/stack_adjust.s: -------------------------------------------------------------------------------- 1 | 2 | .arm 3 | .align 2 4 | 5 | .global initSystem 6 | .type initSystem, %function 7 | 8 | initSystem: 9 | ldr r2, =saved_stack 10 | str sp, [r2] 11 | str lr, [r2,#4] 12 | 13 | bl __libctru_init 14 | 15 | ldr r2, =fake_heap_start 16 | ldr sp, [r2] 17 | 18 | ldr r3, =__stacksize__ 19 | ldr r3, [r3] 20 | add sp, sp, r3 21 | add sp, sp, #7 22 | bics sp, sp, #7 23 | str sp, [r2] 24 | 25 | 26 | bl __appInit 27 | bl __libc_init_array 28 | 29 | ldr r2, =saved_stack 30 | ldr lr, [r2,#4] 31 | bx lr 32 | 33 | 34 | .global __ctru_exit 35 | .type __ctru_exit, %function 36 | 37 | __ctru_exit: 38 | bl __libc_fini_array 39 | bl __appExit 40 | 41 | ldr r2, =saved_stack 42 | ldr sp, [r2] 43 | b __libctru_exit 44 | 45 | .data 46 | .align 2 47 | __stacksize__: 48 | .word 32 * 1024 49 | .weak __stacksize__ 50 | 51 | 52 | .bss 53 | .align 2 54 | saved_stack: 55 | .space 8 56 | 57 | 58 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_clear.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | #include "rbtree_internal.h" 3 | 4 | void 5 | rbtree_clear(rbtree_t *tree, 6 | rbtree_node_destructor_t destructor) 7 | { 8 | rbtree_node_t *node = tree->root; 9 | 10 | while(tree->root != NULL) 11 | { 12 | while(node->child[LEFT] != NULL) 13 | node = node->child[LEFT]; 14 | 15 | if(node->child[RIGHT] != NULL) 16 | node = node->child[RIGHT]; 17 | else 18 | { 19 | rbtree_node_t *parent = get_parent(node); 20 | 21 | if(parent == NULL) 22 | tree->root = NULL; 23 | else 24 | parent->child[node != parent->child[LEFT]] = NULL; 25 | 26 | if(destructor != NULL) 27 | (*destructor)(node); 28 | 29 | node = parent; 30 | } 31 | } 32 | 33 | tree->size = 0; 34 | } 35 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_empty.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | 3 | int 4 | rbtree_empty(const rbtree_t *tree) 5 | { 6 | return tree->root == NULL; 7 | } 8 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_find.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | #include "rbtree_internal.h" 3 | 4 | rbtree_node_t* 5 | rbtree_find(const rbtree_t *tree, 6 | const rbtree_node_t *node) 7 | { 8 | rbtree_node_t *tmp = tree->root; 9 | rbtree_node_t *save = NULL; 10 | 11 | while(tmp != NULL) 12 | { 13 | int rc = (*tree->comparator)(node, tmp); 14 | if(rc < 0) 15 | { 16 | tmp = tmp->child[LEFT]; 17 | } 18 | else if(rc > 0) 19 | { 20 | tmp = tmp->child[RIGHT]; 21 | } 22 | else 23 | { 24 | save = tmp; 25 | tmp = tmp->child[LEFT]; 26 | } 27 | } 28 | 29 | return save; 30 | } 31 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_init.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | 3 | void 4 | rbtree_init(rbtree_t *tree, 5 | rbtree_node_comparator_t comparator) 6 | { 7 | tree->root = NULL; 8 | tree->comparator = comparator; 9 | tree->size = 0; 10 | } 11 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_insert.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | #include "rbtree_internal.h" 3 | 4 | static rbtree_node_t* 5 | do_insert(rbtree_t *tree, 6 | rbtree_node_t *node, 7 | int multi) 8 | { 9 | rbtree_node_t *original = node; 10 | rbtree_node_t **tmp = &tree->root; 11 | rbtree_node_t *parent = NULL; 12 | rbtree_node_t *save = NULL; 13 | 14 | while(*tmp != NULL) 15 | { 16 | int cmp = (*(tree->comparator))(node, *tmp); 17 | parent = *tmp; 18 | 19 | if(cmp < 0) 20 | tmp = &((*tmp)->child[LEFT]); 21 | else if(cmp > 0) 22 | tmp = &((*tmp)->child[RIGHT]); 23 | else 24 | { 25 | if(!multi) 26 | save = *tmp; 27 | 28 | tmp = &((*tmp)->child[LEFT]); 29 | } 30 | } 31 | 32 | if(save != NULL) 33 | { 34 | return save; 35 | } 36 | 37 | *tmp = node; 38 | 39 | node->child[LEFT] = node->child[RIGHT] = NULL; 40 | set_parent(node, parent); 41 | 42 | set_red(node); 43 | 44 | while(is_red((parent = get_parent(node)))) 45 | { 46 | rbtree_node_t *grandparent = get_parent(parent); 47 | int left = (parent == grandparent->child[LEFT]); 48 | rbtree_node_t *uncle = grandparent->child[left]; 49 | 50 | if(is_red(uncle)) 51 | { 52 | set_black(uncle); 53 | set_black(parent); 54 | set_red(grandparent); 55 | 56 | node = grandparent; 57 | } 58 | else 59 | { 60 | if(parent->child[left] == node) 61 | { 62 | rbtree_node_t *tmp; 63 | 64 | rbtree_rotate(tree, parent, left); 65 | 66 | tmp = parent; 67 | parent = node; 68 | node = tmp; 69 | } 70 | 71 | set_black(parent); 72 | set_red(grandparent); 73 | rbtree_rotate(tree, grandparent, !left); 74 | } 75 | } 76 | 77 | set_black(tree->root); 78 | 79 | tree->size += 1; 80 | 81 | return original; 82 | } 83 | 84 | rbtree_node_t* 85 | rbtree_insert(rbtree_t *tree, 86 | rbtree_node_t *node) 87 | { 88 | return do_insert(tree, node, 0); 89 | } 90 | 91 | void 92 | rbtree_insert_multi(rbtree_t *tree, 93 | rbtree_node_t *node) 94 | { 95 | do_insert(tree, node, 1); 96 | } 97 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_internal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define LEFT 0 4 | #define RIGHT 1 5 | 6 | typedef enum rbtree_color 7 | { 8 | RED = 0, 9 | BLACK = 1, 10 | } rbtree_color_t; 11 | 12 | #define COLOR_MASK (RED|BLACK) 13 | 14 | static inline void 15 | set_black(rbtree_node_t *node) 16 | { 17 | node->parent_color &= ~COLOR_MASK; 18 | node->parent_color |= BLACK; 19 | } 20 | 21 | static inline void 22 | set_red(rbtree_node_t *node) 23 | { 24 | node->parent_color &= ~COLOR_MASK; 25 | node->parent_color |= RED; 26 | } 27 | 28 | static inline rbtree_color_t 29 | get_color(const rbtree_node_t *node) 30 | { 31 | if(node == NULL) 32 | return BLACK; 33 | return (rbtree_color_t)(node->parent_color & COLOR_MASK); 34 | } 35 | 36 | static inline int 37 | is_black(const rbtree_node_t *node) 38 | { 39 | return get_color(node) == BLACK; 40 | } 41 | 42 | static inline int 43 | is_red(const rbtree_node_t *node) 44 | { 45 | return get_color(node) == RED; 46 | } 47 | 48 | static inline rbtree_node_t* 49 | get_parent(const rbtree_node_t *node) 50 | { 51 | return (rbtree_node_t*)(node->parent_color & ~COLOR_MASK); 52 | } 53 | 54 | static inline void 55 | set_parent(rbtree_node_t *node, 56 | const rbtree_node_t *parent) 57 | { 58 | node->parent_color = (get_color(node)) | ((uintptr_t)parent); 59 | } 60 | 61 | void 62 | rbtree_rotate(rbtree_t *tree, 63 | rbtree_node_t *node, 64 | int left); 65 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_iterator.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | #include "rbtree_internal.h" 3 | 4 | static inline rbtree_node_t* 5 | do_iterate(const rbtree_node_t *node, 6 | int next) 7 | { 8 | rbtree_node_t *it = (rbtree_node_t*)node; 9 | 10 | if(it->child[next] != NULL) 11 | { 12 | it = it->child[next]; 13 | while(it->child[!next] != NULL) 14 | it = it->child[!next]; 15 | } 16 | else 17 | { 18 | rbtree_node_t *parent = get_parent(node); 19 | while(parent != NULL && it == parent->child[next]) 20 | { 21 | it = parent; 22 | parent = get_parent(it); 23 | } 24 | 25 | it = parent; 26 | } 27 | 28 | return it; 29 | } 30 | 31 | rbtree_node_t* 32 | rbtree_node_next(const rbtree_node_t *node) 33 | { 34 | return do_iterate(node, RIGHT); 35 | } 36 | 37 | rbtree_node_t* 38 | rbtree_node_prev(const rbtree_node_t *node) 39 | { 40 | return do_iterate(node, LEFT); 41 | } 42 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_minmax.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | #include "rbtree_internal.h" 3 | 4 | static inline rbtree_node_t* 5 | do_minmax(const rbtree_t *tree, 6 | int max) 7 | { 8 | rbtree_node_t *node = tree->root; 9 | 10 | if(node == NULL) 11 | return NULL; 12 | 13 | while(node->child[max] != NULL) 14 | node = node->child[max]; 15 | 16 | return node; 17 | } 18 | 19 | rbtree_node_t* 20 | rbtree_min(const rbtree_t *tree) 21 | { 22 | rbtree_node_t *node; 23 | 24 | node = do_minmax(tree, LEFT); 25 | 26 | return node; 27 | } 28 | 29 | rbtree_node_t* 30 | rbtree_max(const rbtree_t *tree) 31 | { 32 | rbtree_node_t *node; 33 | 34 | node = do_minmax(tree, RIGHT); 35 | 36 | return node; 37 | } 38 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_remove.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | #include "rbtree_internal.h" 3 | 4 | static void 5 | recolor(rbtree_t *tree, 6 | rbtree_node_t *parent, 7 | rbtree_node_t *node) 8 | { 9 | rbtree_node_t *sibling; 10 | 11 | while(is_black(node) && node != tree->root) 12 | { 13 | int left = (node == parent->child[LEFT]); 14 | 15 | sibling = parent->child[left]; 16 | 17 | if(is_red(sibling)) 18 | { 19 | set_black(sibling); 20 | set_red(parent); 21 | rbtree_rotate(tree, parent, left); 22 | sibling = parent->child[left]; 23 | } 24 | 25 | if(is_black(sibling->child[LEFT]) && is_black(sibling->child[RIGHT])) 26 | { 27 | set_red(sibling); 28 | node = parent; 29 | parent = get_parent(node); 30 | } 31 | else 32 | { 33 | if(is_black(sibling->child[left])) 34 | { 35 | set_black(sibling->child[!left]); 36 | set_red(sibling); 37 | rbtree_rotate(tree, sibling, !left); 38 | sibling = parent->child[left]; 39 | } 40 | 41 | if(is_black(parent)) 42 | set_black(sibling); 43 | else 44 | set_red(sibling); 45 | set_black(parent); 46 | set_black(sibling->child[left]); 47 | 48 | rbtree_rotate(tree, parent, left); 49 | 50 | node = tree->root; 51 | } 52 | } 53 | 54 | if(node != NULL) 55 | set_black(node); 56 | } 57 | 58 | rbtree_node_t* 59 | rbtree_remove(rbtree_t *tree, 60 | rbtree_node_t *node, 61 | rbtree_node_destructor_t destructor) 62 | { 63 | rbtree_color_t color; 64 | rbtree_node_t *child, *parent, *original = node; 65 | rbtree_node_t *next; 66 | 67 | next = rbtree_node_next(node); 68 | 69 | if(node->child[LEFT] != NULL && node->child[RIGHT] != NULL) 70 | { 71 | rbtree_node_t *old = node; 72 | 73 | node = node->child[RIGHT]; 74 | while(node->child[LEFT] != NULL) 75 | node = node->child[LEFT]; 76 | 77 | parent = get_parent(old); 78 | if(parent != NULL) 79 | { 80 | if(parent->child[LEFT] == old) 81 | parent->child[LEFT] = node; 82 | else 83 | parent->child[RIGHT] = node; 84 | } 85 | else 86 | tree->root = node; 87 | 88 | child = node->child[RIGHT]; 89 | parent = get_parent(node); 90 | color = get_color(node); 91 | 92 | if(parent == old) 93 | parent = node; 94 | else 95 | { 96 | if(child != NULL) 97 | set_parent(child, parent); 98 | parent->child[LEFT] = child; 99 | 100 | node->child[RIGHT] = old->child[RIGHT]; 101 | set_parent(old->child[RIGHT], node); 102 | } 103 | 104 | node->parent_color = old->parent_color; 105 | node->child[LEFT] = old->child[LEFT]; 106 | set_parent(old->child[LEFT], node); 107 | } 108 | else 109 | { 110 | if(node->child[LEFT] == NULL) 111 | child = node->child[RIGHT]; 112 | else 113 | child = node->child[LEFT]; 114 | 115 | parent = get_parent(node); 116 | color = get_color(node); 117 | 118 | if(child != NULL) 119 | set_parent(child, parent); 120 | if(parent != NULL) 121 | { 122 | if(parent->child[LEFT] == node) 123 | parent->child[LEFT] = child; 124 | else 125 | parent->child[RIGHT] = child; 126 | } 127 | else 128 | tree->root = child; 129 | } 130 | 131 | if(color == BLACK) 132 | recolor(tree, parent, child); 133 | 134 | if(destructor != NULL) 135 | (*destructor)(original); 136 | 137 | tree->size -= 1; 138 | 139 | return next; 140 | } 141 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_rotate.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | #include "rbtree_internal.h" 3 | 4 | void 5 | rbtree_rotate(rbtree_t *tree, 6 | rbtree_node_t *node, 7 | int left) 8 | { 9 | rbtree_node_t *tmp = node->child[left]; 10 | rbtree_node_t *parent = get_parent(node); 11 | 12 | node->child[left] = tmp->child[!left]; 13 | if(tmp->child[!left] != NULL) 14 | set_parent(tmp->child[!left], node); 15 | 16 | tmp->child[!left] = node; 17 | set_parent(tmp, parent); 18 | if(parent != NULL) 19 | { 20 | if(node == parent->child[!left]) 21 | parent->child[!left] = tmp; 22 | else 23 | parent->child[left] = tmp; 24 | } 25 | else 26 | tree->root = tmp; 27 | set_parent(node, tmp); 28 | } 29 | -------------------------------------------------------------------------------- /libctru/source/util/rbtree/rbtree_size.c: -------------------------------------------------------------------------------- 1 | #include <3ds/util/rbtree.h> 2 | 3 | size_t 4 | rbtree_size(const rbtree_t *tree) 5 | { 6 | return tree->size; 7 | } 8 | -------------------------------------------------------------------------------- /libctru/source/util/utf/decode_utf16.c: -------------------------------------------------------------------------------- 1 | #include "3ds/util/utf.h" 2 | 3 | ssize_t 4 | decode_utf16(uint32_t *out, 5 | const uint16_t *in) 6 | { 7 | uint16_t code1, code2; 8 | 9 | code1 = *in++; 10 | if(code1 >= 0xD800 && code1 < 0xDC00) 11 | { 12 | /* surrogate pair */ 13 | code2 = *in++; 14 | if(code2 >= 0xDC00 && code2 < 0xE000) 15 | { 16 | *out = (code1 << 10) + code2 - 0x35FDC00; 17 | return 2; 18 | } 19 | 20 | return -1; 21 | } 22 | 23 | *out = code1; 24 | return 1; 25 | } 26 | -------------------------------------------------------------------------------- /libctru/source/util/utf/decode_utf8.c: -------------------------------------------------------------------------------- 1 | #include "3ds/util/utf.h" 2 | 3 | ssize_t 4 | decode_utf8(uint32_t *out, 5 | const uint8_t *in) 6 | { 7 | uint8_t code1, code2, code3, code4; 8 | 9 | code1 = *in++; 10 | if(code1 < 0x80) 11 | { 12 | /* 1-byte sequence */ 13 | *out = code1; 14 | return 1; 15 | } 16 | else if(code1 < 0xC2) 17 | { 18 | return -1; 19 | } 20 | else if(code1 < 0xE0) 21 | { 22 | /* 2-byte sequence */ 23 | code2 = *in++; 24 | if((code2 & 0xC0) != 0x80) 25 | { 26 | return -1; 27 | } 28 | 29 | *out = (code1 << 6) + code2 - 0x3080; 30 | return 2; 31 | } 32 | else if(code1 < 0xF0) 33 | { 34 | /* 3-byte sequence */ 35 | code2 = *in++; 36 | if((code2 & 0xC0) != 0x80) 37 | { 38 | return -1; 39 | } 40 | if(code1 == 0xE0 && code2 < 0xA0) 41 | { 42 | return -1; 43 | } 44 | 45 | code3 = *in++; 46 | if((code3 & 0xC0) != 0x80) 47 | { 48 | return -1; 49 | } 50 | 51 | *out = (code1 << 12) + (code2 << 6) + code3 - 0xE2080; 52 | return 3; 53 | } 54 | else if(code1 < 0xF5) 55 | { 56 | /* 4-byte sequence */ 57 | code2 = *in++; 58 | if((code2 & 0xC0) != 0x80) 59 | { 60 | return -1; 61 | } 62 | if(code1 == 0xF0 && code2 < 0x90) 63 | { 64 | return -1; 65 | } 66 | if(code1 == 0xF4 && code2 >= 0x90) 67 | { 68 | return -1; 69 | } 70 | 71 | code3 = *in++; 72 | if((code3 & 0xC0) != 0x80) 73 | { 74 | return -1; 75 | } 76 | 77 | code4 = *in++; 78 | if((code4 & 0xC0) != 0x80) 79 | { 80 | return -1; 81 | } 82 | 83 | *out = (code1 << 18) + (code2 << 12) + (code3 << 6) + code4 - 0x3C82080; 84 | return 4; 85 | } 86 | 87 | return -1; 88 | } 89 | -------------------------------------------------------------------------------- /libctru/source/util/utf/encode_utf16.c: -------------------------------------------------------------------------------- 1 | #include "3ds/util/utf.h" 2 | 3 | ssize_t 4 | encode_utf16(uint16_t *out, 5 | uint32_t in) 6 | { 7 | if(in < 0x10000) 8 | { 9 | if(out != NULL) 10 | *out++ = in; 11 | return 1; 12 | } 13 | else if(in < 0x110000) 14 | { 15 | if(out != NULL) 16 | { 17 | *out++ = (in >> 10) + 0xD7C0; 18 | *out++ = (in & 0x3FF) + 0xDC00; 19 | } 20 | return 2; 21 | } 22 | 23 | return -1; 24 | } 25 | -------------------------------------------------------------------------------- /libctru/source/util/utf/encode_utf8.c: -------------------------------------------------------------------------------- 1 | #include "3ds/util/utf.h" 2 | 3 | ssize_t 4 | encode_utf8(uint8_t *out, 5 | uint32_t in) 6 | { 7 | if(in < 0x80) 8 | { 9 | if(out != NULL) 10 | *out++ = in; 11 | return 1; 12 | } 13 | else if(in < 0x800) 14 | { 15 | if(out != NULL) 16 | { 17 | *out++ = (in >> 6) + 0xC0; 18 | *out++ = (in & 0x3F) + 0x80; 19 | } 20 | return 2; 21 | } 22 | else if(in < 0x10000) 23 | { 24 | if(out != NULL) 25 | { 26 | *out++ = (in >> 12) + 0xE0; 27 | *out++ = ((in >> 6) & 0x3F) + 0x80; 28 | *out++ = (in & 0x3F) + 0x80; 29 | } 30 | return 3; 31 | } 32 | else if(in < 0x110000) 33 | { 34 | if(out != NULL) 35 | { 36 | *out++ = (in >> 18) + 0xF0; 37 | *out++ = ((in >> 12) & 0x3F) + 0x80; 38 | *out++ = ((in >> 6) & 0x3F) + 0x80; 39 | *out++ = (in & 0x3F) + 0x80; 40 | } 41 | return 4; 42 | } 43 | 44 | return -1; 45 | } 46 | -------------------------------------------------------------------------------- /libctru/source/util/utf/utf16_to_utf32.c: -------------------------------------------------------------------------------- 1 | #include "3ds/types.h" 2 | #include "3ds/util/utf.h" 3 | 4 | ssize_t 5 | utf16_to_utf32(uint32_t *out, 6 | const uint16_t *in, 7 | size_t len) 8 | { 9 | ssize_t rc = 0; 10 | ssize_t units; 11 | uint32_t code; 12 | 13 | do 14 | { 15 | units = decode_utf16(&code, in); 16 | if(units == -1) 17 | return -1; 18 | 19 | if(code > 0) 20 | { 21 | in += units; 22 | 23 | if(out != NULL) 24 | { 25 | if(rc < len) 26 | *out++ = code; 27 | } 28 | 29 | if(SSIZE_MAX - 1 >= rc) 30 | ++rc; 31 | else 32 | return -1; 33 | } 34 | } while(code > 0); 35 | 36 | return rc; 37 | } 38 | -------------------------------------------------------------------------------- /libctru/source/util/utf/utf16_to_utf8.c: -------------------------------------------------------------------------------- 1 | #include "3ds/types.h" 2 | #include "3ds/util/utf.h" 3 | 4 | ssize_t 5 | utf16_to_utf8(uint8_t *out, 6 | const uint16_t *in, 7 | size_t len) 8 | { 9 | ssize_t rc = 0; 10 | ssize_t units; 11 | uint32_t code; 12 | uint8_t encoded[4]; 13 | 14 | do 15 | { 16 | units = decode_utf16(&code, in); 17 | if(units == -1) 18 | return -1; 19 | 20 | if(code > 0) 21 | { 22 | in += units; 23 | 24 | units = encode_utf8(encoded, code); 25 | if(units == -1) 26 | return -1; 27 | 28 | if(out != NULL) 29 | { 30 | if(rc + units <= len) 31 | { 32 | *out++ = encoded[0]; 33 | if(units > 1) 34 | *out++ = encoded[1]; 35 | if(units > 2) 36 | *out++ = encoded[2]; 37 | if(units > 3) 38 | *out++ = encoded[3]; 39 | } 40 | } 41 | 42 | if(SSIZE_MAX - units >= rc) 43 | rc += units; 44 | else 45 | return -1; 46 | } 47 | } while(code > 0); 48 | 49 | return rc; 50 | } 51 | -------------------------------------------------------------------------------- /libctru/source/util/utf/utf32_to_utf16.c: -------------------------------------------------------------------------------- 1 | #include "3ds/types.h" 2 | #include "3ds/util/utf.h" 3 | 4 | ssize_t 5 | utf32_to_utf16(uint16_t *out, 6 | const uint32_t *in, 7 | size_t len) 8 | { 9 | ssize_t rc = 0; 10 | ssize_t units; 11 | uint16_t encoded[2]; 12 | 13 | while(*in > 0) 14 | { 15 | units = encode_utf16(encoded, *in++); 16 | if(units == -1) 17 | return -1; 18 | 19 | if(out != NULL) 20 | { 21 | if(rc + units <= len) 22 | { 23 | *out++ = encoded[0]; 24 | if(units > 1) 25 | *out++ = encoded[1]; 26 | } 27 | } 28 | 29 | if(SSIZE_MAX - units >= rc) 30 | rc += units; 31 | else 32 | return -1; 33 | } 34 | 35 | return rc; 36 | } 37 | -------------------------------------------------------------------------------- /libctru/source/util/utf/utf32_to_utf8.c: -------------------------------------------------------------------------------- 1 | #include "3ds/types.h" 2 | #include "3ds/util/utf.h" 3 | 4 | ssize_t 5 | utf32_to_utf8(uint8_t *out, 6 | const uint32_t *in, 7 | size_t len) 8 | { 9 | ssize_t rc = 0; 10 | ssize_t units; 11 | uint8_t encoded[4]; 12 | 13 | while(*in > 0) 14 | { 15 | units = encode_utf8(encoded, *in++); 16 | if(units == -1) 17 | return -1; 18 | 19 | if(out != NULL) 20 | { 21 | if(rc + units <= len) 22 | { 23 | *out++ = encoded[0]; 24 | if(units > 1) 25 | *out++ = encoded[1]; 26 | if(units > 2) 27 | *out++ = encoded[2]; 28 | if(units > 3) 29 | *out++ = encoded[3]; 30 | } 31 | } 32 | 33 | if(SSIZE_MAX - units >= rc) 34 | rc += units; 35 | else 36 | return -1; 37 | } 38 | 39 | return rc; 40 | } 41 | -------------------------------------------------------------------------------- /libctru/source/util/utf/utf8_to_utf16.c: -------------------------------------------------------------------------------- 1 | #include "3ds/types.h" 2 | #include "3ds/util/utf.h" 3 | 4 | ssize_t 5 | utf8_to_utf16(uint16_t *out, 6 | const uint8_t *in, 7 | size_t len) 8 | { 9 | ssize_t rc = 0; 10 | ssize_t units; 11 | uint32_t code; 12 | uint16_t encoded[2]; 13 | 14 | do 15 | { 16 | units = decode_utf8(&code, in); 17 | if(units == -1) 18 | return -1; 19 | 20 | if(code > 0) 21 | { 22 | in += units; 23 | 24 | units = encode_utf16(encoded, code); 25 | if(units == -1) 26 | return -1; 27 | 28 | if(out != NULL) 29 | { 30 | if(rc + units <= len) 31 | { 32 | *out++ = encoded[0]; 33 | if(units > 1) 34 | *out++ = encoded[1]; 35 | } 36 | } 37 | 38 | if(SSIZE_MAX - units >= rc) 39 | rc += units; 40 | else 41 | return -1; 42 | } 43 | } while(code > 0); 44 | 45 | return rc; 46 | } 47 | -------------------------------------------------------------------------------- /libctru/source/util/utf/utf8_to_utf32.c: -------------------------------------------------------------------------------- 1 | #include "3ds/types.h" 2 | #include "3ds/util/utf.h" 3 | 4 | ssize_t 5 | utf8_to_utf32(uint32_t *out, 6 | const uint8_t *in, 7 | size_t len) 8 | { 9 | ssize_t rc = 0; 10 | ssize_t units; 11 | uint32_t code; 12 | 13 | do 14 | { 15 | units = decode_utf8(&code, in); 16 | if(units == -1) 17 | return -1; 18 | 19 | if(code > 0) 20 | { 21 | in += units; 22 | 23 | if(out != NULL) 24 | { 25 | if(rc < len) 26 | *out++ = code; 27 | } 28 | 29 | if(SSIZE_MAX - 1 >= rc) 30 | ++rc; 31 | else 32 | return -1; 33 | } 34 | } while(code > 0); 35 | 36 | return rc; 37 | } 38 | -------------------------------------------------------------------------------- /source/ff_ctr.c: -------------------------------------------------------------------------------- 1 | #include "include/ff.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include <3ds.h> 8 | #ifdef USE_DMALLOC 9 | #include 10 | #endif 11 | 12 | extern char path[256]; 13 | static signed char **dirfname; 14 | static int dirpos; 15 | static int dirsize; 16 | 17 | static int wildcard(const signed char *name, const signed char *match) 18 | { 19 | int i; 20 | int max; 21 | max=strlen(name); 22 | if(strlen(match)!=max) { 23 | return 0; 24 | } 25 | for(i=0;i='a' && a<='z') a^=32; 30 | if(b>='a' && b<='z') b^=32; 31 | if(b=='?' || a==b) { 32 | // continue 33 | } else { 34 | return 0; 35 | } 36 | } 37 | return 1; 38 | } 39 | 40 | void unicodeToChar(signed char* dst, u16* src){ 41 | if(!src || !dst)return; 42 | while(*src)*(dst++)=(*(src++))&0xFF; 43 | *dst=0x00; 44 | } 45 | 46 | typedef struct{ 47 | u16 name[0x106]; ///< UTF-16 encoded name 48 | u8 shortName[0x0A]; ///< 8.3 File name 49 | u8 shortExt[0x04]; ///< 8.3 File extension (set to spaces for directories) 50 | u8 unknown2; ///< ??? 51 | u8 unknown3; ///< ??? 52 | u8 isDirectory; ///< Directory bit 53 | u8 isHidden; ///< Hidden bit 54 | u8 isArchive; ///< Archive bit 55 | u8 isReadOnly; ///< Read-only bit 56 | u64 fileSize; ///< File size 57 | } FS_dirent; 58 | 59 | int findfirst(const signed char *pathname, struct ffblk *ffblk, int attrib) { 60 | signed char *match=strdup(pathname); 61 | unsigned int i; 62 | if(match[0]=='*') match++; 63 | for(i=0;i='a' && match[i]<='z') match[i]^=32; 65 | } 66 | dirsize=0; 67 | printf("Looking for '%s' (%s)\n",match,pathname); 68 | Handle dirHandle; 69 | FS_dirent entry; 70 | FS_Path dirPath=fsMakePath(PATH_ASCII, path); 71 | FS_Archive sdmcArchive = (FS_Archive){0x9, (FS_Path){PATH_EMPTY, 1, (u8*)""}}; 72 | FSUSER_OpenArchive( &sdmcArchive); 73 | FSUSER_OpenDirectory(&dirHandle, sdmcArchive, dirPath); 74 | u32 entriesRead; 75 | for (;;){ 76 | entriesRead=0; 77 | FSDIR_Read(dirHandle, &entriesRead, 1, &entry); 78 | static signed char name[64]; 79 | if (entriesRead){ 80 | unicodeToChar(name,entry.name); 81 | if(strcasestr(name,match)==0 && wildcard(name,match)==0) continue; 82 | if(dirsize==0) { 83 | dirfname=(signed char **)calloc(sizeof(signed char *),64); 84 | } else if((dirsize%64)==0) { 85 | dirfname=(signed char **)realloc(dirfname,sizeof(signed char *)*(dirsize+64)); 86 | } 87 | dirfname[dirsize++]=strdup(name); 88 | }else break; 89 | } 90 | FSDIR_Close(dirHandle); 91 | FSUSER_CloseArchive( &sdmcArchive); 92 | printf("Got %d matches\n",dirsize); 93 | if (dirsize>0) { 94 | dirpos=1; 95 | strcpy(ffblk->ff_name,dirfname[dirsize-1]); 96 | return 0; 97 | } 98 | 99 | return 1; 100 | 101 | } 102 | 103 | int findnext(struct ffblk *ffblk) { 104 | 105 | if (dirposff_name,dirfname[dirpos++]); 107 | return 0; 108 | } 109 | return 1; 110 | 111 | } 112 | 113 | void resetinactivity(void) { 114 | //User::ResetInactivityTime(); 115 | } 116 | -------------------------------------------------------------------------------- /source/include/ff.h: -------------------------------------------------------------------------------- 1 | #ifndef __FF_H__ 2 | #define __FF_H__ 3 | 4 | #define FA_ARCH 0 5 | 6 | struct ffblk { 7 | // signed char ff_reserved[5]; /* used to hold the state of the search */ 8 | // unsigned char ff_attrib; /* actual attributes of the file found */ 9 | // unsigned short ff_ftime; /* hours:5, minutes:6, (seconds/2):5 */ 10 | // unsigned short ff_fdate; /* (year-1980):7, month:4, day:5 */ 11 | // unsigned long ff_fsize; /* size of file */ 12 | signed char ff_name[256]; /* name of file as ASCIIZ string */ 13 | }; 14 | 15 | #ifdef __cplusplus 16 | extern "C" 17 | #endif 18 | int findfirst(const signed char *pathname, struct ffblk *ffblk, int attrib); 19 | #ifdef __cplusplus 20 | extern "C" 21 | #endif 22 | int findnext(struct ffblk *ffblk); 23 | #ifdef __cplusplus 24 | extern "C" 25 | #endif 26 | void resetinactivity(void); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /source/include/id_ca.h: -------------------------------------------------------------------------------- 1 | #ifndef __ID_CA_H__ 2 | #define __ID_CA_H__ 3 | 4 | /* ======================================================================== */ 5 | 6 | #define NUMMAPS 60 7 | #define MAPPLANES 2 8 | 9 | typedef struct 10 | { 11 | int planestart[3]; 12 | int planelength[3]; 13 | int width, height; 14 | signed char name[16]; 15 | } maptype; 16 | 17 | /* ======================================================================== */ 18 | 19 | extern int mapon; 20 | 21 | extern word *mapsegs[MAPPLANES]; 22 | extern maptype *mapheaderseg[NUMMAPS]; 23 | extern byte *audiosegs[NUMSNDCHUNKS]; 24 | extern byte *grsegs[NUMCHUNKS]; 25 | 26 | extern signed char extension[5]; 27 | 28 | /* ======================================================================== */ 29 | 30 | boolean CA_LoadFile(signed char *filename, memptr *ptr); 31 | boolean CA_WriteFile(signed char *filename, void *ptr, long length); 32 | 33 | void CA_RLEWexpand(word *source, word *dest, long length, word rlewtag); 34 | 35 | void CA_Startup(); 36 | void CA_Shutdown(); 37 | 38 | void CA_CacheAudioChunk(int chunk); 39 | void CA_UnCacheAudioChunk(int chunk); 40 | void CA_LoadAllSounds(); 41 | 42 | void CA_CacheMap(int mapnum); 43 | void CA_CacheGrChunk(int chunk); 44 | void CA_UnCacheGrChunk(int chunk); 45 | 46 | /* ======================================================================= */ 47 | 48 | void MM_Startup(); 49 | void MM_Shutdown(); 50 | 51 | void MM_GetPtr(memptr *baseptr, unsigned long size); 52 | void MM_FreePtr(memptr *baseptr); 53 | 54 | void MM_SetPurge(memptr *baseptr, int purge); 55 | void MM_SetLock(memptr *baseptr, boolean locked); 56 | void MM_SortMem(); 57 | 58 | #define PMPageSize 4096 59 | 60 | typedef struct { 61 | int offset; /* Offset of chunk into file */ 62 | int length; /* Length of the chunk */ 63 | memptr addr; 64 | } PageListStruct; 65 | 66 | extern int ChunksInFile, PMSpriteStart, PMSoundStart; 67 | 68 | extern PageListStruct *PMPages; 69 | 70 | #define PM_GetSoundPage(v) PM_GetPage(PMSoundStart + (v)) 71 | #define PM_GetSpritePage(v) PM_GetPage(PMSpriteStart + (v)) 72 | memptr PM_GetPage(int pagenum); 73 | void PM_FreePage(int pagenum); 74 | 75 | void PM_Startup(); 76 | void PM_Shutdown(); 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /source/include/id_heads.h: -------------------------------------------------------------------------------- 1 | #ifndef __ID_HEADS_H__ 2 | #define __ID_HEADS_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | //#include 11 | #include 12 | #include 13 | 14 | #ifdef __cplusplus 15 | typedef bool boolean; 16 | #else 17 | typedef enum { false, true } boolean; 18 | #endif 19 | 20 | #include "version.h" 21 | 22 | /* ------------------------------------------------------------------------ */ 23 | 24 | #ifndef SPEAR 25 | 26 | #ifndef UPLOAD 27 | #include "gfxv_wl6.h" 28 | #else 29 | #include "gfxv_wl1.h" 30 | #endif 31 | 32 | #include "audiowl6.h" 33 | 34 | #else /* SPEAR */ 35 | 36 | #ifndef SPEARDEMO 37 | #include "gfxv_sod.h" 38 | #else /* SPEARDEMO */ 39 | #include "gfxv_sdm.h" 40 | #endif /* SPEARDEMO */ 41 | 42 | #include "audiosod.h" 43 | 44 | #endif /* SPEAR */ 45 | 46 | /* ---------------- */ 47 | 48 | typedef uint8_t byte; 49 | typedef uint16_t word; 50 | typedef uint32_t longword; 51 | typedef uint32_t dword; 52 | 53 | typedef long fixed; 54 | 55 | typedef void * memptr; 56 | 57 | typedef struct { 58 | int x, y; 59 | } Point; 60 | 61 | typedef struct { 62 | Point ul, lr; 63 | } Rect; 64 | 65 | #include "misc.h" 66 | 67 | #include "vi_comm.h" 68 | #include "sd_comm.h" 69 | 70 | #include "id_ca.h" 71 | #include "id_vh.h" 72 | #include "id_us.h" 73 | 74 | extern const byte gamepal[]; 75 | 76 | int MS_CheckParm(signed char *string); 77 | void Quit(signed char *error); 78 | 79 | #define TickBase 70 /* 70Hz per tick */ 80 | 81 | #undef PI 82 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445920 83 | 84 | #define MAXTICS 10 85 | #define DEMOTICS 4 86 | 87 | extern int tics; 88 | 89 | #define mapwidth 64 90 | #define mapheight 64 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /source/include/id_us.h: -------------------------------------------------------------------------------- 1 | #ifndef __ID_US_H__ 2 | #define __ID_US_H__ 3 | 4 | #define MaxX 400 //320 5 | #define MaxY 240 //200 6 | 7 | #define MaxHighName 57 8 | #define MaxScores 7 9 | typedef struct { 10 | signed char name[MaxHighName + 1]; 11 | int score; 12 | int completed, episode; 13 | } HighScore; 14 | 15 | #define MaxString 128 // Maximum input string size 16 | 17 | extern boolean NoWait; 18 | extern word PrintX,PrintY; // Current printing location in the window 19 | extern word WindowX,WindowY,// Current location of window 20 | WindowW,WindowH;// Current size of window 21 | 22 | #define USL_MeasureString VW_MeasurePropString 23 | #define USL_DrawString VW_DrawPropString 24 | 25 | 26 | extern HighScore Scores[]; 27 | 28 | void US_Startup(), 29 | US_Shutdown(), 30 | US_InitRndT(boolean randomize), 31 | US_DrawWindow(word x,word y,word w,word h), 32 | US_ClearWindow(void), 33 | US_PrintCentered(signed char *s), 34 | US_CPrint(signed char *s), 35 | US_CPrintLine(signed char *s), 36 | US_Print(signed char *s), 37 | US_PrintUnsigned(longword n); 38 | boolean US_LineInput(int x,int y,signed char *buf,signed char *def,boolean escok, 39 | int maxchars,int maxwidth); 40 | int US_RndT(); 41 | 42 | void USL_PrintInCenter(signed char *s,Rect r); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /source/include/id_vh.h: -------------------------------------------------------------------------------- 1 | #ifndef __ID_VH_H__ 2 | #define __ID_VH_H__ 3 | 4 | // colors 5 | #define BLACK 0 6 | #define BLUE 1 7 | #define GREEN 2 8 | #define CYAN 3 9 | #define RED 4 10 | #define MAGENTA 5 11 | #define BROWN 6 12 | #define GRAY 7 13 | // lite version of the above colors 14 | #define LITE 8 15 | #define DARKGRAY (LITE + BLACK) 16 | #define LITEBLUE (LITE + BLUE) 17 | #define LITEGREEN (LITE + GREEN) 18 | #define LITECYAN (LITE + CYAN) 19 | #define LITERED (LITE + RED) 20 | #define LITEMAGENTA (LITE + MAGENTA) 21 | #define YELLOW (LITE + BROWN) 22 | #define WHITE (LITE + GRAY) 23 | 24 | typedef struct 25 | { 26 | int width, height; 27 | } pictabletype; 28 | 29 | extern pictabletype pictable[NUMPICS]; 30 | 31 | extern byte fontcolor, backcolor; 32 | extern int fontnumber; 33 | extern int px, py; 34 | 35 | #define SETFONTCOLOR(f, b) { fontcolor = f; backcolor = b; } 36 | 37 | void VW_UpdateScreen(); 38 | 39 | void VWB_DrawTile8(int x, int y, int tile); 40 | void VWB_DrawPic(int x, int y, int chunknum); 41 | 42 | extern boolean screenfaded; 43 | 44 | #define VW_Hlin(x,z,y,c) VL_Hlin(x,y,(z)-(x)+1,c) 45 | #define VW_Vlin(y,z,x,c) VL_Vlin(x,y,(z)-(y)+1,c) 46 | #define VW_WaitVBL VL_WaitVBL 47 | #define VW_FadeIn() VL_FadeIn(0,255,gamepal,30); 48 | #define VW_FadeOut() VL_FadeOut(0,255,0,0,0,30); 49 | void VW_MeasurePropString(signed char *string, word *width, word *height); 50 | 51 | void VW_DrawPropString(signed char *string); 52 | 53 | void VL_FadeOut(int start, int end, int red, int green, int blue, int steps); 54 | void VL_FadeIn(int start, int end, const byte *palette, int steps); 55 | 56 | void VL_CacheScreen(int chunk); 57 | 58 | void VW_Bar(int x, int y, int width, int height, int color); 59 | 60 | void VW_Startup(); 61 | void VW_Shutdown(); 62 | 63 | void VL_FillPalette(int red, int green, int blue); 64 | void VW_Plot(int x, int y, int color); 65 | void VL_Hlin(unsigned x, unsigned y, unsigned width, unsigned color); 66 | void VL_Vlin(int x, int y, int height, int color); 67 | void VL_Bar(int x, int y, int width, int height, int color); 68 | 69 | void VL_MemToScreen(const byte *source, int width, int height, int x, int y); 70 | 71 | void VL_DeModeXize(byte *buf, int width, int height); 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /source/include/misc.h: -------------------------------------------------------------------------------- 1 | #ifndef __MISC_H__ 2 | #define __MISC_H__ 3 | 4 | extern int _argc; 5 | extern signed char **_argv; 6 | 7 | void SavePCX256ToFile(unsigned char *buf, int width, int height, unsigned char *pal, signed char *name); 8 | void SavePCXRGBToFile(unsigned char *buf, int width, int height, signed char *name); 9 | 10 | void set_TimeCount(unsigned long t); 11 | unsigned long get_TimeCount(); 12 | 13 | long filelength(int handle); 14 | 15 | #define stricmp strcasecmp 16 | #define strnicmp strncasecmp 17 | char *strlwr(char *s); 18 | 19 | char *itoa(int value, char *string, int radix); 20 | char *ltoa(long value, char *string, int radix); 21 | char *ultoa(unsigned long value, char *string, int radix); 22 | 23 | uint16_t SwapInt16L(uint16_t i); 24 | uint32_t SwapInt32L(uint32_t i); 25 | 26 | extern int OpenWrite(signed char *fn); 27 | extern int OpenWriteAppend(signed char *fn); 28 | extern void CloseWrite(int fp); 29 | 30 | extern int WriteSeek(int fp, int offset, int whence); 31 | extern int WritePos(int fp); 32 | 33 | extern int WriteInt8(int fp, int8_t d); 34 | extern int WriteInt16(int fp, int16_t d); 35 | extern int WriteInt32(int fp, int32_t d); 36 | extern int WriteBytes(int fp, byte *d, int len); 37 | 38 | extern int OpenRead(signed char *fn); 39 | extern void CloseRead(int fp); 40 | 41 | extern int ReadSeek(int fp, int offset, int whence); 42 | extern int ReadLength(int fp); 43 | 44 | extern int8_t ReadInt8(int fp); 45 | extern int16_t ReadInt16(int fp); 46 | extern int32_t ReadInt32(int fp); 47 | extern int ReadBytes(int fp, byte *d, int len); 48 | 49 | 50 | static __inline__ uint16_t SwapInt16(uint16_t i) 51 | { 52 | return ((uint16_t)i >> 8) | ((uint16_t)i << 8); 53 | } 54 | 55 | static __inline__ uint32_t SwapInt32(uint32_t i) 56 | { 57 | return ((uint32_t)(i & 0xFF000000) >> 24) | 58 | ((uint32_t)(i & 0x00FF0000) >> 8) | 59 | ((uint32_t)(i & 0x0000FF00) << 8) | 60 | ((uint32_t)(i & 0x000000FF) << 24); 61 | } 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /source/include/sd_comm.h: -------------------------------------------------------------------------------- 1 | #ifndef __SD_COMM_H__ 2 | #define __SD_COMM_H__ 3 | 4 | typedef enum { 5 | sdm_Off, 6 | sdm_PC,sdm_AdLib 7 | } SDMode; 8 | typedef enum { 9 | smm_Off,smm_AdLib 10 | } SMMode; 11 | typedef enum { 12 | sds_Off,sds_PC,sds_SoundBlaster 13 | } SDSMode; 14 | 15 | extern boolean AdLibPresent, SoundBlasterPresent; 16 | 17 | extern SDMode SoundMode; 18 | extern SDSMode DigiMode; 19 | extern SMMode MusicMode; 20 | 21 | extern void SD_Startup(); 22 | extern void SD_Shutdown(); 23 | extern void Blah(); 24 | 25 | extern boolean SD_PlaySound(soundnames sound); 26 | extern void SD_StopSound(), 27 | SD_WaitSoundDone(), 28 | SD_StartMusic(int music), 29 | SD_MusicOn(), 30 | SD_MusicOff(); 31 | 32 | extern boolean SD_SetSoundMode(SDMode mode), SD_SetMusicMode(SMMode mode); 33 | 34 | extern word SD_SoundPlaying(); 35 | 36 | extern void SD_SetDigiDevice(SDSMode); 37 | 38 | void PlaySoundLocGlobal(word s, int id, fixed gx, fixed gy); 39 | void UpdateSoundLoc(fixed x, fixed y, int angle); 40 | 41 | 42 | extern int DigiMap[]; 43 | void InitDigiMap(); 44 | 45 | extern void SD_SetVolume(int vol); 46 | extern int SD_GetVolume(); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /source/include/version.h: -------------------------------------------------------------------------------- 1 | #ifndef __VERSION_H__ 2 | #define __VERSION_H__ 3 | 4 | 5 | /* Change WMODE to point to the executable you would like to build: */ 6 | // Mode 0 = Wolf3D Shareware 7 | // Mode 1 = Wolf3d Full 8 | // Mode 2 = SOD Shareware 9 | // Mode 3 = SOD Full / SOD Episode 1 & 2 10 | 11 | #ifndef WMODE 12 | #define WMODE 0 13 | #endif 14 | 15 | /* --- End of User-Modifiable Variables --- */ 16 | 17 | #if WMODE == 0 18 | /* #define SPEAR */ 19 | /* #define SPEARDEMO */ 20 | #define UPLOAD 21 | #define GAMENAME "Wolfenstein 3D Shareware" 22 | #define GAMEEXT "wl1" 23 | #define GAMETYPE "WL1\0" 24 | 25 | #elif WMODE == 1 26 | /* #define SPEAR */ 27 | /* #define SPEARDEMO */ 28 | /* #define UPLOAD */ 29 | #define GAMENAME "Wolfenstein 3D" 30 | #define GAMEEXT "wl6" 31 | #define GAMETYPE "WL6\0" 32 | 33 | #elif WMODE == 2 34 | #define SPEAR 35 | #define SPEARDEMO 36 | /* #define UPLOAD */ 37 | #define GAMENAME "Spear of Destiny Demo" 38 | #define GAMEEXT "sdm" 39 | #define GAMETYPE "SDM\0" 40 | 41 | #elif WMODE == 3 42 | #define SPEAR 43 | /* #define SPEARDEMO */ 44 | /* #define UPLOAD */ 45 | #define GAMENAME "Spear of Destiny" 46 | #define GAMEEXT "sod" 47 | #define GAMETYPE "SOD\0" 48 | 49 | #else 50 | #error "please edit version.h and fix WMODE" 51 | #endif 52 | 53 | #define GAMEHDR "WOLF3D\0\0" 54 | 55 | #define SAVTYPE "SAV\0" 56 | #define CFGTYPE "CFG\0" 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /source/sd_comm.c: -------------------------------------------------------------------------------- 1 | #include "include/wl_def.h" 2 | 3 | /* 4 | ===================== 5 | = 6 | = InitDigiMap 7 | = 8 | ===================== 9 | */ 10 | 11 | int DigiMap[LASTSOUND]; 12 | 13 | static int wolfdigimap[] = 14 | { 15 | #ifndef SPEAR 16 | HALTSND, 0, 17 | DOGBARKSND, 1, 18 | CLOSEDOORSND, 2, 19 | OPENDOORSND, 3, 20 | ATKMACHINEGUNSND, 4, 21 | ATKPISTOLSND, 5, 22 | ATKGATLINGSND, 6, 23 | SCHUTZADSND, 7, 24 | GUTENTAGSND, 8, 25 | MUTTISND, 9, 26 | BOSSFIRESND, 10, 27 | SSFIRESND, 11, 28 | DEATHSCREAM1SND, 12, 29 | DEATHSCREAM2SND, 13, 30 | DEATHSCREAM3SND, 13, 31 | TAKEDAMAGESND, 14, 32 | PUSHWALLSND, 15, 33 | LEBENSND, 20, 34 | NAZIFIRESND, 21, 35 | SLURPIESND, 22, 36 | YEAHSND, 32, 37 | #ifndef UPLOAD 38 | DOGDEATHSND, 16, 39 | AHHHGSND, 17, 40 | DIESND, 18, 41 | EVASND, 19, 42 | TOT_HUNDSND, 23, 43 | MEINGOTTSND, 24, 44 | SCHABBSHASND, 25, 45 | HITLERHASND, 26, 46 | SPIONSND, 27, 47 | NEINSOVASSND, 28, 48 | DOGATTACKSND, 29, 49 | LEVELDONESND, 30, 50 | MECHSTEPSND, 31, 51 | 52 | SCHEISTSND, 33, 53 | DEATHSCREAM4SND, 34, /* AIIEEE */ 54 | DEATHSCREAM5SND, 35, /* DEE-DEE */ 55 | DONNERSND, 36, /* EPISODE 4 BOSS DIE */ 56 | EINESND, 37, /* EPISODE 4 BOSS SIGHTING */ 57 | ERLAUBENSND, 38, /* EPISODE 6 BOSS SIGHTING */ 58 | DEATHSCREAM6SND, 39, /* FART */ 59 | DEATHSCREAM7SND, 40, /* GASP */ 60 | DEATHSCREAM8SND, 41, /* GUH-BOY! */ 61 | DEATHSCREAM9SND, 42, /* AH GEEZ! */ 62 | KEINSND, 43, /* EPISODE 5 BOSS SIGHTING */ 63 | MEINSND, 44, /* EPISODE 6 BOSS DIE */ 64 | ROSESND, 45, /* EPISODE 5 BOSS DIE */ 65 | #endif 66 | 67 | #else /* SPEAR OF DESTINY DIGISOUNDS */ 68 | HALTSND, 0, 69 | CLOSEDOORSND, 2, 70 | OPENDOORSND, 3, 71 | ATKMACHINEGUNSND, 4, 72 | ATKPISTOLSND, 5, 73 | ATKGATLINGSND, 6, 74 | SCHUTZADSND, 7, 75 | BOSSFIRESND, 8, 76 | SSFIRESND, 9, 77 | DEATHSCREAM1SND, 10, 78 | DEATHSCREAM2SND, 11, 79 | TAKEDAMAGESND, 12, 80 | PUSHWALLSND, 13, 81 | AHHHGSND, 15, 82 | LEBENSND, 16, 83 | NAZIFIRESND, 17, 84 | SLURPIESND, 18, 85 | LEVELDONESND, 22, 86 | DEATHSCREAM4SND, 23, // AIIEEE 87 | DEATHSCREAM3SND, 23, // DOUBLY-MAPPED!!! 88 | DEATHSCREAM5SND, 24, // DEE-DEE 89 | DEATHSCREAM6SND, 25, // FART 90 | DEATHSCREAM7SND, 26, // GASP 91 | DEATHSCREAM8SND, 27, // GUH-BOY! 92 | DEATHSCREAM9SND, 28, // AH GEEZ! 93 | GETGATLINGSND, 38, // Got Gat replacement 94 | #ifndef SPEARDEMO 95 | DOGBARKSND, 1, 96 | DOGDEATHSND, 14, 97 | SPIONSND, 19, 98 | NEINSOVASSND, 20, 99 | DOGATTACKSND, 21, 100 | TRANSSIGHTSND, 29, // Trans Sight 101 | TRANSDEATHSND, 30, // Trans Death 102 | WILHELMSIGHTSND, 31, // Wilhelm Sight 103 | WILHELMDEATHSND, 32, // Wilhelm Death 104 | UBERDEATHSND, 33, // Uber Death 105 | KNIGHTSIGHTSND, 34, // Death Knight Sight 106 | KNIGHTDEATHSND, 35, // Death Knight Death 107 | ANGELSIGHTSND, 36, // Angel Sight 108 | ANGELDEATHSND, 37, // Angel Death 109 | GETSPEARSND, 39, // Got Spear replacement 110 | #endif 111 | #endif 112 | LASTSOUND 113 | }; 114 | 115 | void InitDigiMap() 116 | { 117 | int *map, i; 118 | 119 | for (i = 0; i < LASTSOUND; i++) 120 | DigiMap[i] = -1; 121 | 122 | for (map = wolfdigimap; *map != LASTSOUND; map += 2) 123 | DigiMap[map[0]] = map[1]; 124 | } 125 | -------------------------------------------------------------------------------- /source/wl_play.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rinnegatamante/ctrWolfen/f243d125d66f6ffea08f9580728075d6c36a3144/source/wl_play.c --------------------------------------------------------------------------------