Merge 86f6d29dcb
into cecae02b1d
This commit is contained in:
commit
7bbc594cf7
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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) */
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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]);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user