This commit is contained in:
profi200 2015-01-16 17:41:38 +00:00
commit 7bbc594cf7
30 changed files with 1788 additions and 1789 deletions

View File

@ -24,7 +24,7 @@ bufferMatrix_s bufferMatrixList[BUFFERMATRIXLIST_SIZE];
int bufferMatrixListLength; int bufferMatrixListLength;
//---------------------- //----------------------
// GS SYSTEM STUFF // GS SYSTEM STUFF
//---------------------- //----------------------
void initBufferMatrixList() void initBufferMatrixList()
@ -74,7 +74,7 @@ void gsLinearFree(void* mem)
} }
//---------------------- //----------------------
// MATRIX STACK STUFF // MATRIX STACK STUFF
//---------------------- //----------------------
static mtx44 gsMatrixStacks[GS_MATRIXTYPES][GS_MATRIXSTACK_SIZE]; static mtx44 gsMatrixStacks[GS_MATRIXTYPES][GS_MATRIXSTACK_SIZE];
@ -149,7 +149,7 @@ int gsMatrixMode(GS_MATRIX m)
} }
//------------------------ //------------------------
// MATRIX TRANSFORM STUFF // MATRIX TRANSFORM STUFF
//------------------------ //------------------------
int gsMultMatrix(float* data) int gsMultMatrix(float* data)
@ -208,7 +208,7 @@ void gsTranslate(float x, float y, float z)
} }
//---------------------- //----------------------
// MATRIX RENDER STUFF // MATRIX RENDER STUFF
//---------------------- //----------------------
static void gsSetUniformMatrix(u32 startreg, float* m) static void gsSetUniformMatrix(u32 startreg, float* m)
@ -279,7 +279,7 @@ void gsAdjustBufferMatrices(mtx44 transformation)
} }
//---------------------- //----------------------
// VBO STUFF // VBO STUFF
//---------------------- //----------------------
int gsVboInit(gsVbo_s* vbo) int gsVboInit(gsVbo_s* vbo)

View File

@ -1,6 +1,6 @@
/////////////////////////////////////// //////////////////////////////////////
// GPU example // // GPU example //
/////////////////////////////////////// //////////////////////////////////////
//this example is meant to show how to use the GPU to render a 3D object //this example is meant to show how to use the GPU to render a 3D object
//it also shows how to do stereoscopic 3D //it also shows how to do stereoscopic 3D

View File

@ -1,6 +1,6 @@
/////////////////////////////////////// //////////////////////////////////////
// SDMC example // // SDMC example //
/////////////////////////////////////// //////////////////////////////////////
//this example shows you how to load a binary image file from the SD card and display it on the lower screen //this example shows you how to load a binary image file from the SD card and display it on the lower screen
//for this to work you should copy test.bin to same folder as your .3dsx //for this to work you should copy test.bin to same folder as your .3dsx

View File

@ -1,7 +1,7 @@
/*! \file console.h /*! \file console.h
\brief 3ds stdio support. \brief 3ds stdio support.
<div class="fileHeader"> <div class="fileHeader">
Provides stdio integration for printing to the 3DS screen as well as debug print Provides stdio integration for printing to the 3DS screen as well as debug print
@ -29,7 +29,7 @@ typedef bool(* ConsolePrint)(void* con, int c);
typedef struct ConsoleFont typedef struct ConsoleFont
{ {
u8* gfx; //!< A pointer to the font graphics u8* gfx; //!< A pointer to the font graphics
u16 asciiOffset; //!< Offset to the first valid character in the font table u16 asciiOffset; //!< Offset to the first valid character in the font table
u16 numChars; //!< Number of characters in the font graphics u16 numChars; //!< Number of characters in the font graphics
}ConsoleFont; }ConsoleFont;
@ -50,13 +50,13 @@ PrintConsole defaultConsole =
0,0, //prevcursorX prevcursorY 0,0, //prevcursorX prevcursorY
40, //console width 40, //console width
30, //console height 30, //console height
0, //window x 0, //window x
0, //window y 0, //window y
32, //window width 32, //window width
24, //window height 24, //window height
3, //tab size 3, //tab size
0, //font character offset 0, //font character offset
0, //print callback 0, //print callback
false //console initialized false //console initialized
}; };
</pre></div> </pre></div>
@ -74,7 +74,7 @@ typedef struct PrintConsole
int prevCursorY; /*!< Internal state */ int prevCursorY; /*!< Internal state */
int consoleWidth; /*!< Width of the console hardware layer in characters */ int consoleWidth; /*!< Width of the console hardware layer in characters */
int consoleHeight; /*!< Height of the console hardware layer in characters */ int consoleHeight; /*!< Height of the console hardware layer in characters */
int windowX; /*!< Window X location in characters (not implemented) */ int windowX; /*!< Window X location in characters (not implemented) */
int windowY; /*!< Window Y location in characters (not implemented) */ int windowY; /*!< Window Y location in characters (not implemented) */

View File

@ -23,17 +23,17 @@ typedef enum{
}APP_STATUS; }APP_STATUS;
enum { enum {
APTSIGNAL_HOMEBUTTON = 1, APTSIGNAL_HOMEBUTTON = 1,
// 2: sleep-mode related? // 2: sleep-mode related?
APTSIGNAL_PREPARESLEEP = 3, APTSIGNAL_PREPARESLEEP = 3,
// 4: triggered when ptm:s GetShellStatus() returns 5. // 4: triggered when ptm:s GetShellStatus() returns 5.
APTSIGNAL_ENTERSLEEP = 5, APTSIGNAL_ENTERSLEEP = 5,
APTSIGNAL_WAKEUP = 6, APTSIGNAL_WAKEUP = 6,
APTSIGNAL_ENABLE = 7, APTSIGNAL_ENABLE = 7,
APTSIGNAL_POWERBUTTON = 8, APTSIGNAL_POWERBUTTON = 8,
APTSIGNAL_UTILITY = 9, APTSIGNAL_UTILITY = 9,
APTSIGNAL_SLEEPSYSTEM = 10, APTSIGNAL_SLEEPSYSTEM = 10,
APTSIGNAL_ERROR = 11 APTSIGNAL_ERROR = 11
}; };
@ -82,4 +82,3 @@ Result APT_DoAppJump(Handle* handle, u32 NSbuf0Size, u32 NSbuf1Size, u8 *NSbuf0P
Result APT_PrepareToStartLibraryApplet(Handle* handle, NS_APPID appID); Result APT_PrepareToStartLibraryApplet(Handle* handle, NS_APPID appID);
Result APT_StartLibraryApplet(Handle* handle, NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize); Result APT_StartLibraryApplet(Handle* handle, NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize);
Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize);//This should be used for launching library applets, this uses the above APT_StartLibraryApplet/APT_PrepareToStartLibraryApplet funcs + apt*Session(). parambuf is used for APT params input, when the applet closes the output param block is copied here. This is not usable from the homebrew launcher. This is broken: when the applet does get launched at all, the applet process doesn't actually get terminated when the applet gets closed. Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize);//This should be used for launching library applets, this uses the above APT_StartLibraryApplet/APT_PrepareToStartLibraryApplet funcs + apt*Session(). parambuf is used for APT params input, when the applet closes the output param block is copied here. This is not usable from the homebrew launcher. This is broken: when the applet does get launched at all, the applet process doesn't actually get terminated when the applet gets closed.

View File

@ -3,67 +3,67 @@
/*! @file FS.h /*! @file FS.h
* *
* Filesystem Services * Filesystem Services
*/ */
/*! @defgroup fs_open_flags FS Open Flags /*! @defgroup fs_open_flags FS Open Flags
* *
* @sa FSUSER_OpenFile * @sa FSUSER_OpenFile
* @sa FSUSER_OpenFileDirectly * @sa FSUSER_OpenFileDirectly
* *
* @{ * @{
*/ */
/*! Open file for read. */ /*! Open file for read. */
#define FS_OPEN_READ (1<<0) #define FS_OPEN_READ (1<<0)
/*! Open file for write. */ /*! Open file for write. */
#define FS_OPEN_WRITE (1<<1) #define FS_OPEN_WRITE (1<<1)
/*! Create file if it doesn't exist. */ /*! Create file if it doesn't exist. */
#define FS_OPEN_CREATE (1<<2) #define FS_OPEN_CREATE (1<<2)
/* @} */ /* @} */
/*! @defgroup fs_create_attributes FS Create Attributes /*! @defgroup fs_create_attributes FS Create Attributes
* *
* @sa FSUSER_OpenFile * @sa FSUSER_OpenFile
* @sa FSUSER_OpenFileDirectly * @sa FSUSER_OpenFileDirectly
* *
* @{ * @{
*/ */
/*! No attributes. */ /*! No attributes. */
#define FS_ATTRIBUTE_NONE (0x00000000) #define FS_ATTRIBUTE_NONE (0x00000000)
/*! Create with read-only attribute. */ /*! Create with read-only attribute. */
#define FS_ATTRIBUTE_READONLY (0x00000001) #define FS_ATTRIBUTE_READONLY (0x00000001)
/*! Create with archive attribute. */ /*! Create with archive attribute. */
#define FS_ATTRIBUTE_ARCHIVE (0x00000100) #define FS_ATTRIBUTE_ARCHIVE (0x00000100)
/*! Create with hidden attribute. */ /*! Create with hidden attribute. */
#define FS_ATTRIBUTE_HIDDEN (0x00010000) #define FS_ATTRIBUTE_HIDDEN (0x00010000)
/*! Create with directory attribute. */ /*! Create with directory attribute. */
#define FS_ATTRIBUTE_DIRECTORY (0x01000000) #define FS_ATTRIBUTE_DIRECTORY (0x01000000)
/*! @} */ /*! @} */
/*! @defgroup fs_write_flush_flags FS Flush Flags /*! @defgroup fs_write_flush_flags FS Flush Flags
* *
* @sa FSFILE_Write * @sa FSFILE_Write
* *
* @{ * @{
*/ */
/*! Don't flush */ /*! Don't flush */
#define FS_WRITE_NOFLUSH (0x00000000) #define FS_WRITE_NOFLUSH (0x00000000)
/*! Flush */ /*! Flush */
#define FS_WRITE_FLUSH (0x00010001) #define FS_WRITE_FLUSH (0x00010001)
/* @} */ /* @} */
/*! FS path type */ /*! FS path type */
typedef enum typedef enum
{ {
PATH_INVALID = 0, //!< Specifies an invalid path. PATH_INVALID = 0, //!< Specifies an invalid path.
PATH_EMPTY = 1, //!< Specifies an empty path. PATH_EMPTY = 1, //!< Specifies an empty path.
PATH_BINARY = 2, //!< Specifies a binary path, which is non-text based. PATH_BINARY = 2, //!< Specifies a binary path, which is non-text based.
PATH_CHAR = 3, //!< Specifies a text based path with a 8-bit byte per character. PATH_CHAR = 3, //!< Specifies a text based path with a 8-bit byte per character.
PATH_WCHAR = 4, //!< Specifies a text based path with a 16-bit short per character. PATH_WCHAR = 4, //!< Specifies a text based path with a 16-bit short per character.
} FS_pathType; } FS_pathType;
/*! FS archive ids */ /*! FS archive ids */
@ -86,51 +86,51 @@ typedef enum
/*! FS path */ /*! FS path */
typedef struct typedef struct
{ {
FS_pathType type; //!< FS path type. FS_pathType type; //!< FS path type.
u32 size; //!< FS path size. u32 size; //!< FS path size.
const u8 *data; //!< Pointer to FS path data. const u8 *data; //!< Pointer to FS path data.
} FS_path; } FS_path;
/*! FS archive */ /*! FS archive */
typedef struct typedef struct
{ {
u32 id; //!< Archive ID. u32 id; //!< Archive ID.
FS_path lowPath; //!< FS path. FS_path lowPath; //!< FS path.
Handle handleLow; //!< High word of handle. Handle handleLow; //!< High word of handle.
Handle handleHigh; //!< Low word of handle. Handle handleHigh; //!< Low word of handle.
} FS_archive; } FS_archive;
/*! Directory entry */ /*! Directory entry */
typedef struct typedef struct
{ {
// 0x00 // 0x00
u16 name[0x106]; //!< UTF-16 encoded name u16 name[0x106]; //!< UTF-16 encoded name
// 0x20C // 0x20C
u8 shortName[0x09]; //!< 8.3 file name u8 shortName[0x09]; //!< 8.3 file name
// 0x215 // 0x215
u8 unknown1; //!< ??? u8 unknown1; //!< ???
// 0x216 // 0x216
u8 shortExt[0x04]; //!< 8.3 file extension (set to spaces for directories) u8 shortExt[0x04]; //!< 8.3 file extension (set to spaces for directories)
// 0x21A // 0x21A
u8 unknown2; //!< ??? u8 unknown2; //!< ???
// 0x21B // 0x21B
u8 unknown3; //!< ??? u8 unknown3; //!< ???
// 0x21C // 0x21C
u8 isDirectory; //!< directory bit u8 isDirectory; //!< directory bit
// 0x21D // 0x21D
u8 isHidden; //!< hidden bit u8 isHidden; //!< hidden bit
// 0x21E // 0x21E
u8 isArchive; //!< archive bit u8 isArchive; //!< archive bit
// 0x21F // 0x21F
u8 isReadOnly; //!< read-only bit u8 isReadOnly; //!< read-only bit
// 0x220 // 0x220
u64 fileSize; //!< file size u64 fileSize; //!< file size
} FS_dirent; } FS_dirent;
Result fsInit(void); Result fsInit(void);
Result fsExit(void); Result fsExit(void);
FS_path FS_makePath(FS_pathType type, const char *path); FS_path FS_makePath(FS_pathType type, const char *path);
Result FSUSER_Initialize(Handle* handle); Result FSUSER_Initialize(Handle* handle);
Result FSUSER_OpenArchive(Handle* handle, FS_archive* archive); Result FSUSER_OpenArchive(Handle* handle, FS_archive* archive);

View File

@ -6,35 +6,35 @@
typedef enum typedef enum
{ {
KEY_A = BIT(0), KEY_A = BIT(0),
KEY_B = BIT(1), KEY_B = BIT(1),
KEY_SELECT = BIT(2), KEY_SELECT = BIT(2),
KEY_START = BIT(3), KEY_START = BIT(3),
KEY_DRIGHT = BIT(4), KEY_DRIGHT = BIT(4),
KEY_DLEFT = BIT(5), KEY_DLEFT = BIT(5),
KEY_DUP = BIT(6), KEY_DUP = BIT(6),
KEY_DDOWN = BIT(7), KEY_DDOWN = BIT(7),
KEY_R = BIT(8), KEY_R = BIT(8),
KEY_L = BIT(9), KEY_L = BIT(9),
KEY_X = BIT(10), KEY_X = BIT(10),
KEY_Y = BIT(11), KEY_Y = BIT(11),
KEY_ZL = BIT(14), // (new 3DS only) KEY_ZL = BIT(14), // (new 3DS only)
KEY_ZR = BIT(15), // (new 3DS only) KEY_ZR = BIT(15), // (new 3DS only)
KEY_TOUCH = BIT(20), // Not actually provided by HID KEY_TOUCH = BIT(20), // Not actually provided by HID
KEY_CSTICK_RIGHT = BIT(24), // c-stick (new 3DS only) KEY_CSTICK_RIGHT = BIT(24), // c-stick (new 3DS only)
KEY_CSTICK_LEFT = BIT(25), // c-stick (new 3DS only) KEY_CSTICK_LEFT = BIT(25), // c-stick (new 3DS only)
KEY_CSTICK_UP = BIT(26), // c-stick (new 3DS only) KEY_CSTICK_UP = BIT(26), // c-stick (new 3DS only)
KEY_CSTICK_DOWN = BIT(27), // c-stick (new 3DS only) KEY_CSTICK_DOWN = BIT(27), // c-stick (new 3DS only)
KEY_CPAD_RIGHT = BIT(28), // circle pad KEY_CPAD_RIGHT = BIT(28), // circle pad
KEY_CPAD_LEFT = BIT(29), // circle pad KEY_CPAD_LEFT = BIT(29), // circle pad
KEY_CPAD_UP = BIT(30), // circle pad KEY_CPAD_UP = BIT(30), // circle pad
KEY_CPAD_DOWN = BIT(31), // circle pad KEY_CPAD_DOWN = BIT(31), // circle pad
// Generic catch-all directions // Generic catch-all directions
KEY_UP = KEY_DUP | KEY_CPAD_UP, KEY_UP = KEY_DUP | KEY_CPAD_UP,
KEY_DOWN = KEY_DDOWN | KEY_CPAD_DOWN, KEY_DOWN = KEY_DDOWN | KEY_CPAD_DOWN,
KEY_LEFT = KEY_DLEFT | KEY_CPAD_LEFT, KEY_LEFT = KEY_DLEFT | KEY_CPAD_LEFT,
KEY_RIGHT = KEY_DRIGHT | KEY_CPAD_RIGHT, KEY_RIGHT = KEY_DRIGHT | KEY_CPAD_RIGHT,
} PAD_KEY; } PAD_KEY;
typedef struct typedef struct
@ -90,12 +90,12 @@ void hidGyroRead(angularRate* rate);
void hidWaitForEvent(HID_Event id, bool nextEvent); void hidWaitForEvent(HID_Event id, bool nextEvent);
// libnds compatibility defines // libnds compatibility defines
#define scanKeys hidScanInput #define scanKeys hidScanInput
#define keysHeld hidKeysHeld #define keysHeld hidKeysHeld
#define keysDown hidKeysDown #define keysDown hidKeysDown
#define keysUp hidKeysUp #define keysUp hidKeysUp
#define touchRead hidTouchRead #define touchRead hidTouchRead
#define circleRead hidCircleRead #define circleRead hidCircleRead
Result HIDUSER_GetHandles(Handle* outMemHandle, Handle *eventpad0, Handle *eventpad1, Handle *eventaccel, Handle *eventgyro, Handle *eventdebugpad); Result HIDUSER_GetHandles(Handle* outMemHandle, Handle *eventpad0, Handle *eventpad1, Handle *eventaccel, Handle *eventgyro, Handle *eventdebugpad);
Result HIDUSER_EnableAccelerometer(); Result HIDUSER_EnableAccelerometer();

View File

@ -1,45 +1,45 @@
/* /*
svc.h _ Syscall wrappers. svc.h _ Syscall wrappers.
*/ */
#pragma once #pragma once
typedef enum { typedef enum {
MEMOP_FREE =1, // Free heap MEMOP_FREE =1, // Free heap
MEMOP_ALLOC=3, // Allocate heap MEMOP_ALLOC =3, // Allocate heap
MEMOP_MAP =4, // Mirror mapping MEMOP_MAP =4, // Mirror mapping
MEMOP_UNMAP=5, // Mirror unmapping MEMOP_UNMAP =5, // Mirror unmapping
MEMOP_PROT =6, // Change protection MEMOP_PROT =6, // Change protection
MEMOP_FREE_LINEAR =0x10001, // Free linear heap MEMOP_FREE_LINEAR =0x10001, // Free linear heap
MEMOP_ALLOC_LINEAR=0x10003 // Allocate linear heap MEMOP_ALLOC_LINEAR=0x10003 // Allocate linear heap
} MemOp; } MemOp;
typedef enum { typedef enum {
MEMPERM_READ = 1, MEMPERM_READ = 1,
MEMPERM_WRITE = 2, MEMPERM_WRITE = 2,
MEMPERM_EXECUTE = 4, MEMPERM_EXECUTE = 4,
MEMPERM_DONTCARE = 0x10000000, MEMPERM_DONTCARE = 0x10000000,
MEMPERM_MAX = 0xFFFFFFFF //force 4-byte MEMPERM_MAX = 0xFFFFFFFF //force 4-byte
} MemPerm; } MemPerm;
typedef struct { typedef struct {
u32 base_addr; u32 base_addr;
u32 size; u32 size;
u32 perm; u32 perm;
u32 state; u32 state;
} MemInfo; } MemInfo;
typedef struct { typedef struct {
u32 flags; u32 flags;
} PageInfo; } PageInfo;
typedef enum { typedef enum {
ARBITER_FREE =0, ARBITER_FREE =0,
ARBITER_ACQUIRE =1, ARBITER_ACQUIRE =1,
ARBITER_KERNEL2 =2, ARBITER_KERNEL2 =2,
ARBITER_ACQUIRE_TIMEOUT=3, ARBITER_ACQUIRE_TIMEOUT =3,
ARBITER_KERNEL4 =4, ARBITER_KERNEL4 =4,
} ArbitrationType; } ArbitrationType;
static inline void* getThreadLocalStorage(void) static inline void* getThreadLocalStorage(void)
@ -54,38 +54,38 @@ static inline u32* getThreadCommandBuffer(void)
return (u32*)((u8*)getThreadLocalStorage() + 0x80); return (u32*)((u8*)getThreadLocalStorage() + 0x80);
} }
s32 svcControlMemory(u32* addr_out, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm); s32 svcControlMemory(u32* addr_out, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm);
s32 svcQueryMemory(MemInfo* info, PageInfo* out, u32 addr); s32 svcQueryMemory(MemInfo* info, PageInfo* out, u32 addr);
void __attribute__((noreturn)) svcExitProcess(); void __attribute__((noreturn)) svcExitProcess();
s32 svcCreateThread(Handle* thread, ThreadFunc entrypoint, u32 arg, u32* stack_top, s32 thread_priority, s32 processor_id); s32 svcCreateThread(Handle* thread, ThreadFunc entrypoint, u32 arg, u32* stack_top, s32 thread_priority, s32 processor_id);
void __attribute__((noreturn)) svcExitThread(); void __attribute__((noreturn)) svcExitThread();
void svcSleepThread(s64 ns); void svcSleepThread(s64 ns);
s32 svcSetThreadPriority(Handle thread, s32 prio); s32 svcSetThreadPriority(Handle thread, s32 prio);
s32 svcCreateMutex(Handle* mutex, bool initially_locked); s32 svcCreateMutex(Handle* mutex, bool initially_locked);
s32 svcReleaseMutex(Handle handle); s32 svcReleaseMutex(Handle handle);
s32 svcCreateSemaphore(Handle* semaphore, s32 initial_count, s32 max_count); s32 svcCreateSemaphore(Handle* semaphore, s32 initial_count, s32 max_count);
s32 svcReleaseSemaphore(s32* count, Handle semaphore, s32 release_count); s32 svcReleaseSemaphore(s32* count, Handle semaphore, s32 release_count);
s32 svcCreateEvent(Handle* event, u8 reset_type); s32 svcCreateEvent(Handle* event, u8 reset_type);
s32 svcSignalEvent(Handle handle); s32 svcSignalEvent(Handle handle);
s32 svcClearEvent(Handle handle); s32 svcClearEvent(Handle handle);
s32 svcCreateTimer(Handle* timer, u8 reset_type); s32 svcCreateTimer(Handle* timer, u8 reset_type);
s32 svcSetTimer(Handle timer, s64 initial, s64 interval); s32 svcSetTimer(Handle timer, s64 initial, s64 interval);
s32 svcCancelTimer(Handle timer); s32 svcCancelTimer(Handle timer);
s32 svcClearTimer(Handle timer); s32 svcClearTimer(Handle timer);
s32 svcCreateMemoryBlock(Handle* memblock, u32 addr, u32 size, MemPerm my_perm, MemPerm other_perm); s32 svcCreateMemoryBlock(Handle* memblock, u32 addr, u32 size, MemPerm my_perm, MemPerm other_perm);
s32 svcMapMemoryBlock(Handle memblock, u32 addr, MemPerm my_perm, MemPerm other_perm); s32 svcMapMemoryBlock(Handle memblock, u32 addr, MemPerm my_perm, MemPerm other_perm);
s32 svcUnmapMemoryBlock(Handle memblock, u32 addr); s32 svcUnmapMemoryBlock(Handle memblock, u32 addr);
s32 svcCreateAddressArbiter(Handle *arbiter); s32 svcCreateAddressArbiter(Handle *arbiter);
s32 svcArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds); s32 svcArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds);
s32 svcWaitSynchronization(Handle handle, s64 nanoseconds); s32 svcWaitSynchronization(Handle handle, s64 nanoseconds);
s32 svcWaitSynchronizationN(s32* out, Handle* handles, s32 handles_num, bool wait_all, s64 nanoseconds); s32 svcWaitSynchronizationN(s32* out, Handle* handles, s32 handles_num, bool wait_all, s64 nanoseconds);
s32 svcCloseHandle(Handle handle); s32 svcCloseHandle(Handle handle);
s32 svcDuplicateHandle(Handle* out, Handle original); s32 svcDuplicateHandle(Handle* out, Handle original);
u64 svcGetSystemTick(); u64 svcGetSystemTick();
s32 svcGetSystemInfo(s64* out, u32 type, s32 param); s32 svcGetSystemInfo(s64* out, u32 type, s32 param);
s32 svcGetProcessInfo(s64* out, Handle process, u32 type); s32 svcGetProcessInfo(s64* out, Handle process, u32 type);
s32 svcConnectToPort(volatile Handle* out, const char* portName); s32 svcConnectToPort(volatile Handle* out, const char* portName);
s32 svcSendSyncRequest(Handle session); s32 svcSendSyncRequest(Handle session);
s32 svcGetProcessId(u32 *out, Handle handle); s32 svcGetProcessId(u32 *out, Handle handle);
s32 svcGetThreadId(u32 *out, Handle handle); s32 svcGetThreadId(u32 *out, Handle handle);
s32 svcOutputDebugString(const char* str, int length); s32 svcOutputDebugString(const char* str, int length);

View File

@ -4,25 +4,25 @@
#include <stddef.h> #include <stddef.h>
#define rbtree_item(ptr, type, member) \ #define rbtree_item(ptr, type, member) \
((type*)(((char*)ptr) - offsetof(type, member))) ((type*)(((char*)ptr) - offsetof(type, member)))
typedef struct rbtree rbtree_t; typedef struct rbtree rbtree_t;
typedef struct rbtree_node rbtree_node_t; typedef struct rbtree_node rbtree_node_t;
typedef void (*rbtree_node_destructor_t)(rbtree_node_t *Node); typedef void (*rbtree_node_destructor_t)(rbtree_node_t *Node);
typedef int (*rbtree_node_comparator_t)(const rbtree_node_t *lhs, typedef int (*rbtree_node_comparator_t)(const rbtree_node_t *lhs,
const rbtree_node_t *rhs); const rbtree_node_t *rhs);
struct rbtree_node struct rbtree_node
{ {
uintptr_t parent_color; uintptr_t parent_color;
rbtree_node_t *child[2]; rbtree_node_t *child[2];
}; };
struct rbtree struct rbtree
{ {
rbtree_node_t *root; rbtree_node_t *root;
rbtree_node_comparator_t comparator; rbtree_node_comparator_t comparator;
size_t size; size_t size;
}; };
#ifdef __cplusplus #ifdef __cplusplus
@ -30,8 +30,8 @@ extern "C" {
#endif #endif
void void
rbtree_init(rbtree_t *tree, rbtree_init(rbtree_t *tree,
rbtree_node_comparator_t comparator); rbtree_node_comparator_t comparator);
int int
rbtree_empty(const rbtree_t *tree); rbtree_empty(const rbtree_t *tree);
@ -41,16 +41,16 @@ rbtree_size(const rbtree_t *tree);
__attribute__((warn_unused_result)) __attribute__((warn_unused_result))
rbtree_node_t* rbtree_node_t*
rbtree_insert(rbtree_t *tree, rbtree_insert(rbtree_t *tree,
rbtree_node_t *node); rbtree_node_t *node);
void void
rbtree_insert_multi(rbtree_t *tree, rbtree_insert_multi(rbtree_t *tree,
rbtree_node_t *node); rbtree_node_t *node);
rbtree_node_t* rbtree_node_t*
rbtree_find(const rbtree_t *tree, rbtree_find(const rbtree_t *tree,
const rbtree_node_t *node); const rbtree_node_t *node);
rbtree_node_t* rbtree_node_t*
rbtree_min(const rbtree_t *tree); rbtree_min(const rbtree_t *tree);
@ -65,13 +65,13 @@ rbtree_node_t*
rbtree_node_prev(const rbtree_node_t *node); rbtree_node_prev(const rbtree_node_t *node);
rbtree_node_t* rbtree_node_t*
rbtree_remove(rbtree_t *tree, rbtree_remove(rbtree_t *tree,
rbtree_node_t *node, rbtree_node_t *node,
rbtree_node_destructor_t destructor); rbtree_node_destructor_t destructor);
void void
rbtree_clear(rbtree_t *tree, rbtree_clear(rbtree_t *tree,
rbtree_node_destructor_t destructor); rbtree_node_destructor_t destructor);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -63,9 +63,9 @@ bool MemPool::Allocate(MemChunk& chunk, u32 size, int align)
if (nSize) if (nSize)
{ {
// We need to add the tail chunk that wasn't used to the list // We need to add the tail chunk that wasn't used to the list
auto n = MemBlock::Create(nAddr, nSize); auto n = MemBlock::Create(nAddr, nSize);
if (n) InsertAfter(b, n); if (n) InsertAfter(b, n);
else chunk.size += nSize; // we have no choice but to waste the space. else chunk.size += nSize; // we have no choice but to waste the space.
} }
} }
return true; return true;
@ -76,9 +76,9 @@ bool MemPool::Allocate(MemChunk& chunk, u32 size, int align)
void MemPool::Deallocate(const MemChunk& chunk) void MemPool::Deallocate(const MemChunk& chunk)
{ {
u8* cAddr = chunk.addr; u8* cAddr = chunk.addr;
auto cSize = chunk.size; auto cSize = chunk.size;
bool done = false; bool done = false;
// Try to merge the chunk somewhere into the list // Try to merge the chunk somewhere into the list
for (auto b = first; !done && b; b = b->next) for (auto b = first; !done && b; b = b->next)
@ -121,7 +121,7 @@ void MemPool::Dump(const char* title)
{ {
printf("<%s> VRAM Pool Dump\n", title); printf("<%s> VRAM Pool Dump\n", title);
for (auto b = first; b; b = b->next) for (auto b = first; b; b = b->next)
printf(" - %p (%u bytes)\n", b->base, b->size); printf(" - %p (%u bytes)\n", b->base, b->size);
} }
*/ */

View File

@ -31,17 +31,17 @@ void gfxSet3D(bool enable)
} }
void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format) { void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format) {
if(screen==GFX_TOP) if(screen==GFX_TOP)
topFormat = format; topFormat = format;
else else
botFormat = format; botFormat = format;
} }
GSP_FramebufferFormats gfxGetScreenFormat(gfxScreen_t screen) { GSP_FramebufferFormats gfxGetScreenFormat(gfxScreen_t screen) {
if(screen==GFX_TOP) if(screen==GFX_TOP)
return topFormat; return topFormat;
else else
return botFormat; return botFormat;
} }
void gfxSetDoubleBuffering( gfxScreen_t screen, bool doubleBuffering) { void gfxSetDoubleBuffering( gfxScreen_t screen, bool doubleBuffering) {
@ -49,18 +49,18 @@ void gfxSetDoubleBuffering( gfxScreen_t screen, bool doubleBuffering) {
} }
static u32 __get_bytes_per_pixel(GSP_FramebufferFormats format) { static u32 __get_bytes_per_pixel(GSP_FramebufferFormats format) {
switch(format) { switch(format) {
case GSP_RGBA8_OES: case GSP_RGBA8_OES:
return 4; return 4;
case GSP_BGR8_OES: case GSP_BGR8_OES:
return 3; return 3;
case GSP_RGB565_OES: case GSP_RGB565_OES:
case GSP_RGB5_A1_OES: case GSP_RGB5_A1_OES:
case GSP_RGBA4_OES: case GSP_RGBA4_OES:
return 2; return 2;
} }
return 3; return 3;
} }
void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id) void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -39,14 +39,14 @@ Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy)
if(ret!=0) { if(ret!=0) {
HTTPC_CloseContext(__httpc_servhandle, context->httphandle); HTTPC_CloseContext(__httpc_servhandle, context->httphandle);
return ret; return ret;
} }
ret = HTTPC_InitializeConnectionSession(context->servhandle, context->httphandle); ret = HTTPC_InitializeConnectionSession(context->servhandle, context->httphandle);
if(ret!=0) { if(ret!=0) {
HTTPC_CloseContext(__httpc_servhandle, context->httphandle); HTTPC_CloseContext(__httpc_servhandle, context->httphandle);
svcCloseHandle(context->servhandle); svcCloseHandle(context->servhandle);
return ret; return ret;
} }
if(use_defaultproxy==0)return 0; if(use_defaultproxy==0)return 0;
@ -55,7 +55,7 @@ Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy)
HTTPC_CloseContext(__httpc_servhandle, context->httphandle); HTTPC_CloseContext(__httpc_servhandle, context->httphandle);
svcCloseHandle(context->servhandle); svcCloseHandle(context->servhandle);
return ret; return ret;
} }
return 0; return 0;
} }

View File

@ -5,8 +5,8 @@
#define O_NONBLOCK_3DS 0x4 #define O_NONBLOCK_3DS 0x4
#define ALL_3DS (O_NONBLOCK_3DS) #define ALL_3DS (O_NONBLOCK_3DS)
#define ALL_FLAGS (O_NONBLOCK) #define ALL_FLAGS (O_NONBLOCK)
static int from_3ds(int flags) static int from_3ds(int flags)
{ {

View File

@ -2,9 +2,9 @@
#include <netdb.h> #include <netdb.h>
#define MAX_HOSTENT_RESULTS 16 #define MAX_HOSTENT_RESULTS 16
static struct hostent SOC_hostent; static struct hostent SOC_hostent;
static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1]; static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1];
static char *SOC_hostent_alias = NULL; static char *SOC_hostent_alias = NULL;
int h_errno = 0; int h_errno = 0;
@ -30,11 +30,11 @@ struct hostent* gethostbyname(const char *name)
if(( ret = svcSendSyncRequest(SOCU_handle))!=0)return NULL; if(( ret = svcSendSyncRequest(SOCU_handle))!=0)return NULL;
cmdbuf[0x100>>2] = saved_threadstorage[0]; cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1]; cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1]; ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]); if(ret==0)ret = _net_convert_error(cmdbuf[2]);
if(ret<0)SOCU_errno = ret; if(ret<0)SOCU_errno = ret;
/* TODO: set h_errno based on SOCU_errno */ /* TODO: set h_errno based on SOCU_errno */
if(ret<0)return NULL; if(ret<0)return NULL;
@ -44,11 +44,11 @@ struct hostent* gethostbyname(const char *name)
if(num_results > MAX_HOSTENT_RESULTS) if(num_results > MAX_HOSTENT_RESULTS)
num_results = MAX_HOSTENT_RESULTS; num_results = MAX_HOSTENT_RESULTS;
SOC_hostent.h_name = (char*)outbuf + 8; SOC_hostent.h_name = (char*)outbuf + 8;
SOC_hostent.h_aliases = &SOC_hostent_alias; SOC_hostent.h_aliases = &SOC_hostent_alias;
SOC_hostent.h_addrtype = AF_INET; SOC_hostent.h_addrtype = AF_INET;
SOC_hostent.h_length = 4; SOC_hostent.h_length = 4;
SOC_hostent.h_addr_list = SOC_hostent_results; SOC_hostent.h_addr_list = SOC_hostent_results;
SOC_hostent_alias = NULL; SOC_hostent_alias = NULL;

View File

@ -5,11 +5,11 @@
int inet_aton(const char *cp, struct in_addr *inp) int inet_aton(const char *cp, struct in_addr *inp)
{ {
int base; int base;
uint32_t val; uint32_t val;
int c; int c;
char bytes[4]; char bytes[4];
size_t num_bytes = 0; size_t num_bytes = 0;
c = *cp; c = *cp;
for(;;) { for(;;) {
@ -31,12 +31,12 @@ int inet_aton(const char *cp, struct in_addr *inp)
if(base == 8 && c >= '8') return 0; if(base == 8 && c >= '8') return 0;
val *= base; val *= base;
val += c - '0'; val += c - '0';
c = *++cp; c = *++cp;
} }
else if(base == 16 && isxdigit(c)) { else if(base == 16 && isxdigit(c)) {
val *= base; val *= base;
val += c + 10 - (islower(c) ? 'a' : 'A'); val += c + 10 - (islower(c) ? 'a' : 'A');
c = *++cp; c = *++cp;
} }
else break; else break;
} }

View File

@ -28,8 +28,8 @@ int ioctl(int fd, int request, ...)
return -1; return -1;
} }
if(*value) ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); if(*value) ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
else ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); else ret = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
if(ret != 0) if(ret != 0)
errno = SOC_GetErrno(); errno = SOC_GetErrno();

View File

@ -24,7 +24,7 @@ int poll(struct pollfd *fds, nfds_t nfsd, int timeout)
if((ret = svcSendSyncRequest(SOCU_handle)) != 0)return ret; if((ret = svcSendSyncRequest(SOCU_handle)) != 0)return ret;
cmdbuf[0x100>>2] = saved_threadstorage[0]; cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1]; cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1]; ret = (int)cmdbuf[1];
if(ret==0)ret = _net_convert_error(cmdbuf[2]); if(ret==0)ret = _net_convert_error(cmdbuf[2]);

View File

@ -28,9 +28,9 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struc
if((readfds && FD_ISSET(i, readfds)) if((readfds && FD_ISSET(i, readfds))
|| (writefds && FD_ISSET(i, writefds)) || (writefds && FD_ISSET(i, writefds))
|| (exceptfds && FD_ISSET(i, exceptfds))) { || (exceptfds && FD_ISSET(i, exceptfds))) {
pollinfo[j].fd = i; pollinfo[j].fd = i;
pollinfo[j].events = 0; pollinfo[j].events = 0;
pollinfo[j].revents = 0; pollinfo[j].revents = 0;
if(readfds && FD_ISSET(i, readfds)) if(readfds && FD_ISSET(i, readfds))
pollinfo[j].events |= POLLIN; pollinfo[j].events |= POLLIN;

View File

@ -1,5 +1,5 @@
/* /*
srv.c _ Service manager. srv.c _ Service manager.
*/ */
#include <string.h> #include <string.h>
@ -9,15 +9,15 @@
/* /*
The homebrew loader can choose to supply a list of service handles that have The homebrew loader can choose to supply a list of service handles that have
been "stolen" from other processes that have been compromised. This allows us been "stolen" from other processes that have been compromised. This allows us
to access services that are normally restricted from the current process. to access services that are normally restricted from the current process.
For every service requested by the application, we shall first check if the For every service requested by the application, we shall first check if the
list given to us contains the requested service and if so use it. If we don't list given to us contains the requested service and if so use it. If we don't
find the service in that list, we ask the service manager and hope for the find the service in that list, we ask the service manager and hope for the
best. best.
*/ */
typedef struct { typedef struct {
u32 num; u32 num;
@ -100,9 +100,9 @@ Result srvExit()
Result srvRegisterClient() Result srvRegisterClient()
{ {
Result rc = 0; Result rc = 0;
u32* cmdbuf = getThreadCommandBuffer(); u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x10002; cmdbuf[0] = 0x10002;
cmdbuf[1] = 0x20; cmdbuf[1] = 0x20;
@ -116,7 +116,7 @@ Result srvGetServiceHandle(Handle* out, const char* name)
Result rc = 0; Result rc = 0;
/* Look in service-list given to us by loader. If we find find a match, /* Look in service-list given to us by loader. If we find find a match,
we return it. */ we return it. */
Handle h = __get_handle_from_list(name); Handle h = __get_handle_from_list(name);
if(h != 0) { if(h != 0) {
@ -129,7 +129,7 @@ Result srvGetServiceHandle(Handle* out, const char* name)
strcpy((char*) &cmdbuf[1], name); strcpy((char*) &cmdbuf[1], name);
cmdbuf[3] = strlen(name); cmdbuf[3] = strlen(name);
cmdbuf[4] = 0x0; cmdbuf[4] = 0x0;
if((rc = svcSendSyncRequest(g_srv_handle)))return rc; if((rc = svcSendSyncRequest(g_srv_handle)))return rc;
*out = cmdbuf[3]; *out = cmdbuf[3];
@ -138,11 +138,11 @@ Result srvGetServiceHandle(Handle* out, const char* name)
// Old srv:pm interface, will only work on systems where srv:pm was a port (<7.X) // Old srv:pm interface, will only work on systems where srv:pm was a port (<7.X)
Result srvPmInit() Result srvPmInit()
{ {
Result rc = 0; Result rc = 0;
if((rc = svcConnectToPort(&g_srv_handle, "srv:pm")))return rc; if((rc = svcConnectToPort(&g_srv_handle, "srv:pm")))return rc;
if((rc = srvRegisterClient())) { if((rc = srvRegisterClient())) {
svcCloseHandle(g_srv_handle); svcCloseHandle(g_srv_handle);
g_srv_handle = 0; g_srv_handle = 0;
@ -154,7 +154,7 @@ Result srvPmInit()
Result srvRegisterProcess(u32 procid, u32 count, void *serviceaccesscontrol) Result srvRegisterProcess(u32 procid, u32 count, void *serviceaccesscontrol)
{ {
Result rc = 0; Result rc = 0;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x04030082; // <7.x cmdbuf[0] = 0x04030082; // <7.x
@ -162,22 +162,22 @@ Result srvRegisterProcess(u32 procid, u32 count, void *serviceaccesscontrol)
cmdbuf[2] = count; cmdbuf[2] = count;
cmdbuf[3] = (count << 16) | 2; cmdbuf[3] = (count << 16) | 2;
cmdbuf[4] = (u32)serviceaccesscontrol; cmdbuf[4] = (u32)serviceaccesscontrol;
if((rc = svcSendSyncRequest(g_srv_handle))) return rc; if((rc = svcSendSyncRequest(g_srv_handle))) return rc;
return cmdbuf[1]; return cmdbuf[1];
} }
Result srvUnregisterProcess(u32 procid) Result srvUnregisterProcess(u32 procid)
{ {
Result rc = 0; Result rc = 0;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x04040040; // <7.x cmdbuf[0] = 0x04040040; // <7.x
cmdbuf[1] = procid; cmdbuf[1] = procid;
if((rc = svcSendSyncRequest(g_srv_handle))) return rc; if((rc = svcSendSyncRequest(g_srv_handle))) return rc;
return cmdbuf[1]; return cmdbuf[1];
} }

View File

@ -2,33 +2,33 @@
#include "rbtree_internal.h" #include "rbtree_internal.h"
void void
rbtree_clear(rbtree_t *tree, rbtree_clear(rbtree_t *tree,
rbtree_node_destructor_t destructor) rbtree_node_destructor_t destructor)
{ {
rbtree_node_t *node = tree->root; rbtree_node_t *node = tree->root;
while(tree->root != NULL) while(tree->root != NULL)
{ {
while(node->child[LEFT] != NULL) while(node->child[LEFT] != NULL)
node = node->child[LEFT]; node = node->child[LEFT];
if(node->child[RIGHT] != NULL) if(node->child[RIGHT] != NULL)
node = node->child[RIGHT]; node = node->child[RIGHT];
else else
{ {
rbtree_node_t *parent = get_parent(node); rbtree_node_t *parent = get_parent(node);
if(parent == NULL) if(parent == NULL)
tree->root = NULL; tree->root = NULL;
else else
parent->child[node != parent->child[LEFT]] = NULL; parent->child[node != parent->child[LEFT]] = NULL;
if(destructor != NULL) if(destructor != NULL)
(*destructor)(node); (*destructor)(node);
node = parent; node = parent;
} }
} }
tree->size = 0; tree->size = 0;
} }

View File

@ -2,29 +2,29 @@
#include "rbtree_internal.h" #include "rbtree_internal.h"
rbtree_node_t* rbtree_node_t*
rbtree_find(const rbtree_t *tree, rbtree_find(const rbtree_t *tree,
const rbtree_node_t *node) const rbtree_node_t *node)
{ {
rbtree_node_t *tmp = tree->root; rbtree_node_t *tmp = tree->root;
rbtree_node_t *save = NULL; rbtree_node_t *save = NULL;
while(tmp != NULL) while(tmp != NULL)
{ {
int rc = (*tree->comparator)(node, tmp); int rc = (*tree->comparator)(node, tmp);
if(rc < 0) if(rc < 0)
{ {
tmp = tmp->child[LEFT]; tmp = tmp->child[LEFT];
} }
else if(rc > 0) else if(rc > 0)
{ {
tmp = tmp->child[RIGHT]; tmp = tmp->child[RIGHT];
} }
else else
{ {
save = tmp; save = tmp;
tmp = tmp->child[LEFT]; tmp = tmp->child[LEFT];
} }
} }
return save; return save;
} }

View File

@ -1,10 +1,10 @@
#include <3ds/util/rbtree.h> #include <3ds/util/rbtree.h>
void void
rbtree_init(rbtree_t *tree, rbtree_init(rbtree_t *tree,
rbtree_node_comparator_t comparator) rbtree_node_comparator_t comparator)
{ {
tree->root = NULL; tree->root = NULL;
tree->comparator = comparator; tree->comparator = comparator;
tree->size = 0; tree->size = 0;
} }

View File

@ -2,95 +2,95 @@
#include "rbtree_internal.h" #include "rbtree_internal.h"
static rbtree_node_t* static rbtree_node_t*
do_insert(rbtree_t *tree, do_insert(rbtree_t *tree,
rbtree_node_t *node, rbtree_node_t *node,
int multi) int multi)
{ {
rbtree_node_t *original = node; rbtree_node_t *original = node;
rbtree_node_t **tmp = &tree->root; rbtree_node_t **tmp = &tree->root;
rbtree_node_t *parent = NULL; rbtree_node_t *parent = NULL;
rbtree_node_t *save = NULL; rbtree_node_t *save = NULL;
while(*tmp != NULL) while(*tmp != NULL)
{ {
int cmp = (*(tree->comparator))(node, *tmp); int cmp = (*(tree->comparator))(node, *tmp);
parent = *tmp; parent = *tmp;
if(cmp < 0) if(cmp < 0)
tmp = &((*tmp)->child[LEFT]); tmp = &((*tmp)->child[LEFT]);
else if(cmp > 0) else if(cmp > 0)
tmp = &((*tmp)->child[RIGHT]); tmp = &((*tmp)->child[RIGHT]);
else else
{ {
if(!multi) if(!multi)
save = *tmp; save = *tmp;
tmp = &((*tmp)->child[LEFT]); tmp = &((*tmp)->child[LEFT]);
} }
} }
if(save != NULL) if(save != NULL)
{ {
return save; return save;
} }
*tmp = node; *tmp = node;
node->child[LEFT] = node->child[RIGHT] = NULL; node->child[LEFT] = node->child[RIGHT] = NULL;
set_parent(node, parent); set_parent(node, parent);
set_red(node); set_red(node);
while(is_red((parent = get_parent(node)))) while(is_red((parent = get_parent(node))))
{ {
rbtree_node_t *grandparent = get_parent(parent); rbtree_node_t *grandparent = get_parent(parent);
int left = (parent == grandparent->child[LEFT]); int left = (parent == grandparent->child[LEFT]);
rbtree_node_t *uncle = grandparent->child[left]; rbtree_node_t *uncle = grandparent->child[left];
if(is_red(uncle)) if(is_red(uncle))
{ {
set_black(uncle); set_black(uncle);
set_black(parent); set_black(parent);
set_red(grandparent); set_red(grandparent);
node = grandparent; node = grandparent;
} }
else else
{ {
if(parent->child[left] == node) if(parent->child[left] == node)
{ {
rbtree_node_t *tmp; rbtree_node_t *tmp;
rbtree_rotate(tree, parent, left); rbtree_rotate(tree, parent, left);
tmp = parent; tmp = parent;
parent = node; parent = node;
node = tmp; node = tmp;
} }
set_black(parent); set_black(parent);
set_red(grandparent); set_red(grandparent);
rbtree_rotate(tree, grandparent, !left); rbtree_rotate(tree, grandparent, !left);
} }
} }
set_black(tree->root); set_black(tree->root);
tree->size += 1; tree->size += 1;
return original; return original;
} }
rbtree_node_t* rbtree_node_t*
rbtree_insert(rbtree_t *tree, rbtree_insert(rbtree_t *tree,
rbtree_node_t *node) rbtree_node_t *node)
{ {
return do_insert(tree, node, 0); return do_insert(tree, node, 0);
} }
void void
rbtree_insert_multi(rbtree_t *tree, rbtree_insert_multi(rbtree_t *tree,
rbtree_node_t *node) rbtree_node_t *node)
{ {
do_insert(tree, node, 1); do_insert(tree, node, 1);
} }

View File

@ -1,64 +1,64 @@
#pragma once #pragma once
#define LEFT 0 #define LEFT 0
#define RIGHT 1 #define RIGHT 1
typedef enum rbtree_color typedef enum rbtree_color
{ {
RED = 0, RED = 0,
BLACK = 1, BLACK = 1,
} rbtree_color_t; } rbtree_color_t;
#define COLOR_MASK (RED|BLACK) #define COLOR_MASK (RED|BLACK)
static inline void static inline void
set_black(rbtree_node_t *node) set_black(rbtree_node_t *node)
{ {
node->parent_color &= ~COLOR_MASK; node->parent_color &= ~COLOR_MASK;
node->parent_color |= BLACK; node->parent_color |= BLACK;
} }
static inline void static inline void
set_red(rbtree_node_t *node) set_red(rbtree_node_t *node)
{ {
node->parent_color &= ~COLOR_MASK; node->parent_color &= ~COLOR_MASK;
node->parent_color |= RED; node->parent_color |= RED;
} }
static inline rbtree_color_t static inline rbtree_color_t
get_color(const rbtree_node_t *node) get_color(const rbtree_node_t *node)
{ {
if(node == NULL) if(node == NULL)
return BLACK; return BLACK;
return (rbtree_color_t)(node->parent_color & COLOR_MASK); return (rbtree_color_t)(node->parent_color & COLOR_MASK);
} }
static inline int static inline int
is_black(const rbtree_node_t *node) is_black(const rbtree_node_t *node)
{ {
return get_color(node) == BLACK; return get_color(node) == BLACK;
} }
static inline int static inline int
is_red(const rbtree_node_t *node) is_red(const rbtree_node_t *node)
{ {
return get_color(node) == RED; return get_color(node) == RED;
} }
static inline rbtree_node_t* static inline rbtree_node_t*
get_parent(const rbtree_node_t *node) get_parent(const rbtree_node_t *node)
{ {
return (rbtree_node_t*)(node->parent_color & ~COLOR_MASK); return (rbtree_node_t*)(node->parent_color & ~COLOR_MASK);
} }
static inline void static inline void
set_parent(rbtree_node_t *node, set_parent(rbtree_node_t *node,
const rbtree_node_t *parent) const rbtree_node_t *parent)
{ {
node->parent_color = (get_color(node)) | ((uintptr_t)parent); node->parent_color = (get_color(node)) | ((uintptr_t)parent);
} }
void void
rbtree_rotate(rbtree_t *tree, rbtree_rotate(rbtree_t *tree,
rbtree_node_t *node, rbtree_node_t *node,
int left); int left);

View File

@ -2,40 +2,40 @@
#include "rbtree_internal.h" #include "rbtree_internal.h"
static inline rbtree_node_t* static inline rbtree_node_t*
do_iterate(const rbtree_node_t *node, do_iterate(const rbtree_node_t *node,
int next) int next)
{ {
rbtree_node_t *it = (rbtree_node_t*)node; rbtree_node_t *it = (rbtree_node_t*)node;
if(it->child[next] != NULL) if(it->child[next] != NULL)
{ {
it = it->child[next]; it = it->child[next];
while(it->child[!next] != NULL) while(it->child[!next] != NULL)
it = it->child[!next]; it = it->child[!next];
} }
else else
{ {
rbtree_node_t *parent = get_parent(node); rbtree_node_t *parent = get_parent(node);
while(parent != NULL && it == parent->child[next]) while(parent != NULL && it == parent->child[next])
{ {
it = parent; it = parent;
parent = get_parent(it); parent = get_parent(it);
} }
it = parent; it = parent;
} }
return it; return it;
} }
rbtree_node_t* rbtree_node_t*
rbtree_node_next(const rbtree_node_t *node) rbtree_node_next(const rbtree_node_t *node)
{ {
return do_iterate(node, RIGHT); return do_iterate(node, RIGHT);
} }
rbtree_node_t* rbtree_node_t*
rbtree_node_prev(const rbtree_node_t *node) rbtree_node_prev(const rbtree_node_t *node)
{ {
return do_iterate(node, LEFT); return do_iterate(node, LEFT);
} }

View File

@ -2,36 +2,36 @@
#include "rbtree_internal.h" #include "rbtree_internal.h"
static inline rbtree_node_t* static inline rbtree_node_t*
do_minmax(const rbtree_t *tree, do_minmax(const rbtree_t *tree,
int max) int max)
{ {
rbtree_node_t *node = tree->root; rbtree_node_t *node = tree->root;
if(node == NULL) if(node == NULL)
return NULL; return NULL;
while(node->child[max] != NULL) while(node->child[max] != NULL)
node = node->child[max]; node = node->child[max];
return node; return node;
} }
rbtree_node_t* rbtree_node_t*
rbtree_min(const rbtree_t *tree) rbtree_min(const rbtree_t *tree)
{ {
rbtree_node_t *node; rbtree_node_t *node;
node = do_minmax(tree, LEFT); node = do_minmax(tree, LEFT);
return node; return node;
} }
rbtree_node_t* rbtree_node_t*
rbtree_max(const rbtree_t *tree) rbtree_max(const rbtree_t *tree)
{ {
rbtree_node_t *node; rbtree_node_t *node;
node = do_minmax(tree, RIGHT); node = do_minmax(tree, RIGHT);
return node; return node;
} }

View File

@ -2,139 +2,139 @@
#include "rbtree_internal.h" #include "rbtree_internal.h"
static void static void
recolor(rbtree_t *tree, recolor(rbtree_t *tree,
rbtree_node_t *parent, rbtree_node_t *parent,
rbtree_node_t *node) rbtree_node_t *node)
{ {
rbtree_node_t *sibling; rbtree_node_t *sibling;
while(is_black(node) && node != tree->root) while(is_black(node) && node != tree->root)
{ {
int left = (node == parent->child[LEFT]); int left = (node == parent->child[LEFT]);
sibling = parent->child[left]; sibling = parent->child[left];
if(is_red(sibling)) if(is_red(sibling))
{ {
set_black(sibling); set_black(sibling);
set_red(parent); set_red(parent);
rbtree_rotate(tree, parent, left); rbtree_rotate(tree, parent, left);
sibling = parent->child[left]; sibling = parent->child[left];
} }
if(is_black(sibling->child[LEFT]) && is_black(sibling->child[RIGHT])) if(is_black(sibling->child[LEFT]) && is_black(sibling->child[RIGHT]))
{ {
set_red(sibling); set_red(sibling);
node = parent; node = parent;
parent = get_parent(node); parent = get_parent(node);
} }
else else
{ {
if(is_black(sibling->child[left])) if(is_black(sibling->child[left]))
{ {
set_black(sibling->child[!left]); set_black(sibling->child[!left]);
set_red(sibling); set_red(sibling);
rbtree_rotate(tree, sibling, !left); rbtree_rotate(tree, sibling, !left);
sibling = parent->child[left]; sibling = parent->child[left];
} }
if(is_black(parent)) if(is_black(parent))
set_black(sibling); set_black(sibling);
else else
set_red(sibling); set_red(sibling);
set_black(parent); set_black(parent);
set_black(sibling->child[left]); set_black(sibling->child[left]);
rbtree_rotate(tree, parent, left); rbtree_rotate(tree, parent, left);
node = tree->root; node = tree->root;
} }
} }
if(node != NULL) if(node != NULL)
set_black(node); set_black(node);
} }
rbtree_node_t* rbtree_node_t*
rbtree_remove(rbtree_t *tree, rbtree_remove(rbtree_t *tree,
rbtree_node_t *node, rbtree_node_t *node,
rbtree_node_destructor_t destructor) rbtree_node_destructor_t destructor)
{ {
rbtree_color_t color; rbtree_color_t color;
rbtree_node_t *child, *parent, *original = node; rbtree_node_t *child, *parent, *original = node;
rbtree_node_t *next; rbtree_node_t *next;
next = rbtree_node_next(node); next = rbtree_node_next(node);
if(node->child[LEFT] != NULL && node->child[RIGHT] != NULL) if(node->child[LEFT] != NULL && node->child[RIGHT] != NULL)
{ {
rbtree_node_t *old = node; rbtree_node_t *old = node;
node = node->child[RIGHT]; node = node->child[RIGHT];
while(node->child[LEFT] != NULL) while(node->child[LEFT] != NULL)
node = node->child[LEFT]; node = node->child[LEFT];
parent = get_parent(old); parent = get_parent(old);
if(parent != NULL) if(parent != NULL)
{ {
if(parent->child[LEFT] == old) if(parent->child[LEFT] == old)
parent->child[LEFT] = node; parent->child[LEFT] = node;
else else
parent->child[RIGHT] = node; parent->child[RIGHT] = node;
} }
else else
tree->root = node; tree->root = node;
child = node->child[RIGHT]; child = node->child[RIGHT];
parent = get_parent(node); parent = get_parent(node);
color = get_color(node); color = get_color(node);
if(parent == old) if(parent == old)
parent = node; parent = node;
else else
{ {
if(child != NULL) if(child != NULL)
set_parent(child, parent); set_parent(child, parent);
parent->child[LEFT] = child; parent->child[LEFT] = child;
node->child[RIGHT] = old->child[RIGHT]; node->child[RIGHT] = old->child[RIGHT];
set_parent(old->child[RIGHT], node); set_parent(old->child[RIGHT], node);
} }
node->parent_color = old->parent_color; node->parent_color = old->parent_color;
node->child[LEFT] = old->child[LEFT]; node->child[LEFT] = old->child[LEFT];
set_parent(old->child[LEFT], node); set_parent(old->child[LEFT], node);
} }
else else
{ {
if(node->child[LEFT] == NULL) if(node->child[LEFT] == NULL)
child = node->child[RIGHT]; child = node->child[RIGHT];
else else
child = node->child[LEFT]; child = node->child[LEFT];
parent = get_parent(node); parent = get_parent(node);
color = get_color(node); color = get_color(node);
if(child != NULL) if(child != NULL)
set_parent(child, parent); set_parent(child, parent);
if(parent != NULL) if(parent != NULL)
{ {
if(parent->child[LEFT] == node) if(parent->child[LEFT] == node)
parent->child[LEFT] = child; parent->child[LEFT] = child;
else else
parent->child[RIGHT] = child; parent->child[RIGHT] = child;
} }
else else
tree->root = child; tree->root = child;
} }
if(color == BLACK) if(color == BLACK)
recolor(tree, parent, child); recolor(tree, parent, child);
if(destructor != NULL) if(destructor != NULL)
(*destructor)(original); (*destructor)(original);
tree->size -= 1; tree->size -= 1;
return next; return next;
} }

View File

@ -2,27 +2,27 @@
#include "rbtree_internal.h" #include "rbtree_internal.h"
void void
rbtree_rotate(rbtree_t *tree, rbtree_rotate(rbtree_t *tree,
rbtree_node_t *node, rbtree_node_t *node,
int left) int left)
{ {
rbtree_node_t *tmp = node->child[left]; rbtree_node_t *tmp = node->child[left];
rbtree_node_t *parent = get_parent(node); rbtree_node_t *parent = get_parent(node);
node->child[left] = tmp->child[!left]; node->child[left] = tmp->child[!left];
if(tmp->child[!left] != NULL) if(tmp->child[!left] != NULL)
set_parent(tmp->child[!left], node); set_parent(tmp->child[!left], node);
tmp->child[!left] = node; tmp->child[!left] = node;
set_parent(tmp, parent); set_parent(tmp, parent);
if(parent != NULL) if(parent != NULL)
{ {
if(node == parent->child[!left]) if(node == parent->child[!left])
parent->child[!left] = tmp; parent->child[!left] = tmp;
else else
parent->child[left] = tmp; parent->child[left] = tmp;
} }
else else
tree->root = tmp; tree->root = tmp;
set_parent(node, tmp); set_parent(node, tmp);
} }