whitespace fixes
This commit is contained in:
parent
664ae583c4
commit
3501efd7e5
@ -1,173 +1,173 @@
|
||||
/**
|
||||
* @file console.h
|
||||
* @brief 3ds stdio support.
|
||||
*
|
||||
* Provides stdio integration for printing to the 3DS screen as well as debug print
|
||||
* functionality provided by stderr.
|
||||
*
|
||||
* General usage is to initialize the console by:
|
||||
* @code
|
||||
* consoleDemoInit()
|
||||
* @endcode
|
||||
* or to customize the console usage by:
|
||||
* @code
|
||||
* consoleInit()
|
||||
* @endcode
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/gfx.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CONSOLE_ESC(x) "\x1b[" #x
|
||||
#define CONSOLE_RESET CONSOLE_ESC(0m)
|
||||
#define CONSOLE_BLACK CONSOLE_ESC(30m)
|
||||
#define CONSOLE_RED CONSOLE_ESC(31;1m)
|
||||
#define CONSOLE_GREEN CONSOLE_ESC(32;1m)
|
||||
#define CONSOLE_YELLOW CONSOLE_ESC(33;1m)
|
||||
#define CONSOLE_BLUE CONSOLE_ESC(34;1m)
|
||||
#define CONSOLE_MAGENTA CONSOLE_ESC(35;1m)
|
||||
#define CONSOLE_CYAN CONSOLE_ESC(36;1m)
|
||||
#define CONSOLE_WHITE CONSOLE_ESC(37;1m)
|
||||
|
||||
/// A callback for printing a character.
|
||||
typedef bool(*ConsolePrint)(void* con, int c);
|
||||
|
||||
/// A font struct for the console.
|
||||
typedef struct ConsoleFont
|
||||
{
|
||||
u8* gfx; ///< A pointer to the font graphics
|
||||
u16 asciiOffset; ///< Offset to the first valid character in the font table
|
||||
u16 numChars; ///< Number of characters in the font graphics
|
||||
}ConsoleFont;
|
||||
|
||||
/**
|
||||
* @brief Console structure used to store the state of a console render context.
|
||||
*
|
||||
* Default values from consoleGetDefault();
|
||||
* @code
|
||||
* PrintConsole defaultConsole =
|
||||
* {
|
||||
* //Font:
|
||||
* {
|
||||
* (u8*)default_font_bin, //font gfx
|
||||
* 0, //first ascii character in the set
|
||||
* 128, //number of characters in the font set
|
||||
* },
|
||||
* 0,0, //cursorX cursorY
|
||||
* 0,0, //prevcursorX prevcursorY
|
||||
* 40, //console width
|
||||
* 30, //console height
|
||||
* 0, //window x
|
||||
* 0, //window y
|
||||
* 32, //window width
|
||||
* 24, //window height
|
||||
* 3, //tab size
|
||||
* 0, //font character offset
|
||||
* 0, //print callback
|
||||
* false //console initialized
|
||||
* };
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct PrintConsole
|
||||
{
|
||||
ConsoleFont font; ///< Font of the console
|
||||
|
||||
u16 *frameBuffer; ///< Framebuffer address
|
||||
|
||||
int cursorX; ///< Current X location of the cursor (as a tile offset by default)
|
||||
int cursorY; ///< Current Y location of the cursor (as a tile offset by default)
|
||||
|
||||
int prevCursorX; ///< Internal state
|
||||
int prevCursorY; ///< Internal state
|
||||
|
||||
int consoleWidth; ///< Width 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 windowY; ///< Window Y location in characters (not implemented)
|
||||
int windowWidth; ///< Window width in characters (not implemented)
|
||||
int windowHeight; ///< Window height in characters (not implemented)
|
||||
|
||||
int tabSize; ///< Size of a tab
|
||||
int fg; ///< Foreground color
|
||||
int bg; ///< Background color
|
||||
int flags; ///< Reverse/bright flags
|
||||
|
||||
ConsolePrint PrintChar; ///< Callback for printing a character. Should return true if it has handled rendering the graphics (else the print engine will attempt to render via tiles).
|
||||
|
||||
bool consoleInitialised; ///< True if the console is initialized
|
||||
}PrintConsole;
|
||||
|
||||
#define CONSOLE_COLOR_BOLD (1<<0) ///< Bold text
|
||||
#define CONSOLE_COLOR_FAINT (1<<1) ///< Faint text
|
||||
#define CONSOLE_ITALIC (1<<2) ///< Italic text
|
||||
#define CONSOLE_UNDERLINE (1<<3) ///< Underlined text
|
||||
#define CONSOLE_BLINK_SLOW (1<<4) ///< Slow blinking text
|
||||
#define CONSOLE_BLINK_FAST (1<<5) ///< Fast blinking text
|
||||
#define CONSOLE_COLOR_REVERSE (1<<6) ///< Reversed color text
|
||||
#define CONSOLE_CONCEAL (1<<7) ///< Concealed text
|
||||
#define CONSOLE_CROSSED_OUT (1<<8) ///< Crossed out text
|
||||
|
||||
/// Console debug devices supported by libnds.
|
||||
typedef enum {
|
||||
debugDevice_NULL, ///< Swallows prints to stderr
|
||||
debugDevice_3DMOO, ///< Directs stderr debug statements to 3dmoo
|
||||
debugDevice_CONSOLE, ///< Directs stderr debug statements to 3DS console window
|
||||
} debugDevice;
|
||||
|
||||
/**
|
||||
* @brief Loads the font into the console.
|
||||
* @param console Pointer to the console to update, if NULL it will update the current console.
|
||||
* @param font The font to load.
|
||||
*/
|
||||
void consoleSetFont(PrintConsole* console, ConsoleFont* font);
|
||||
|
||||
/**
|
||||
* @brief Sets the print window.
|
||||
* @param console Console to set, if NULL it will set the current console window.
|
||||
* @param x X location of the window.
|
||||
* @param y Y location of the window.
|
||||
* @param width Width of the window.
|
||||
* @param height Height of the window.
|
||||
*/
|
||||
void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height);
|
||||
|
||||
/**
|
||||
* @brief Gets a pointer to the console with the default values.
|
||||
* This should only be used when using a single console or without changing the console that is returned, otherwise use consoleInit().
|
||||
* @return A pointer to the console with the default values.
|
||||
*/
|
||||
PrintConsole* consoleGetDefault(void);
|
||||
|
||||
/**
|
||||
* @brief Make the specified console the render target.
|
||||
* @param console A pointer to the console struct (must have been initialized with consoleInit(PrintConsole* console)).
|
||||
* @return A pointer to the previous console.
|
||||
*/
|
||||
PrintConsole *consoleSelect(PrintConsole* console);
|
||||
|
||||
/**
|
||||
* @brief Initialise the console.
|
||||
* @param screen The screen to use for the console.
|
||||
* @param console A pointer to the console data to initialize (if it's NULL, the default console will be used).
|
||||
* @return A pointer to the current console.
|
||||
*/
|
||||
PrintConsole* consoleInit(gfxScreen_t screen, PrintConsole* console);
|
||||
|
||||
/**
|
||||
* @brief Initializes debug console output on stderr to the specified device.
|
||||
* @param device The debug device (or devices) to output debug print statements to.
|
||||
*/
|
||||
void consoleDebugInit(debugDevice device);
|
||||
|
||||
/// Clears the screan by using iprintf("\x1b[2J");
|
||||
void consoleClear(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @file console.h
|
||||
* @brief 3ds stdio support.
|
||||
*
|
||||
* Provides stdio integration for printing to the 3DS screen as well as debug print
|
||||
* functionality provided by stderr.
|
||||
*
|
||||
* General usage is to initialize the console by:
|
||||
* @code
|
||||
* consoleDemoInit()
|
||||
* @endcode
|
||||
* or to customize the console usage by:
|
||||
* @code
|
||||
* consoleInit()
|
||||
* @endcode
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/gfx.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CONSOLE_ESC(x) "\x1b[" #x
|
||||
#define CONSOLE_RESET CONSOLE_ESC(0m)
|
||||
#define CONSOLE_BLACK CONSOLE_ESC(30m)
|
||||
#define CONSOLE_RED CONSOLE_ESC(31;1m)
|
||||
#define CONSOLE_GREEN CONSOLE_ESC(32;1m)
|
||||
#define CONSOLE_YELLOW CONSOLE_ESC(33;1m)
|
||||
#define CONSOLE_BLUE CONSOLE_ESC(34;1m)
|
||||
#define CONSOLE_MAGENTA CONSOLE_ESC(35;1m)
|
||||
#define CONSOLE_CYAN CONSOLE_ESC(36;1m)
|
||||
#define CONSOLE_WHITE CONSOLE_ESC(37;1m)
|
||||
|
||||
/// A callback for printing a character.
|
||||
typedef bool(*ConsolePrint)(void* con, int c);
|
||||
|
||||
/// A font struct for the console.
|
||||
typedef struct ConsoleFont
|
||||
{
|
||||
u8* gfx; ///< A pointer to the font graphics
|
||||
u16 asciiOffset; ///< Offset to the first valid character in the font table
|
||||
u16 numChars; ///< Number of characters in the font graphics
|
||||
}ConsoleFont;
|
||||
|
||||
/**
|
||||
* @brief Console structure used to store the state of a console render context.
|
||||
*
|
||||
* Default values from consoleGetDefault();
|
||||
* @code
|
||||
* PrintConsole defaultConsole =
|
||||
* {
|
||||
* //Font:
|
||||
* {
|
||||
* (u8*)default_font_bin, //font gfx
|
||||
* 0, //first ascii character in the set
|
||||
* 128, //number of characters in the font set
|
||||
* },
|
||||
* 0,0, //cursorX cursorY
|
||||
* 0,0, //prevcursorX prevcursorY
|
||||
* 40, //console width
|
||||
* 30, //console height
|
||||
* 0, //window x
|
||||
* 0, //window y
|
||||
* 32, //window width
|
||||
* 24, //window height
|
||||
* 3, //tab size
|
||||
* 0, //font character offset
|
||||
* 0, //print callback
|
||||
* false //console initialized
|
||||
* };
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct PrintConsole
|
||||
{
|
||||
ConsoleFont font; ///< Font of the console
|
||||
|
||||
u16 *frameBuffer; ///< Framebuffer address
|
||||
|
||||
int cursorX; ///< Current X location of the cursor (as a tile offset by default)
|
||||
int cursorY; ///< Current Y location of the cursor (as a tile offset by default)
|
||||
|
||||
int prevCursorX; ///< Internal state
|
||||
int prevCursorY; ///< Internal state
|
||||
|
||||
int consoleWidth; ///< Width 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 windowY; ///< Window Y location in characters (not implemented)
|
||||
int windowWidth; ///< Window width in characters (not implemented)
|
||||
int windowHeight; ///< Window height in characters (not implemented)
|
||||
|
||||
int tabSize; ///< Size of a tab
|
||||
int fg; ///< Foreground color
|
||||
int bg; ///< Background color
|
||||
int flags; ///< Reverse/bright flags
|
||||
|
||||
ConsolePrint PrintChar; ///< Callback for printing a character. Should return true if it has handled rendering the graphics (else the print engine will attempt to render via tiles).
|
||||
|
||||
bool consoleInitialised; ///< True if the console is initialized
|
||||
}PrintConsole;
|
||||
|
||||
#define CONSOLE_COLOR_BOLD (1<<0) ///< Bold text
|
||||
#define CONSOLE_COLOR_FAINT (1<<1) ///< Faint text
|
||||
#define CONSOLE_ITALIC (1<<2) ///< Italic text
|
||||
#define CONSOLE_UNDERLINE (1<<3) ///< Underlined text
|
||||
#define CONSOLE_BLINK_SLOW (1<<4) ///< Slow blinking text
|
||||
#define CONSOLE_BLINK_FAST (1<<5) ///< Fast blinking text
|
||||
#define CONSOLE_COLOR_REVERSE (1<<6) ///< Reversed color text
|
||||
#define CONSOLE_CONCEAL (1<<7) ///< Concealed text
|
||||
#define CONSOLE_CROSSED_OUT (1<<8) ///< Crossed out text
|
||||
|
||||
/// Console debug devices supported by libnds.
|
||||
typedef enum {
|
||||
debugDevice_NULL, ///< Swallows prints to stderr
|
||||
debugDevice_3DMOO, ///< Directs stderr debug statements to 3dmoo
|
||||
debugDevice_CONSOLE, ///< Directs stderr debug statements to 3DS console window
|
||||
} debugDevice;
|
||||
|
||||
/**
|
||||
* @brief Loads the font into the console.
|
||||
* @param console Pointer to the console to update, if NULL it will update the current console.
|
||||
* @param font The font to load.
|
||||
*/
|
||||
void consoleSetFont(PrintConsole* console, ConsoleFont* font);
|
||||
|
||||
/**
|
||||
* @brief Sets the print window.
|
||||
* @param console Console to set, if NULL it will set the current console window.
|
||||
* @param x X location of the window.
|
||||
* @param y Y location of the window.
|
||||
* @param width Width of the window.
|
||||
* @param height Height of the window.
|
||||
*/
|
||||
void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height);
|
||||
|
||||
/**
|
||||
* @brief Gets a pointer to the console with the default values.
|
||||
* This should only be used when using a single console or without changing the console that is returned, otherwise use consoleInit().
|
||||
* @return A pointer to the console with the default values.
|
||||
*/
|
||||
PrintConsole* consoleGetDefault(void);
|
||||
|
||||
/**
|
||||
* @brief Make the specified console the render target.
|
||||
* @param console A pointer to the console struct (must have been initialized with consoleInit(PrintConsole* console)).
|
||||
* @return A pointer to the previous console.
|
||||
*/
|
||||
PrintConsole *consoleSelect(PrintConsole* console);
|
||||
|
||||
/**
|
||||
* @brief Initialise the console.
|
||||
* @param screen The screen to use for the console.
|
||||
* @param console A pointer to the console data to initialize (if it's NULL, the default console will be used).
|
||||
* @return A pointer to the current console.
|
||||
*/
|
||||
PrintConsole* consoleInit(gfxScreen_t screen, PrintConsole* console);
|
||||
|
||||
/**
|
||||
* @brief Initializes debug console output on stderr to the specified device.
|
||||
* @param device The debug device (or devices) to output debug print statements to.
|
||||
*/
|
||||
void consoleDebugInit(debugDevice device);
|
||||
|
||||
/// Clears the screan by using iprintf("\x1b[2J");
|
||||
void consoleClear(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -202,7 +202,7 @@ typedef enum
|
||||
GPU_WRITE_BLUE = 0x04, ///< Write blue.
|
||||
GPU_WRITE_ALPHA = 0x08, ///< Write alpha.
|
||||
GPU_WRITE_DEPTH = 0x10, ///< Write depth.
|
||||
|
||||
|
||||
GPU_WRITE_COLOR = 0x0F, ///< Write all color components.
|
||||
GPU_WRITE_ALL = 0x1F, ///< Write all components.
|
||||
} GPU_WRITEMASK;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,120 +1,120 @@
|
||||
/**
|
||||
* @file shaderProgram.h
|
||||
* @brief Functions for working with shaders.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/gpu/shbin.h>
|
||||
|
||||
/// 24-bit float uniforms.
|
||||
typedef struct
|
||||
{
|
||||
u32 id; ///< Uniform ID.
|
||||
u32 data[3]; ///< Uniform data.
|
||||
}float24Uniform_s;
|
||||
|
||||
/// Describes an instance of either a vertex or geometry shader.
|
||||
typedef struct
|
||||
{
|
||||
DVLE_s* dvle; ///< Shader DVLE.
|
||||
u16 boolUniforms; ///< Boolean uniforms.
|
||||
u16 boolUniformMask; ///< Used boolean uniform mask.
|
||||
u32 intUniforms[4]; ///< Integer uniforms.
|
||||
float24Uniform_s* float24Uniforms; ///< 24-bit float uniforms.
|
||||
u8 intUniformMask; ///< Used integer uniform mask.
|
||||
u8 numFloat24Uniforms; ///< Float uniform count.
|
||||
}shaderInstance_s;
|
||||
|
||||
/// Describes an instance of a full shader program.
|
||||
typedef struct
|
||||
{
|
||||
shaderInstance_s* vertexShader; ///< Vertex shader.
|
||||
shaderInstance_s* geometryShader; ///< Geometry shader.
|
||||
u32 geoShaderInputPermutation[2]; ///< Geometry shader input permutation.
|
||||
u8 geoShaderInputStride; ///< Geometry shader input stride.
|
||||
}shaderProgram_s;
|
||||
|
||||
/**
|
||||
* @brief Initializes a shader instance.
|
||||
* @param si Shader instance to initialize.
|
||||
* @param dvle DVLE to initialize the shader instance with.
|
||||
*/
|
||||
Result shaderInstanceInit(shaderInstance_s* si, DVLE_s* dvle);
|
||||
|
||||
/**
|
||||
* @brief Frees a shader instance.
|
||||
* @param si Shader instance to free.
|
||||
*/
|
||||
Result shaderInstanceFree(shaderInstance_s* si);
|
||||
|
||||
/**
|
||||
* @brief Sets a bool uniform of a shader.
|
||||
* @param si Shader instance to use.
|
||||
* @param id ID of the bool uniform.
|
||||
* @param value Value to set.
|
||||
*/
|
||||
Result shaderInstanceSetBool(shaderInstance_s* si, int id, bool value);
|
||||
|
||||
/**
|
||||
* @brief Gets a bool uniform of a shader.
|
||||
* @param si Shader instance to use.
|
||||
* @param id ID of the bool uniform.
|
||||
* @param value Pointer to output the value to.
|
||||
*/
|
||||
Result shaderInstanceGetBool(shaderInstance_s* si, int id, bool* value);
|
||||
|
||||
/**
|
||||
* @brief Gets the location of a shader's uniform.
|
||||
* @param si Shader instance to use.
|
||||
* @param name Name of the uniform.
|
||||
*/
|
||||
s8 shaderInstanceGetUniformLocation(shaderInstance_s* si, const char* name);
|
||||
|
||||
/**
|
||||
* @brief Initializes a shader program.
|
||||
* @param sp Shader program to initialize.
|
||||
*/
|
||||
Result shaderProgramInit(shaderProgram_s* sp);
|
||||
|
||||
/**
|
||||
* @brief Frees a shader program.
|
||||
* @param sp Shader program to free.
|
||||
*/
|
||||
Result shaderProgramFree(shaderProgram_s* sp);
|
||||
|
||||
/**
|
||||
* @brief Sets the vertex shader of a shader program.
|
||||
* @param sp Shader program to use.
|
||||
* @param dvle Vertex shader to set.
|
||||
*/
|
||||
Result shaderProgramSetVsh(shaderProgram_s* sp, DVLE_s* dvle);
|
||||
|
||||
/**
|
||||
* @brief Sets the geometry shader of a shader program.
|
||||
* @param sp Shader program to use.
|
||||
* @param dvle Geometry shader to set.
|
||||
* @param stride Input stride of the shader (pass 0 to match the number of outputs of the vertex shader).
|
||||
*/
|
||||
Result shaderProgramSetGsh(shaderProgram_s* sp, DVLE_s* dvle, u8 stride);
|
||||
|
||||
/**
|
||||
* @brief Configures the permutation of the input attributes of the geometry shader of a shader program.
|
||||
* @param sp Shader program to use.
|
||||
* @param permutation Attribute permutation to use.
|
||||
*/
|
||||
Result shaderProgramSetGshInputPermutation(shaderProgram_s* sp, u64 permutation);
|
||||
|
||||
/**
|
||||
* @brief Configures the shader units to use the specified shader program.
|
||||
* @param sp Shader program to use.
|
||||
* @param sendVshCode When true, the vertex shader's code and operand descriptors are uploaded.
|
||||
* @param sendGshCode When true, the geometry shader's code and operand descriptors are uploaded.
|
||||
*/
|
||||
Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGshCode);
|
||||
|
||||
/**
|
||||
* @brief Same as shaderProgramConfigure, but always loading code/operand descriptors and uploading DVLE constants afterwards.
|
||||
* @param sp Shader program to use.
|
||||
*/
|
||||
Result shaderProgramUse(shaderProgram_s* sp);
|
||||
/**
|
||||
* @file shaderProgram.h
|
||||
* @brief Functions for working with shaders.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/gpu/shbin.h>
|
||||
|
||||
/// 24-bit float uniforms.
|
||||
typedef struct
|
||||
{
|
||||
u32 id; ///< Uniform ID.
|
||||
u32 data[3]; ///< Uniform data.
|
||||
}float24Uniform_s;
|
||||
|
||||
/// Describes an instance of either a vertex or geometry shader.
|
||||
typedef struct
|
||||
{
|
||||
DVLE_s* dvle; ///< Shader DVLE.
|
||||
u16 boolUniforms; ///< Boolean uniforms.
|
||||
u16 boolUniformMask; ///< Used boolean uniform mask.
|
||||
u32 intUniforms[4]; ///< Integer uniforms.
|
||||
float24Uniform_s* float24Uniforms; ///< 24-bit float uniforms.
|
||||
u8 intUniformMask; ///< Used integer uniform mask.
|
||||
u8 numFloat24Uniforms; ///< Float uniform count.
|
||||
}shaderInstance_s;
|
||||
|
||||
/// Describes an instance of a full shader program.
|
||||
typedef struct
|
||||
{
|
||||
shaderInstance_s* vertexShader; ///< Vertex shader.
|
||||
shaderInstance_s* geometryShader; ///< Geometry shader.
|
||||
u32 geoShaderInputPermutation[2]; ///< Geometry shader input permutation.
|
||||
u8 geoShaderInputStride; ///< Geometry shader input stride.
|
||||
}shaderProgram_s;
|
||||
|
||||
/**
|
||||
* @brief Initializes a shader instance.
|
||||
* @param si Shader instance to initialize.
|
||||
* @param dvle DVLE to initialize the shader instance with.
|
||||
*/
|
||||
Result shaderInstanceInit(shaderInstance_s* si, DVLE_s* dvle);
|
||||
|
||||
/**
|
||||
* @brief Frees a shader instance.
|
||||
* @param si Shader instance to free.
|
||||
*/
|
||||
Result shaderInstanceFree(shaderInstance_s* si);
|
||||
|
||||
/**
|
||||
* @brief Sets a bool uniform of a shader.
|
||||
* @param si Shader instance to use.
|
||||
* @param id ID of the bool uniform.
|
||||
* @param value Value to set.
|
||||
*/
|
||||
Result shaderInstanceSetBool(shaderInstance_s* si, int id, bool value);
|
||||
|
||||
/**
|
||||
* @brief Gets a bool uniform of a shader.
|
||||
* @param si Shader instance to use.
|
||||
* @param id ID of the bool uniform.
|
||||
* @param value Pointer to output the value to.
|
||||
*/
|
||||
Result shaderInstanceGetBool(shaderInstance_s* si, int id, bool* value);
|
||||
|
||||
/**
|
||||
* @brief Gets the location of a shader's uniform.
|
||||
* @param si Shader instance to use.
|
||||
* @param name Name of the uniform.
|
||||
*/
|
||||
s8 shaderInstanceGetUniformLocation(shaderInstance_s* si, const char* name);
|
||||
|
||||
/**
|
||||
* @brief Initializes a shader program.
|
||||
* @param sp Shader program to initialize.
|
||||
*/
|
||||
Result shaderProgramInit(shaderProgram_s* sp);
|
||||
|
||||
/**
|
||||
* @brief Frees a shader program.
|
||||
* @param sp Shader program to free.
|
||||
*/
|
||||
Result shaderProgramFree(shaderProgram_s* sp);
|
||||
|
||||
/**
|
||||
* @brief Sets the vertex shader of a shader program.
|
||||
* @param sp Shader program to use.
|
||||
* @param dvle Vertex shader to set.
|
||||
*/
|
||||
Result shaderProgramSetVsh(shaderProgram_s* sp, DVLE_s* dvle);
|
||||
|
||||
/**
|
||||
* @brief Sets the geometry shader of a shader program.
|
||||
* @param sp Shader program to use.
|
||||
* @param dvle Geometry shader to set.
|
||||
* @param stride Input stride of the shader (pass 0 to match the number of outputs of the vertex shader).
|
||||
*/
|
||||
Result shaderProgramSetGsh(shaderProgram_s* sp, DVLE_s* dvle, u8 stride);
|
||||
|
||||
/**
|
||||
* @brief Configures the permutation of the input attributes of the geometry shader of a shader program.
|
||||
* @param sp Shader program to use.
|
||||
* @param permutation Attribute permutation to use.
|
||||
*/
|
||||
Result shaderProgramSetGshInputPermutation(shaderProgram_s* sp, u64 permutation);
|
||||
|
||||
/**
|
||||
* @brief Configures the shader units to use the specified shader program.
|
||||
* @param sp Shader program to use.
|
||||
* @param sendVshCode When true, the vertex shader's code and operand descriptors are uploaded.
|
||||
* @param sendGshCode When true, the geometry shader's code and operand descriptors are uploaded.
|
||||
*/
|
||||
Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGshCode);
|
||||
|
||||
/**
|
||||
* @brief Same as shaderProgramConfigure, but always loading code/operand descriptors and uploading DVLE constants afterwards.
|
||||
* @param sp Shader program to use.
|
||||
*/
|
||||
Result shaderProgramUse(shaderProgram_s* sp);
|
||||
|
@ -1,38 +1,38 @@
|
||||
/**
|
||||
* @file hb.h
|
||||
* @brief HB (Homebrew) service.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// WARNING ! THIS FILE PROVIDES AN INTERFACE TO A NON-OFFICIAL SERVICE PROVIDED BY NINJHAX
|
||||
// BY USING COMMANDS FROM THIS SERVICE YOU WILL LIKELY MAKE YOUR APPLICATION INCOMPATIBLE WITH OTHER HOMEBREW LAUNCHING METHODS
|
||||
// A GOOD WAY TO COPE WITH THIS IS TO CHECK THE OUTPUT OF hbInit FOR ERRORS
|
||||
|
||||
#include <3ds/types.h>
|
||||
|
||||
/// Initializes HB.
|
||||
Result hbInit(void);
|
||||
|
||||
/// Exits HB.
|
||||
void hbExit(void);
|
||||
|
||||
/// Flushes/invalidates the entire data/instruction cache.
|
||||
Result HB_FlushInvalidateCache(void);
|
||||
|
||||
/**
|
||||
* @brief Fetches the address for Ninjhax 1.x bootloader addresses.
|
||||
* @param load3dsx void (*callBootloader)(Handle hb, Handle file);
|
||||
* @param setArgv void (*setArgs)(u32* src, u32 length);
|
||||
*/
|
||||
Result HB_GetBootloaderAddresses(void** load3dsx, void** setArgv);
|
||||
|
||||
/**
|
||||
* @brief Changes the permissions of a given number of pages at address addr to mode.
|
||||
* Should it fail, the appropriate kernel error code will be returned and *reprotectedPages (if not NULL)
|
||||
* will be set to the number of sequential pages which were successfully reprotected + 1
|
||||
* @param addr Address to reprotect.
|
||||
* @param pages Number of pages to reprotect.
|
||||
* @param mode Mode to reprotect to.
|
||||
* @param reprotectedPages Number of successfully reprotected pages, on failure.
|
||||
*/
|
||||
Result HB_ReprotectMemory(u32* addr, u32 pages, u32 mode, u32* reprotectedPages);
|
||||
/**
|
||||
* @file hb.h
|
||||
* @brief HB (Homebrew) service.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// WARNING ! THIS FILE PROVIDES AN INTERFACE TO A NON-OFFICIAL SERVICE PROVIDED BY NINJHAX
|
||||
// BY USING COMMANDS FROM THIS SERVICE YOU WILL LIKELY MAKE YOUR APPLICATION INCOMPATIBLE WITH OTHER HOMEBREW LAUNCHING METHODS
|
||||
// A GOOD WAY TO COPE WITH THIS IS TO CHECK THE OUTPUT OF hbInit FOR ERRORS
|
||||
|
||||
#include <3ds/types.h>
|
||||
|
||||
/// Initializes HB.
|
||||
Result hbInit(void);
|
||||
|
||||
/// Exits HB.
|
||||
void hbExit(void);
|
||||
|
||||
/// Flushes/invalidates the entire data/instruction cache.
|
||||
Result HB_FlushInvalidateCache(void);
|
||||
|
||||
/**
|
||||
* @brief Fetches the address for Ninjhax 1.x bootloader addresses.
|
||||
* @param load3dsx void (*callBootloader)(Handle hb, Handle file);
|
||||
* @param setArgv void (*setArgs)(u32* src, u32 length);
|
||||
*/
|
||||
Result HB_GetBootloaderAddresses(void** load3dsx, void** setArgv);
|
||||
|
||||
/**
|
||||
* @brief Changes the permissions of a given number of pages at address addr to mode.
|
||||
* Should it fail, the appropriate kernel error code will be returned and *reprotectedPages (if not NULL)
|
||||
* will be set to the number of sequential pages which were successfully reprotected + 1
|
||||
* @param addr Address to reprotect.
|
||||
* @param pages Number of pages to reprotect.
|
||||
* @param mode Mode to reprotect to.
|
||||
* @param reprotectedPages Number of successfully reprotected pages, on failure.
|
||||
*/
|
||||
Result HB_ReprotectMemory(u32* addr, u32 pages, u32 mode, u32* reprotectedPages);
|
||||
|
@ -29,7 +29,7 @@ typedef enum
|
||||
OUTPUT_RGB_32 = 0x0, ///< 32-bit RGBA8888. The alpha component is the 8-bit value set by @ref Y2RU_SetAlpha
|
||||
OUTPUT_RGB_24 = 0x1, ///< 24-bit RGB888.
|
||||
OUTPUT_RGB_16_555 = 0x2, ///< 16-bit RGBA5551. The alpha bit is the 7th bit of the alpha value set by @ref Y2RU_SetAlpha
|
||||
OUTPUT_RGB_16_565 = 0x3, ///< 16-bit RGB565.
|
||||
OUTPUT_RGB_16_565 = 0x3, ///< 16-bit RGB565.
|
||||
} Y2RU_OutputFormat;
|
||||
|
||||
/// Rotation to be applied to the output.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,382 +1,382 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/result.h>
|
||||
#include <3ds/gpu/registers.h>
|
||||
#include <3ds/gpu/shaderProgram.h>
|
||||
|
||||
static void GPU_SetShaderOutmap(const u32 outmapData[8]);
|
||||
static void GPU_SendShaderCode(GPU_SHADER_TYPE type, u32* data, u16 offset, u16 length);
|
||||
static void GPU_SendOperandDescriptors(GPU_SHADER_TYPE type, u32* data, u16 offset, u16 length);
|
||||
|
||||
Result shaderInstanceInit(shaderInstance_s* si, DVLE_s* dvle)
|
||||
{
|
||||
if(!si || !dvle)return -1;
|
||||
|
||||
si->dvle = dvle;
|
||||
|
||||
si->boolUniforms = 0;
|
||||
si->boolUniformMask = 0;
|
||||
si->intUniforms[0] = 0x00000000;
|
||||
si->intUniforms[1] = 0x00000000;
|
||||
si->intUniforms[2] = 0x00000000;
|
||||
si->intUniforms[3] = 0x00000000;
|
||||
si->float24Uniforms = NULL;
|
||||
si->intUniformMask = 0;
|
||||
|
||||
int i;
|
||||
DVLE_constEntry_s* cnst = dvle->constTableData;
|
||||
if(cnst)
|
||||
{
|
||||
int float24cnt=0;
|
||||
for(i=0; i<dvle->constTableSize; i++)
|
||||
{
|
||||
switch(cnst[i].type)
|
||||
{
|
||||
case DVLE_CONST_BOOL:
|
||||
shaderInstanceSetBool(si, cnst[i].id, cnst[i].data[0]&1);
|
||||
break;
|
||||
case DVLE_CONST_u8:
|
||||
if(cnst[i].id<4)
|
||||
{
|
||||
si->intUniforms[cnst[i].id] = cnst[i].data[0];
|
||||
si->intUniformMask |= (1<<cnst[i].id);
|
||||
}
|
||||
break;
|
||||
case DVLE_CONST_FLOAT24:
|
||||
float24cnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(float24cnt)
|
||||
{
|
||||
si->float24Uniforms = malloc(sizeof(float24Uniform_s)*float24cnt);
|
||||
if(si->float24Uniforms)
|
||||
{
|
||||
float24cnt = 0;
|
||||
u32 rev[3];
|
||||
u8* rev8=(u8*)rev;
|
||||
for(i=0; i<dvle->constTableSize; i++)
|
||||
{
|
||||
if(cnst[i].type==DVLE_CONST_FLOAT24)
|
||||
{
|
||||
memcpy(&rev8[0], &cnst[i].data[0], 3);
|
||||
memcpy(&rev8[3], &cnst[i].data[1], 3);
|
||||
memcpy(&rev8[6], &cnst[i].data[2], 3);
|
||||
memcpy(&rev8[9], &cnst[i].data[3], 3);
|
||||
|
||||
si->float24Uniforms[float24cnt].id = cnst[i].id&0xFF;
|
||||
si->float24Uniforms[float24cnt].data[0] = rev[2];
|
||||
si->float24Uniforms[float24cnt].data[1] = rev[1];
|
||||
si->float24Uniforms[float24cnt].data[2] = rev[0];
|
||||
|
||||
float24cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
si->numFloat24Uniforms = float24cnt;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderInstanceFree(shaderInstance_s* si)
|
||||
{
|
||||
if(!si)return -1;
|
||||
|
||||
if(si->float24Uniforms)free(si->float24Uniforms);
|
||||
free(si);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderInstanceSetBool(shaderInstance_s* si, int id, bool value)
|
||||
{
|
||||
if(!si)return -1;
|
||||
if(id<0 || id>15)return -2;
|
||||
|
||||
si->boolUniforms &= ~(1<<id);
|
||||
si->boolUniforms |= (value)<<id;
|
||||
si->boolUniformMask |= (1<<id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderInstanceGetBool(shaderInstance_s* si, int id, bool* value)
|
||||
{
|
||||
if(!si)return -1;
|
||||
if(id<0 || id>15)return -2;
|
||||
if(!value)return -3;
|
||||
|
||||
*value = ((si->boolUniforms>>id)&1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s8 shaderInstanceGetUniformLocation(shaderInstance_s* si, const char* name)
|
||||
{
|
||||
if(!si)return -1;
|
||||
|
||||
return DVLE_GetUniformRegister(si->dvle, name);
|
||||
}
|
||||
|
||||
Result shaderProgramInit(shaderProgram_s* sp)
|
||||
{
|
||||
if(!sp)return -1;
|
||||
|
||||
sp->vertexShader = NULL;
|
||||
sp->geometryShader = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderProgramFree(shaderProgram_s* sp)
|
||||
{
|
||||
if(!sp)return -1;
|
||||
|
||||
shaderInstanceFree(sp->vertexShader);
|
||||
shaderInstanceFree(sp->geometryShader);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderProgramSetVsh(shaderProgram_s* sp, DVLE_s* dvle)
|
||||
{
|
||||
if(!sp || !dvle)return -1;
|
||||
if(dvle->type != VERTEX_SHDR)return -2;
|
||||
|
||||
if(sp->vertexShader)shaderInstanceFree(sp->vertexShader);
|
||||
|
||||
sp->vertexShader = (shaderInstance_s*)malloc(sizeof(shaderInstance_s));
|
||||
if(!sp->vertexShader)return -3;
|
||||
|
||||
return shaderInstanceInit(sp->vertexShader, dvle);
|
||||
}
|
||||
|
||||
Result shaderProgramSetGsh(shaderProgram_s* sp, DVLE_s* dvle, u8 stride)
|
||||
{
|
||||
if(!sp || !dvle)return -1;
|
||||
if(dvle->type != GEOMETRY_SHDR)return -2;
|
||||
|
||||
if(sp->geometryShader)shaderInstanceFree(sp->geometryShader);
|
||||
|
||||
sp->geometryShader = (shaderInstance_s*)malloc(sizeof(shaderInstance_s));
|
||||
if(!sp->geometryShader)return -3;
|
||||
|
||||
sp->geoShaderInputPermutation[0] = 0x76543210;
|
||||
sp->geoShaderInputPermutation[1] = 0xFEDCBA98;
|
||||
sp->geoShaderInputStride = stride;
|
||||
|
||||
return shaderInstanceInit(sp->geometryShader, dvle);
|
||||
}
|
||||
|
||||
Result shaderProgramSetGshInputPermutation(shaderProgram_s* sp, u64 permutation)
|
||||
{
|
||||
if(!sp || !sp->geometryShader)return -1;
|
||||
|
||||
sp->geoShaderInputPermutation[0] = permutation & 0xFFFFFFFF;
|
||||
sp->geoShaderInputPermutation[0] = permutation>>32;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void shaderProgramUploadDvle(const DVLE_s* dvle)
|
||||
{
|
||||
const DVLP_s* dvlp = dvle->dvlp;
|
||||
// Limit vertex shader code size to the first 512 instructions
|
||||
int codeSize = dvle->type == GEOMETRY_SHDR ? dvlp->codeSize : (dvlp->codeSize < 512 ? dvlp->codeSize : 512);
|
||||
GPU_SendShaderCode(dvle->type, dvlp->codeData, 0, codeSize);
|
||||
GPU_SendOperandDescriptors(dvle->type, dvlp->opcdescData, 0, dvlp->opdescSize);
|
||||
}
|
||||
|
||||
static inline void shaderProgramMergeOutmaps(u32* outmapData, const u32* vshOutmap, const u32* gshOutmap)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// Find and copy attributes common to both vertex and geometry shader
|
||||
u32 vsh_common = 0, gsh_common = 0;
|
||||
for (i = 1; i < 8; i ++)
|
||||
{
|
||||
u32 mask = gshOutmap[i];
|
||||
if (mask == 0x1F1F1F1F)
|
||||
break;
|
||||
for (j = 1; j < 8; j ++)
|
||||
{
|
||||
if (vshOutmap[j] == mask)
|
||||
{
|
||||
outmapData[++outmapData[0]] = mask;
|
||||
vsh_common |= BIT(j);
|
||||
gsh_common |= BIT(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find and copy attributes that are exclusive to the geometry shader
|
||||
for (i = 1; i < 8; i ++)
|
||||
{
|
||||
u32 mask = gshOutmap[i];
|
||||
if (mask == 0x1F1F1F1F)
|
||||
break;
|
||||
if (!(gsh_common & BIT(i)))
|
||||
outmapData[++outmapData[0]] = mask;
|
||||
}
|
||||
|
||||
// Find and copy attributes that are exclusive to the vertex shader
|
||||
for (i = 1; i < 8; i ++)
|
||||
{
|
||||
u32 mask = vshOutmap[i];
|
||||
if (mask == 0x1F1F1F1F)
|
||||
break;
|
||||
if (!(vsh_common & BIT(i)))
|
||||
outmapData[++outmapData[0]] = mask;
|
||||
}
|
||||
}
|
||||
|
||||
Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGshCode)
|
||||
{
|
||||
if (!sp || !sp->vertexShader) return -1;
|
||||
|
||||
// Get pointers to relevant structures
|
||||
const DVLE_s* vshDvle = sp->vertexShader->dvle;
|
||||
const DVLE_s* gshDvle = sp->geometryShader ? sp->geometryShader->dvle : NULL;
|
||||
const DVLE_s* mainDvle = gshDvle ? gshDvle : vshDvle;
|
||||
|
||||
// Variables for working with the outmap
|
||||
u32 outmapData[8];
|
||||
u32 outmapMode = mainDvle->outmapMode;
|
||||
u32 outmapClock = mainDvle->outmapClock;
|
||||
|
||||
// Initialize geometry engine - do this early in order to ensure all 4 units are correctly initialized
|
||||
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0x3, gshDvle ? 2 : 0);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG2, 0x3, 0);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_VSH_COM_MODE, 0x1, gshDvle ? 1 : 0);
|
||||
|
||||
// Set up vertex shader code blob (if necessary)
|
||||
if (sendVshCode)
|
||||
shaderProgramUploadDvle(vshDvle);
|
||||
|
||||
// Set up vertex shader entrypoint & outmap mask
|
||||
GPUCMD_AddWrite(GPUREG_VSH_ENTRYPOINT, 0x7FFF0000|(vshDvle->mainOffset&0xFFFF));
|
||||
GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_MASK, vshDvle->outmapMask);
|
||||
GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_TOTAL1, vshDvle->outmapData[0]-1);
|
||||
GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_TOTAL2, vshDvle->outmapData[0]-1);
|
||||
|
||||
// Set up geometry shader (if present)
|
||||
if (gshDvle)
|
||||
{
|
||||
// Set up geometry shader code blob (if necessary)
|
||||
if (sendGshCode)
|
||||
shaderProgramUploadDvle(gshDvle);
|
||||
|
||||
// Set up geometry shader entrypoint & outmap mask
|
||||
GPUCMD_AddWrite(GPUREG_GSH_ENTRYPOINT, 0x7FFF0000|(gshDvle->mainOffset&0xFFFF));
|
||||
GPUCMD_AddWrite(GPUREG_GSH_OUTMAP_MASK, gshDvle->outmapMask);
|
||||
}
|
||||
|
||||
// Merge vertex shader & geometry shader outmaps if requested
|
||||
if (gshDvle && gshDvle->mergeOutmaps)
|
||||
{
|
||||
// Clear outmap
|
||||
memset(outmapData, 0x1F, sizeof(outmapData));
|
||||
outmapData[0] = 0;
|
||||
|
||||
// Merge outmaps
|
||||
shaderProgramMergeOutmaps(outmapData, vshDvle->outmapData, gshDvle->outmapData);
|
||||
outmapMode |= vshDvle->outmapMode;
|
||||
outmapClock |= vshDvle->outmapClock;
|
||||
} else
|
||||
memcpy(outmapData, mainDvle->outmapData, sizeof(outmapData));
|
||||
|
||||
// Upload and configure outmap
|
||||
GPU_SetShaderOutmap(outmapData);
|
||||
GPUCMD_AddWrite(GPUREG_SH_OUTATTR_MODE, outmapMode);
|
||||
GPUCMD_AddWrite(GPUREG_SH_OUTATTR_CLOCK, outmapClock);
|
||||
|
||||
// Configure geostage
|
||||
if (gshDvle)
|
||||
{
|
||||
// Input stride: use value if specified, otherwise use number of outputs in vertex shader
|
||||
int stride = sp->geoShaderInputStride ? sp->geoShaderInputStride : vshDvle->outmapData[0];
|
||||
|
||||
// Enable or disable variable-size primitive processing
|
||||
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0xA, gshDvle->gshMode == GSH_VARIABLE_PRIM ? 0x80000000 : 0);
|
||||
|
||||
// Set up geoshader processing mode
|
||||
u32 misc = gshDvle->gshMode;
|
||||
if (misc == GSH_FIXED_PRIM)
|
||||
misc |= 0x01000000 | ((u32)gshDvle->gshFixedVtxStart<<16) | ((stride-1)<<12) | ((u32)(gshDvle->gshFixedVtxNum-1)<<8);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_MISC0, misc);
|
||||
|
||||
// Set up variable-size primitive mode parameters
|
||||
GPUCMD_AddWrite(GPUREG_GSH_MISC1, gshDvle->gshMode == GSH_VARIABLE_PRIM ? (gshDvle->gshVariableVtxNum-1) : 0);
|
||||
|
||||
// Set up geoshader input
|
||||
GPUCMD_AddWrite(GPUREG_GSH_INPUTBUFFER_CONFIG, 0x08000000 | (gshDvle->gshMode ? 0x0100 : 0) | (stride-1));
|
||||
|
||||
// Set up geoshader permutation
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW, sp->geoShaderInputPermutation, 2);
|
||||
} else
|
||||
{
|
||||
// Defaults for when geostage is disabled
|
||||
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0xA, 0);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_MISC0, 0);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_MISC1, 0);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_INPUTBUFFER_CONFIG, 0xA0000000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderProgramUse(shaderProgram_s* sp)
|
||||
{
|
||||
Result rc = shaderProgramConfigure(sp, true, true);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
int i;
|
||||
|
||||
// Set up uniforms
|
||||
GPUCMD_AddWrite(GPUREG_VSH_BOOLUNIFORM, 0x7FFF0000|sp->vertexShader->boolUniforms);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_VSH_INTUNIFORM_I0, sp->vertexShader->intUniforms, 4);
|
||||
for(i=0; i<sp->vertexShader->numFloat24Uniforms; i++) GPUCMD_AddIncrementalWrites(GPUREG_VSH_FLOATUNIFORM_CONFIG, (u32*)&sp->vertexShader->float24Uniforms[i], 4);
|
||||
if (sp->geometryShader)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_GSH_BOOLUNIFORM, 0x7FFF0000|sp->geometryShader->boolUniforms);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_GSH_INTUNIFORM_I0, sp->geometryShader->intUniforms, 4);
|
||||
for(i=0; i<sp->geometryShader->numFloat24Uniforms; i++) GPUCMD_AddIncrementalWrites(GPUREG_GSH_FLOATUNIFORM_CONFIG, (u32*)&sp->geometryShader->float24Uniforms[i], 4);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GPU_SetShaderOutmap(const u32 outmapData[8])
|
||||
{
|
||||
GPUCMD_AddMaskedWrite(GPUREG_PRIMITIVE_CONFIG, 0x1, outmapData[0]-1);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_SH_OUTMAP_TOTAL, outmapData, 8);
|
||||
}
|
||||
|
||||
void GPU_SendShaderCode(GPU_SHADER_TYPE type, u32* data, u16 offset, u16 length)
|
||||
{
|
||||
if(!data)return;
|
||||
|
||||
int regOffset=(type==GPU_GEOMETRY_SHADER)?(-0x30):(0x0);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_VSH_CODETRANSFER_CONFIG+regOffset, offset);
|
||||
|
||||
int i;
|
||||
for(i=0;i<length;i+=0x80)GPUCMD_AddWrites(GPUREG_VSH_CODETRANSFER_DATA+regOffset, &data[i], ((length-i)<0x80)?(length-i):0x80);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_VSH_CODETRANSFER_END+regOffset, 0x00000001);
|
||||
}
|
||||
|
||||
void GPU_SendOperandDescriptors(GPU_SHADER_TYPE type, u32* data, u16 offset, u16 length)
|
||||
{
|
||||
if(!data)return;
|
||||
|
||||
int regOffset=(type==GPU_GEOMETRY_SHADER)?(-0x30):(0x0);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_VSH_OPDESCS_CONFIG+regOffset, offset);
|
||||
|
||||
GPUCMD_AddWrites(GPUREG_VSH_OPDESCS_DATA+regOffset, data, length);
|
||||
}
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/result.h>
|
||||
#include <3ds/gpu/registers.h>
|
||||
#include <3ds/gpu/shaderProgram.h>
|
||||
|
||||
static void GPU_SetShaderOutmap(const u32 outmapData[8]);
|
||||
static void GPU_SendShaderCode(GPU_SHADER_TYPE type, u32* data, u16 offset, u16 length);
|
||||
static void GPU_SendOperandDescriptors(GPU_SHADER_TYPE type, u32* data, u16 offset, u16 length);
|
||||
|
||||
Result shaderInstanceInit(shaderInstance_s* si, DVLE_s* dvle)
|
||||
{
|
||||
if(!si || !dvle)return -1;
|
||||
|
||||
si->dvle = dvle;
|
||||
|
||||
si->boolUniforms = 0;
|
||||
si->boolUniformMask = 0;
|
||||
si->intUniforms[0] = 0x00000000;
|
||||
si->intUniforms[1] = 0x00000000;
|
||||
si->intUniforms[2] = 0x00000000;
|
||||
si->intUniforms[3] = 0x00000000;
|
||||
si->float24Uniforms = NULL;
|
||||
si->intUniformMask = 0;
|
||||
|
||||
int i;
|
||||
DVLE_constEntry_s* cnst = dvle->constTableData;
|
||||
if(cnst)
|
||||
{
|
||||
int float24cnt=0;
|
||||
for(i=0; i<dvle->constTableSize; i++)
|
||||
{
|
||||
switch(cnst[i].type)
|
||||
{
|
||||
case DVLE_CONST_BOOL:
|
||||
shaderInstanceSetBool(si, cnst[i].id, cnst[i].data[0]&1);
|
||||
break;
|
||||
case DVLE_CONST_u8:
|
||||
if(cnst[i].id<4)
|
||||
{
|
||||
si->intUniforms[cnst[i].id] = cnst[i].data[0];
|
||||
si->intUniformMask |= (1<<cnst[i].id);
|
||||
}
|
||||
break;
|
||||
case DVLE_CONST_FLOAT24:
|
||||
float24cnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(float24cnt)
|
||||
{
|
||||
si->float24Uniforms = malloc(sizeof(float24Uniform_s)*float24cnt);
|
||||
if(si->float24Uniforms)
|
||||
{
|
||||
float24cnt = 0;
|
||||
u32 rev[3];
|
||||
u8* rev8=(u8*)rev;
|
||||
for(i=0; i<dvle->constTableSize; i++)
|
||||
{
|
||||
if(cnst[i].type==DVLE_CONST_FLOAT24)
|
||||
{
|
||||
memcpy(&rev8[0], &cnst[i].data[0], 3);
|
||||
memcpy(&rev8[3], &cnst[i].data[1], 3);
|
||||
memcpy(&rev8[6], &cnst[i].data[2], 3);
|
||||
memcpy(&rev8[9], &cnst[i].data[3], 3);
|
||||
|
||||
si->float24Uniforms[float24cnt].id = cnst[i].id&0xFF;
|
||||
si->float24Uniforms[float24cnt].data[0] = rev[2];
|
||||
si->float24Uniforms[float24cnt].data[1] = rev[1];
|
||||
si->float24Uniforms[float24cnt].data[2] = rev[0];
|
||||
|
||||
float24cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
si->numFloat24Uniforms = float24cnt;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderInstanceFree(shaderInstance_s* si)
|
||||
{
|
||||
if(!si)return -1;
|
||||
|
||||
if(si->float24Uniforms)free(si->float24Uniforms);
|
||||
free(si);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderInstanceSetBool(shaderInstance_s* si, int id, bool value)
|
||||
{
|
||||
if(!si)return -1;
|
||||
if(id<0 || id>15)return -2;
|
||||
|
||||
si->boolUniforms &= ~(1<<id);
|
||||
si->boolUniforms |= (value)<<id;
|
||||
si->boolUniformMask |= (1<<id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderInstanceGetBool(shaderInstance_s* si, int id, bool* value)
|
||||
{
|
||||
if(!si)return -1;
|
||||
if(id<0 || id>15)return -2;
|
||||
if(!value)return -3;
|
||||
|
||||
*value = ((si->boolUniforms>>id)&1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s8 shaderInstanceGetUniformLocation(shaderInstance_s* si, const char* name)
|
||||
{
|
||||
if(!si)return -1;
|
||||
|
||||
return DVLE_GetUniformRegister(si->dvle, name);
|
||||
}
|
||||
|
||||
Result shaderProgramInit(shaderProgram_s* sp)
|
||||
{
|
||||
if(!sp)return -1;
|
||||
|
||||
sp->vertexShader = NULL;
|
||||
sp->geometryShader = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderProgramFree(shaderProgram_s* sp)
|
||||
{
|
||||
if(!sp)return -1;
|
||||
|
||||
shaderInstanceFree(sp->vertexShader);
|
||||
shaderInstanceFree(sp->geometryShader);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderProgramSetVsh(shaderProgram_s* sp, DVLE_s* dvle)
|
||||
{
|
||||
if(!sp || !dvle)return -1;
|
||||
if(dvle->type != VERTEX_SHDR)return -2;
|
||||
|
||||
if(sp->vertexShader)shaderInstanceFree(sp->vertexShader);
|
||||
|
||||
sp->vertexShader = (shaderInstance_s*)malloc(sizeof(shaderInstance_s));
|
||||
if(!sp->vertexShader)return -3;
|
||||
|
||||
return shaderInstanceInit(sp->vertexShader, dvle);
|
||||
}
|
||||
|
||||
Result shaderProgramSetGsh(shaderProgram_s* sp, DVLE_s* dvle, u8 stride)
|
||||
{
|
||||
if(!sp || !dvle)return -1;
|
||||
if(dvle->type != GEOMETRY_SHDR)return -2;
|
||||
|
||||
if(sp->geometryShader)shaderInstanceFree(sp->geometryShader);
|
||||
|
||||
sp->geometryShader = (shaderInstance_s*)malloc(sizeof(shaderInstance_s));
|
||||
if(!sp->geometryShader)return -3;
|
||||
|
||||
sp->geoShaderInputPermutation[0] = 0x76543210;
|
||||
sp->geoShaderInputPermutation[1] = 0xFEDCBA98;
|
||||
sp->geoShaderInputStride = stride;
|
||||
|
||||
return shaderInstanceInit(sp->geometryShader, dvle);
|
||||
}
|
||||
|
||||
Result shaderProgramSetGshInputPermutation(shaderProgram_s* sp, u64 permutation)
|
||||
{
|
||||
if(!sp || !sp->geometryShader)return -1;
|
||||
|
||||
sp->geoShaderInputPermutation[0] = permutation & 0xFFFFFFFF;
|
||||
sp->geoShaderInputPermutation[0] = permutation>>32;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void shaderProgramUploadDvle(const DVLE_s* dvle)
|
||||
{
|
||||
const DVLP_s* dvlp = dvle->dvlp;
|
||||
// Limit vertex shader code size to the first 512 instructions
|
||||
int codeSize = dvle->type == GEOMETRY_SHDR ? dvlp->codeSize : (dvlp->codeSize < 512 ? dvlp->codeSize : 512);
|
||||
GPU_SendShaderCode(dvle->type, dvlp->codeData, 0, codeSize);
|
||||
GPU_SendOperandDescriptors(dvle->type, dvlp->opcdescData, 0, dvlp->opdescSize);
|
||||
}
|
||||
|
||||
static inline void shaderProgramMergeOutmaps(u32* outmapData, const u32* vshOutmap, const u32* gshOutmap)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// Find and copy attributes common to both vertex and geometry shader
|
||||
u32 vsh_common = 0, gsh_common = 0;
|
||||
for (i = 1; i < 8; i ++)
|
||||
{
|
||||
u32 mask = gshOutmap[i];
|
||||
if (mask == 0x1F1F1F1F)
|
||||
break;
|
||||
for (j = 1; j < 8; j ++)
|
||||
{
|
||||
if (vshOutmap[j] == mask)
|
||||
{
|
||||
outmapData[++outmapData[0]] = mask;
|
||||
vsh_common |= BIT(j);
|
||||
gsh_common |= BIT(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find and copy attributes that are exclusive to the geometry shader
|
||||
for (i = 1; i < 8; i ++)
|
||||
{
|
||||
u32 mask = gshOutmap[i];
|
||||
if (mask == 0x1F1F1F1F)
|
||||
break;
|
||||
if (!(gsh_common & BIT(i)))
|
||||
outmapData[++outmapData[0]] = mask;
|
||||
}
|
||||
|
||||
// Find and copy attributes that are exclusive to the vertex shader
|
||||
for (i = 1; i < 8; i ++)
|
||||
{
|
||||
u32 mask = vshOutmap[i];
|
||||
if (mask == 0x1F1F1F1F)
|
||||
break;
|
||||
if (!(vsh_common & BIT(i)))
|
||||
outmapData[++outmapData[0]] = mask;
|
||||
}
|
||||
}
|
||||
|
||||
Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGshCode)
|
||||
{
|
||||
if (!sp || !sp->vertexShader) return -1;
|
||||
|
||||
// Get pointers to relevant structures
|
||||
const DVLE_s* vshDvle = sp->vertexShader->dvle;
|
||||
const DVLE_s* gshDvle = sp->geometryShader ? sp->geometryShader->dvle : NULL;
|
||||
const DVLE_s* mainDvle = gshDvle ? gshDvle : vshDvle;
|
||||
|
||||
// Variables for working with the outmap
|
||||
u32 outmapData[8];
|
||||
u32 outmapMode = mainDvle->outmapMode;
|
||||
u32 outmapClock = mainDvle->outmapClock;
|
||||
|
||||
// Initialize geometry engine - do this early in order to ensure all 4 units are correctly initialized
|
||||
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0x3, gshDvle ? 2 : 0);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG2, 0x3, 0);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_VSH_COM_MODE, 0x1, gshDvle ? 1 : 0);
|
||||
|
||||
// Set up vertex shader code blob (if necessary)
|
||||
if (sendVshCode)
|
||||
shaderProgramUploadDvle(vshDvle);
|
||||
|
||||
// Set up vertex shader entrypoint & outmap mask
|
||||
GPUCMD_AddWrite(GPUREG_VSH_ENTRYPOINT, 0x7FFF0000|(vshDvle->mainOffset&0xFFFF));
|
||||
GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_MASK, vshDvle->outmapMask);
|
||||
GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_TOTAL1, vshDvle->outmapData[0]-1);
|
||||
GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_TOTAL2, vshDvle->outmapData[0]-1);
|
||||
|
||||
// Set up geometry shader (if present)
|
||||
if (gshDvle)
|
||||
{
|
||||
// Set up geometry shader code blob (if necessary)
|
||||
if (sendGshCode)
|
||||
shaderProgramUploadDvle(gshDvle);
|
||||
|
||||
// Set up geometry shader entrypoint & outmap mask
|
||||
GPUCMD_AddWrite(GPUREG_GSH_ENTRYPOINT, 0x7FFF0000|(gshDvle->mainOffset&0xFFFF));
|
||||
GPUCMD_AddWrite(GPUREG_GSH_OUTMAP_MASK, gshDvle->outmapMask);
|
||||
}
|
||||
|
||||
// Merge vertex shader & geometry shader outmaps if requested
|
||||
if (gshDvle && gshDvle->mergeOutmaps)
|
||||
{
|
||||
// Clear outmap
|
||||
memset(outmapData, 0x1F, sizeof(outmapData));
|
||||
outmapData[0] = 0;
|
||||
|
||||
// Merge outmaps
|
||||
shaderProgramMergeOutmaps(outmapData, vshDvle->outmapData, gshDvle->outmapData);
|
||||
outmapMode |= vshDvle->outmapMode;
|
||||
outmapClock |= vshDvle->outmapClock;
|
||||
} else
|
||||
memcpy(outmapData, mainDvle->outmapData, sizeof(outmapData));
|
||||
|
||||
// Upload and configure outmap
|
||||
GPU_SetShaderOutmap(outmapData);
|
||||
GPUCMD_AddWrite(GPUREG_SH_OUTATTR_MODE, outmapMode);
|
||||
GPUCMD_AddWrite(GPUREG_SH_OUTATTR_CLOCK, outmapClock);
|
||||
|
||||
// Configure geostage
|
||||
if (gshDvle)
|
||||
{
|
||||
// Input stride: use value if specified, otherwise use number of outputs in vertex shader
|
||||
int stride = sp->geoShaderInputStride ? sp->geoShaderInputStride : vshDvle->outmapData[0];
|
||||
|
||||
// Enable or disable variable-size primitive processing
|
||||
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0xA, gshDvle->gshMode == GSH_VARIABLE_PRIM ? 0x80000000 : 0);
|
||||
|
||||
// Set up geoshader processing mode
|
||||
u32 misc = gshDvle->gshMode;
|
||||
if (misc == GSH_FIXED_PRIM)
|
||||
misc |= 0x01000000 | ((u32)gshDvle->gshFixedVtxStart<<16) | ((stride-1)<<12) | ((u32)(gshDvle->gshFixedVtxNum-1)<<8);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_MISC0, misc);
|
||||
|
||||
// Set up variable-size primitive mode parameters
|
||||
GPUCMD_AddWrite(GPUREG_GSH_MISC1, gshDvle->gshMode == GSH_VARIABLE_PRIM ? (gshDvle->gshVariableVtxNum-1) : 0);
|
||||
|
||||
// Set up geoshader input
|
||||
GPUCMD_AddWrite(GPUREG_GSH_INPUTBUFFER_CONFIG, 0x08000000 | (gshDvle->gshMode ? 0x0100 : 0) | (stride-1));
|
||||
|
||||
// Set up geoshader permutation
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW, sp->geoShaderInputPermutation, 2);
|
||||
} else
|
||||
{
|
||||
// Defaults for when geostage is disabled
|
||||
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0xA, 0);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_MISC0, 0);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_MISC1, 0);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_INPUTBUFFER_CONFIG, 0xA0000000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result shaderProgramUse(shaderProgram_s* sp)
|
||||
{
|
||||
Result rc = shaderProgramConfigure(sp, true, true);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
int i;
|
||||
|
||||
// Set up uniforms
|
||||
GPUCMD_AddWrite(GPUREG_VSH_BOOLUNIFORM, 0x7FFF0000|sp->vertexShader->boolUniforms);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_VSH_INTUNIFORM_I0, sp->vertexShader->intUniforms, 4);
|
||||
for(i=0; i<sp->vertexShader->numFloat24Uniforms; i++) GPUCMD_AddIncrementalWrites(GPUREG_VSH_FLOATUNIFORM_CONFIG, (u32*)&sp->vertexShader->float24Uniforms[i], 4);
|
||||
if (sp->geometryShader)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_GSH_BOOLUNIFORM, 0x7FFF0000|sp->geometryShader->boolUniforms);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_GSH_INTUNIFORM_I0, sp->geometryShader->intUniforms, 4);
|
||||
for(i=0; i<sp->geometryShader->numFloat24Uniforms; i++) GPUCMD_AddIncrementalWrites(GPUREG_GSH_FLOATUNIFORM_CONFIG, (u32*)&sp->geometryShader->float24Uniforms[i], 4);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GPU_SetShaderOutmap(const u32 outmapData[8])
|
||||
{
|
||||
GPUCMD_AddMaskedWrite(GPUREG_PRIMITIVE_CONFIG, 0x1, outmapData[0]-1);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_SH_OUTMAP_TOTAL, outmapData, 8);
|
||||
}
|
||||
|
||||
void GPU_SendShaderCode(GPU_SHADER_TYPE type, u32* data, u16 offset, u16 length)
|
||||
{
|
||||
if(!data)return;
|
||||
|
||||
int regOffset=(type==GPU_GEOMETRY_SHADER)?(-0x30):(0x0);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_VSH_CODETRANSFER_CONFIG+regOffset, offset);
|
||||
|
||||
int i;
|
||||
for(i=0;i<length;i+=0x80)GPUCMD_AddWrites(GPUREG_VSH_CODETRANSFER_DATA+regOffset, &data[i], ((length-i)<0x80)?(length-i):0x80);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_VSH_CODETRANSFER_END+regOffset, 0x00000001);
|
||||
}
|
||||
|
||||
void GPU_SendOperandDescriptors(GPU_SHADER_TYPE type, u32* data, u16 offset, u16 length)
|
||||
{
|
||||
if(!data)return;
|
||||
|
||||
int regOffset=(type==GPU_GEOMETRY_SHADER)?(-0x30):(0x0);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_VSH_OPDESCS_CONFIG+regOffset, offset);
|
||||
|
||||
GPUCMD_AddWrites(GPUREG_VSH_OPDESCS_DATA+regOffset, data, length);
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ void DVLE_GenerateOutmap(DVLE_s* dvle)
|
||||
int mask = dvle->outTableData[i].mask;
|
||||
int regID = dvle->outTableData[i].regID;
|
||||
u32* out = &dvle->outmapData[regID+1];
|
||||
|
||||
|
||||
if (!(dvle->outmapMask & BIT(regID)))
|
||||
{
|
||||
dvle->outmapMask |= BIT(regID);
|
||||
|
@ -548,7 +548,7 @@ sdmc_write_safe(struct _reent *r,
|
||||
memcpy(tmp_buffer, ptr, toWrite);
|
||||
|
||||
/* write the data */
|
||||
rc = FSFILE_Write(file->fd, &bytes, file->offset,
|
||||
rc = FSFILE_Write(file->fd, &bytes, file->offset,
|
||||
(u32*)tmp_buffer, (u32)toWrite, sync);
|
||||
if(R_FAILED(rc))
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ Result AM_GetTitleCount(FS_MediaType mediatype, u32 *count)
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(count) *count = cmdbuf[2];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ Result AM_GetTitleList(u32* titlesRead, FS_MediaType mediatype, u32 titleCount,
|
||||
cmdbuf[4] = (u32)titleIds;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
|
||||
if(titlesRead) *titlesRead = cmdbuf[2];
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
@ -112,7 +112,7 @@ Result AM_GetTicketCount(u32 *count)
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(count) *count = cmdbuf[2];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ Result AM_GetTicketList(u32 *ticketsRead, u32 ticketCount, u32 skip, u64 *ticket
|
||||
cmdbuf[4] = (u32)ticketIds;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
|
||||
if(ticketsRead) *ticketsRead = cmdbuf[2];
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
@ -146,7 +146,7 @@ Result AM_GetPendingTitleCount(u32 *count, FS_MediaType mediatype, u32 statusMas
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(count) *count = cmdbuf[2];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ Result AM_GetPendingTitleList(u32 *titlesRead, u32 titleCount, FS_MediaType medi
|
||||
cmdbuf[5] = (u32)titleIds;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
|
||||
if(titlesRead) *titlesRead = cmdbuf[2];
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
@ -197,7 +197,7 @@ Result AM_GetDeviceId(u32 *deviceID)
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(deviceID) *deviceID = cmdbuf[3];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ Result AM_StartCiaInstall(FS_MediaType mediatype, Handle *ciaHandle)
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(ciaHandle) *ciaHandle = cmdbuf[3];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -311,7 +311,7 @@ Result AM_StartDlpChildCiaInstall(Handle *ciaHandle)
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(ciaHandle) *ciaHandle = cmdbuf[3];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -458,12 +458,12 @@ Result AM_GetTitleProductCode(FS_MediaType mediatype, u64 titleId, char *product
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x5,3,0); // 0x000500C0
|
||||
cmdbuf[1] = mediatype;
|
||||
cmdbuf[2] = titleId & 0xffffffff;
|
||||
cmdbuf[3] = (u32)(titleId >> 32);
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
// The product code string can use the full 16 bytes without NULL terminator
|
||||
@ -476,12 +476,12 @@ Result AM_GetTitleExtDataId(u64 *extDataId, FS_MediaType mediatype, u64 titleId)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x6,3,0); // 0x000600C0
|
||||
cmdbuf[1] = mediatype;
|
||||
cmdbuf[2] = titleId & 0xffffffff;
|
||||
cmdbuf[3] = (u32)(titleId >> 32);
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(extDataId) *extDataId = (u64)cmdbuf[2] | ((u64)cmdbuf[3] << 32);
|
||||
@ -493,7 +493,7 @@ Result AM_GetCiaFileInfo(FS_MediaType mediatype, AM_TitleEntry *titleEntry, Hand
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x408,1,2); // 0x04080042
|
||||
cmdbuf[1] = mediatype;
|
||||
cmdbuf[2] = IPC_Desc_SharedHandles(1);
|
||||
@ -594,7 +594,7 @@ Result AM_GetCiaMetaSection(void *meta, u32 size, Handle fileHandle)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x414,1,4); // 0x04140044
|
||||
cmdbuf[1] = size;
|
||||
cmdbuf[2] = IPC_Desc_SharedHandles(1);
|
||||
@ -648,7 +648,7 @@ Result AM_InstallTicketBegin(Handle *ticketHandle)
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(ticketHandle) *ticketHandle = cmdbuf[3];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -775,7 +775,7 @@ Result AM_InstallTmdBegin(Handle *tmdHandle)
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(tmdHandle) *tmdHandle = cmdbuf[3];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -834,7 +834,7 @@ Result AM_InstallContentBegin(Handle *contentHandle, u16 index)
|
||||
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
|
||||
|
||||
if(contentHandle) *contentHandle = cmdbuf[3];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -864,7 +864,7 @@ Result AM_InstallContentResume(Handle *contentHandle, u64* resumeOffset, u16 ind
|
||||
|
||||
if(contentHandle) *contentHandle = cmdbuf[5];
|
||||
if(resumeOffset) *resumeOffset = cmdbuf[2] | ((u64)cmdbuf[3] << 32);
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ static void aptInitCaptureInfo(aptCaptureBufInfo* capinfo)
|
||||
|
||||
// Fill in display-capture info for NS.
|
||||
capinfo->is3D = (gspcapinfo.screencapture[0].format & 0x20) != 0;
|
||||
|
||||
|
||||
capinfo->top.format = gspcapinfo.screencapture[0].format & 0x7;
|
||||
capinfo->bottom.format = gspcapinfo.screencapture[1].format & 0x7;
|
||||
|
||||
@ -555,7 +555,7 @@ Result APT_GetLockHandle(u16 flags, Handle* lockHandle)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x1,1,0); // 0x10040
|
||||
cmdbuf[1]=flags;
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
if (R_SUCCEEDED(ret))
|
||||
*lockHandle = cmdbuf[5];
|
||||
@ -569,7 +569,7 @@ Result APT_Initialize(NS_APPID appId, APT_AppletAttr attr, Handle* signalEvent,
|
||||
cmdbuf[0]=IPC_MakeHeader(0x2,2,0); // 0x20080
|
||||
cmdbuf[1]=appId;
|
||||
cmdbuf[2]=attr;
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
if (R_SUCCEEDED(ret))
|
||||
{
|
||||
@ -585,7 +585,7 @@ Result APT_Finalize(NS_APPID appId)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x4,1,0); // 0x40040
|
||||
cmdbuf[1]=appId;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -593,7 +593,7 @@ Result APT_HardwareResetAsync(void)
|
||||
{
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x4E,0,0); // 0x4E0000
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -602,7 +602,7 @@ Result APT_Enable(APT_AppletAttr attr)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x3,1,0); // 0x30040
|
||||
cmdbuf[1]=attr;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -611,7 +611,7 @@ Result APT_GetAppletManInfo(APT_AppletPos inpos, APT_AppletPos* outpos, NS_APPID
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x5,1,0); // 0x50040
|
||||
cmdbuf[1]=inpos;
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
if (R_SUCCEEDED(ret))
|
||||
{
|
||||
@ -620,7 +620,7 @@ Result APT_GetAppletManInfo(APT_AppletPos inpos, APT_AppletPos* outpos, NS_APPID
|
||||
if (menu_appid) *menu_appid =cmdbuf[4];
|
||||
if (active_appid) *active_appid=cmdbuf[5];
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -662,7 +662,7 @@ Result APT_GetProgramID(u64* pProgramID)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0] = IPC_MakeHeader(0x58,0,2); // 0x580002
|
||||
cmdbuf[1] = IPC_Desc_CurProcessHandle();
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
if (R_SUCCEEDED(ret))
|
||||
*pProgramID=((u64)cmdbuf[3]<<32)|cmdbuf[2];
|
||||
@ -675,7 +675,7 @@ Result APT_IsRegistered(NS_APPID appID, bool* out)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x9,1,0); // 0x90040
|
||||
cmdbuf[1]=appID;
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
if (R_SUCCEEDED(ret))
|
||||
*out=cmdbuf[2] & 0xFF;
|
||||
@ -688,7 +688,7 @@ Result APT_InquireNotification(u32 appID, APT_Signal* signalType)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0xB,1,0); // 0xB0040
|
||||
cmdbuf[1]=appID;
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
if (R_SUCCEEDED(ret))
|
||||
{
|
||||
@ -703,7 +703,7 @@ Result APT_PrepareToJumpToHomeMenu(void)
|
||||
{
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x2B,0,0); // 0x2B0000
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -738,7 +738,7 @@ Result APT_JumpToApplication(const void* param, size_t paramSize, Handle handle)
|
||||
cmdbuf[3]=handle;
|
||||
cmdbuf[4]=IPC_Desc_StaticBuffer(cmdbuf[1],0);
|
||||
cmdbuf[5]= (u32) param;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -747,7 +747,7 @@ Result APT_NotifyToWait(NS_APPID appID)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x43,1,0); // 0x430040
|
||||
cmdbuf[1]=appID;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -767,7 +767,7 @@ Result APT_AppletUtility(int id, void* out, size_t outSize, const void* in, size
|
||||
saved_threadstorage[1]=staticbufs[1];
|
||||
staticbufs[0]=IPC_Desc_StaticBuffer(cmdbuf[3],0);
|
||||
staticbufs[1]=(u32)out;
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
staticbufs[0]=saved_threadstorage[0];
|
||||
staticbufs[1]=saved_threadstorage[1];
|
||||
@ -805,7 +805,7 @@ Result APT_GlanceParameter(NS_APPID appID, void* buffer, size_t bufferSize, NS_A
|
||||
saved_threadstorage[1]=staticbufs[1];
|
||||
staticbufs[0]=IPC_Desc_StaticBuffer(cmdbuf[2],0);
|
||||
staticbufs[1]=(u32)buffer;
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
staticbufs[0]=saved_threadstorage[0];
|
||||
staticbufs[1]=saved_threadstorage[1];
|
||||
@ -835,7 +835,7 @@ Result APT_ReceiveParameter(NS_APPID appID, void* buffer, size_t bufferSize, NS_
|
||||
saved_threadstorage[1]=staticbufs[1];
|
||||
staticbufs[0]=IPC_Desc_StaticBuffer(cmdbuf[2],0);
|
||||
staticbufs[1]=(u32)buffer;
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
staticbufs[0]=saved_threadstorage[0];
|
||||
staticbufs[1]=saved_threadstorage[1];
|
||||
@ -865,10 +865,10 @@ Result APT_SendParameter(NS_APPID source, NS_APPID dest, APT_Command command, co
|
||||
|
||||
cmdbuf[5] = IPC_Desc_SharedHandles(1);
|
||||
cmdbuf[6] = parameter;
|
||||
|
||||
|
||||
cmdbuf[7] = IPC_Desc_StaticBuffer(cmdbuf[4],0);
|
||||
cmdbuf[8] = (u32)buffer;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -897,7 +897,7 @@ Result APT_SendCaptureBufferInfo(const aptCaptureBufInfo* captureBuf)
|
||||
cmdbuf[1] = sizeof(*captureBuf);
|
||||
cmdbuf[2] = IPC_Desc_StaticBuffer(cmdbuf[1],0);
|
||||
cmdbuf[3] = (u32)captureBuf;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -907,7 +907,7 @@ Result APT_ReplySleepQuery(NS_APPID appID, APT_QueryReply reply)
|
||||
cmdbuf[0]=IPC_MakeHeader(0x3E,2,0); // 0x3E0080
|
||||
cmdbuf[1]=appID;
|
||||
cmdbuf[2]=reply;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -916,7 +916,7 @@ Result APT_ReplySleepNotificationComplete(NS_APPID appID)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x3F,1,0); // 0x3F0040
|
||||
cmdbuf[1]=appID;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -925,7 +925,7 @@ Result APT_PrepareToCloseApplication(bool cancelPreload)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x22,1,0); // 0x220040
|
||||
cmdbuf[1]=cancelPreload;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -938,7 +938,7 @@ Result APT_CloseApplication(const void* param, size_t paramSize, Handle handle)
|
||||
cmdbuf[3]=handle;
|
||||
cmdbuf[4]=IPC_Desc_StaticBuffer(cmdbuf[1],0);
|
||||
cmdbuf[5]= (u32) param;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -949,7 +949,7 @@ Result APT_SetAppCpuTimeLimit(u32 percent)
|
||||
cmdbuf[0]=IPC_MakeHeader(0x4F,2,0); // 0x4F0080
|
||||
cmdbuf[1]=1;
|
||||
cmdbuf[2]=percent;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -958,7 +958,7 @@ Result APT_GetAppCpuTimeLimit(u32 *percent)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x50,1,0); // 0x500040
|
||||
cmdbuf[1]=1;
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
if (R_SUCCEEDED(ret))
|
||||
*percent=cmdbuf[2];
|
||||
@ -970,7 +970,7 @@ static Result APT_CheckNew3DS_System(bool* out)
|
||||
{
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x102,0,0); // 0x1020000
|
||||
|
||||
|
||||
Result ret = aptSendCommand(cmdbuf);
|
||||
if (R_SUCCEEDED(ret))
|
||||
*out = cmdbuf[2] & 0xFF;
|
||||
@ -1001,7 +1001,7 @@ Result APT_PrepareToDoApplicationJump(u8 flags, u64 programID, u8 mediatype)
|
||||
cmdbuf[2]=(u32)programID;
|
||||
cmdbuf[3]=(u32)(programID>>32);
|
||||
cmdbuf[4]=mediatype;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -1015,7 +1015,7 @@ Result APT_DoApplicationJump(const void* param, size_t paramSize, const void* hm
|
||||
cmdbuf[4]=(u32)param;
|
||||
cmdbuf[5]=IPC_Desc_StaticBuffer(cmdbuf[2],2);
|
||||
cmdbuf[6]=(u32)hmac;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -1024,7 +1024,7 @@ Result APT_PrepareToStartLibraryApplet(NS_APPID appID)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x18,1,0); // 0x180040
|
||||
cmdbuf[1]=appID;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -1038,7 +1038,7 @@ Result APT_StartLibraryApplet(NS_APPID appID, const void* param, size_t paramSiz
|
||||
cmdbuf[4]=handle;
|
||||
cmdbuf[5]=IPC_Desc_StaticBuffer(cmdbuf[2],0);
|
||||
cmdbuf[6]=(u32)param;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -1047,7 +1047,7 @@ Result APT_PrepareToStartSystemApplet(NS_APPID appID)
|
||||
u32 cmdbuf[16];
|
||||
cmdbuf[0]=IPC_MakeHeader(0x19,1,0); // 0x190040
|
||||
cmdbuf[1]=appID;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
@ -1061,7 +1061,7 @@ Result APT_StartSystemApplet(NS_APPID appID, const void* param, size_t paramSize
|
||||
cmdbuf[4] = handle;
|
||||
cmdbuf[5] = IPC_Desc_StaticBuffer(cmdbuf[2],0);
|
||||
cmdbuf[6] = (u32)param;
|
||||
|
||||
|
||||
return aptSendCommand(cmdbuf);
|
||||
}
|
||||
|
||||
|
@ -152,9 +152,9 @@ Result DSP_ReadPipeIfPossible(u32 channel, u32 peer, void* buffer, u16 length, u
|
||||
|
||||
staticbufs[0] = saved1;
|
||||
staticbufs[1] = saved2;
|
||||
|
||||
|
||||
if (R_FAILED(ret)) return ret;
|
||||
|
||||
|
||||
if (length_read)
|
||||
*length_read = cmdbuf[2] & 0xFFFF;
|
||||
return cmdbuf[1];
|
||||
|
@ -60,7 +60,7 @@ Result GSPLCD_GetVendors(u8 *vendors)
|
||||
|
||||
Result ret=0;
|
||||
if (R_FAILED(ret = svcSendSyncRequest(gspLcdHandle))) return ret;
|
||||
|
||||
|
||||
if(vendors) *vendors = cmdbuf[2] & 0xFF;
|
||||
|
||||
return cmdbuf[1];
|
||||
|
@ -1,77 +1,77 @@
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/result.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/synchronization.h>
|
||||
#include <3ds/env.h>
|
||||
#include <3ds/ipc.h>
|
||||
|
||||
static Handle hbHandle;
|
||||
static int hbRefCount;
|
||||
|
||||
Result hbInit(void)
|
||||
{
|
||||
Result res=0;
|
||||
if (AtomicPostIncrement(&hbRefCount)) return 0;
|
||||
Handle temp = envGetHandle("hb:HB");
|
||||
res = temp ? svcDuplicateHandle(&hbHandle, temp) : MAKERESULT(RL_STATUS,RS_NOTFOUND,RM_APPLICATION,RD_NOT_FOUND);
|
||||
if (R_FAILED(res)) AtomicDecrement(&hbRefCount);
|
||||
return res;
|
||||
}
|
||||
|
||||
void hbExit(void)
|
||||
{
|
||||
if (AtomicDecrement(&hbRefCount)) return;
|
||||
svcCloseHandle(hbHandle);
|
||||
}
|
||||
|
||||
Result HB_FlushInvalidateCache(void)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x1,1,2); // 0x10042
|
||||
cmdbuf[1] = 0x00000000;
|
||||
cmdbuf[2] = IPC_Desc_SharedHandles(1);
|
||||
cmdbuf[3] = CUR_PROCESS_HANDLE;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(hbHandle))) return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result HB_GetBootloaderAddresses(void** load3dsx, void** setArgv)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x6,0,0); // 0x60000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(hbHandle))) return ret;
|
||||
|
||||
if(load3dsx)*load3dsx=(void*)cmdbuf[2];
|
||||
if(setArgv)*setArgv=(void*)cmdbuf[3];
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result HB_ReprotectMemory(u32* addr, u32 pages, u32 mode, u32* reprotectedPages)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x9,3,0); // 0x900C0
|
||||
cmdbuf[1] = (u32)addr;
|
||||
cmdbuf[2] = pages;
|
||||
cmdbuf[3] = mode;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(hbHandle))) return ret;
|
||||
|
||||
if(reprotectedPages)
|
||||
{
|
||||
if(R_SUCCEEDED(ret))*reprotectedPages=(u32)cmdbuf[2];
|
||||
else *reprotectedPages=0;
|
||||
}
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/result.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/synchronization.h>
|
||||
#include <3ds/env.h>
|
||||
#include <3ds/ipc.h>
|
||||
|
||||
static Handle hbHandle;
|
||||
static int hbRefCount;
|
||||
|
||||
Result hbInit(void)
|
||||
{
|
||||
Result res=0;
|
||||
if (AtomicPostIncrement(&hbRefCount)) return 0;
|
||||
Handle temp = envGetHandle("hb:HB");
|
||||
res = temp ? svcDuplicateHandle(&hbHandle, temp) : MAKERESULT(RL_STATUS,RS_NOTFOUND,RM_APPLICATION,RD_NOT_FOUND);
|
||||
if (R_FAILED(res)) AtomicDecrement(&hbRefCount);
|
||||
return res;
|
||||
}
|
||||
|
||||
void hbExit(void)
|
||||
{
|
||||
if (AtomicDecrement(&hbRefCount)) return;
|
||||
svcCloseHandle(hbHandle);
|
||||
}
|
||||
|
||||
Result HB_FlushInvalidateCache(void)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x1,1,2); // 0x10042
|
||||
cmdbuf[1] = 0x00000000;
|
||||
cmdbuf[2] = IPC_Desc_SharedHandles(1);
|
||||
cmdbuf[3] = CUR_PROCESS_HANDLE;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(hbHandle))) return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result HB_GetBootloaderAddresses(void** load3dsx, void** setArgv)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x6,0,0); // 0x60000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(hbHandle))) return ret;
|
||||
|
||||
if(load3dsx)*load3dsx=(void*)cmdbuf[2];
|
||||
if(setArgv)*setArgv=(void*)cmdbuf[3];
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
Result HB_ReprotectMemory(u32* addr, u32 pages, u32 mode, u32* reprotectedPages)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x9,3,0); // 0x900C0
|
||||
cmdbuf[1] = (u32)addr;
|
||||
cmdbuf[2] = pages;
|
||||
cmdbuf[3] = mode;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(hbHandle))) return ret;
|
||||
|
||||
if(reprotectedPages)
|
||||
{
|
||||
if(R_SUCCEEDED(ret))*reprotectedPages=(u32)cmdbuf[2];
|
||||
else *reprotectedPages=0;
|
||||
}
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ Result httpcCancelConnection(httpcContext *context)
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x4,1,0); // 0x40040
|
||||
cmdbuf[1]=context->httphandle;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(__httpc_servhandle)))return ret;
|
||||
|
||||
@ -181,7 +181,7 @@ static Result HTTPC_Initialize(Handle handle, u32 sharedmem_size, Handle sharedm
|
||||
cmdbuf[2]=IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[4]=IPC_Desc_SharedHandles(1);
|
||||
cmdbuf[5]=sharedmem_handle;// POST buffer memory block handle
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(handle)))return ret;
|
||||
|
||||
@ -210,10 +210,10 @@ static Result HTTPC_CreateContext(Handle handle, HTTPC_RequestMethod method, con
|
||||
cmdbuf[2]=method;
|
||||
cmdbuf[3]=IPC_Desc_Buffer(l,IPC_BUFFER_R);
|
||||
cmdbuf[4]=(u32)url;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(handle)))return ret;
|
||||
|
||||
|
||||
if(contextHandle)*contextHandle=cmdbuf[2];
|
||||
|
||||
return cmdbuf[1];
|
||||
@ -226,7 +226,7 @@ static Result HTTPC_InitializeConnectionSession(Handle handle, Handle contextHan
|
||||
cmdbuf[0]=IPC_MakeHeader(0x8,1,2); // 0x80042
|
||||
cmdbuf[1]=contextHandle;
|
||||
cmdbuf[2]=IPC_Desc_CurProcessHandle();
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(handle)))return ret;
|
||||
|
||||
@ -239,7 +239,7 @@ static Result HTTPC_SetProxyDefault(Handle handle, Handle contextHandle)
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0xE,1,0); // 0xE0040
|
||||
cmdbuf[1]=contextHandle;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(handle)))return ret;
|
||||
|
||||
@ -252,7 +252,7 @@ static Result HTTPC_CloseContext(Handle handle, Handle contextHandle)
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x3,1,0); // 0x30040
|
||||
cmdbuf[1]=contextHandle;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(handle)))return ret;
|
||||
|
||||
@ -274,7 +274,7 @@ Result httpcAddRequestHeaderField(httpcContext *context, const char* name, const
|
||||
cmdbuf[5]=(u32)name;
|
||||
cmdbuf[6]=IPC_Desc_Buffer(value_len,IPC_BUFFER_R);
|
||||
cmdbuf[7]=(u32)value;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
@ -296,7 +296,7 @@ Result httpcAddPostDataAscii(httpcContext *context, const char* name, const char
|
||||
cmdbuf[5]=(u32)name;
|
||||
cmdbuf[6]=IPC_Desc_Buffer(value_len,IPC_BUFFER_R);
|
||||
cmdbuf[7]=(u32)value;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
@ -327,7 +327,7 @@ Result httpcBeginRequest(httpcContext *context)
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x9,1,0); // 0x90040
|
||||
cmdbuf[1]=context->httphandle;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
@ -343,7 +343,7 @@ Result httpcReceiveData(httpcContext *context, u8* buffer, u32 size)
|
||||
cmdbuf[2]=size;
|
||||
cmdbuf[3]=IPC_Desc_Buffer(size,IPC_BUFFER_W);
|
||||
cmdbuf[4]=(u32)buffer;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
@ -361,7 +361,7 @@ Result httpcReceiveDataTimeout(httpcContext *context, u8* buffer, u32 size, u64
|
||||
cmdbuf[4]=(timeout >> 32) & 0xffffffff;
|
||||
cmdbuf[5]=IPC_Desc_Buffer(size,IPC_BUFFER_W);
|
||||
cmdbuf[6]=(u32)buffer;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
@ -374,7 +374,7 @@ Result httpcGetRequestState(httpcContext *context, HTTPC_RequestStatus* out)
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x5,1,0); // 0x50040
|
||||
cmdbuf[1]=context->httphandle;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
@ -389,7 +389,7 @@ Result httpcGetDownloadSizeState(httpcContext *context, u32* downloadedsize, u32
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x6,1,0); // 0x60040
|
||||
cmdbuf[1]=context->httphandle;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
@ -425,7 +425,7 @@ Result httpcGetResponseStatusCode(httpcContext *context, u32* out)
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x22,1,0); // 0x220040
|
||||
cmdbuf[1]=context->httphandle;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
@ -443,7 +443,7 @@ Result httpcGetResponseStatusCodeTimeout(httpcContext *context, u32* out, u64 ti
|
||||
cmdbuf[1]=context->httphandle;
|
||||
cmdbuf[2]=timeout & 0xffffffff;
|
||||
cmdbuf[3]=(timeout >> 32) & 0xffffffff;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
|
@ -109,7 +109,7 @@ u32 irrstCheckSectionUpdateTime(vu32 *sharedmem_section, u32 id)
|
||||
void irrstScanInput(void)
|
||||
{
|
||||
if(irrstRefCount==0)return;
|
||||
|
||||
|
||||
u32 Id=0;
|
||||
kHeld = 0;
|
||||
memset(&csPos, 0, sizeof(circlePosition));
|
||||
|
@ -252,7 +252,7 @@ Result mvdstdInit(MVDSTD_Mode mode, MVDSTD_InputFormat input_type, MVDSTD_Output
|
||||
if(mvdstd_mode==MVDMODE_VIDEOPROCESSING)
|
||||
{
|
||||
ret = MVDSTD_cmd5(tmpinitstruct.cmd5_inval0, tmpinitstruct.cmd5_inval1, tmpinitstruct.cmd5_inval2, tmpinitstruct.cmd5_inval3);
|
||||
if(ret!=MVD_STATUS_OK) goto cleanup3;
|
||||
if(ret!=MVD_STATUS_OK) goto cleanup3;
|
||||
}
|
||||
|
||||
ret = MVDSTD_cmd18();
|
||||
@ -261,7 +261,7 @@ Result mvdstdInit(MVDSTD_Mode mode, MVDSTD_InputFormat input_type, MVDSTD_Output
|
||||
if(mvdstd_mode==MVDMODE_VIDEOPROCESSING)
|
||||
{
|
||||
ret = MVDSTD_cmd1b(tmpinitstruct.cmd1b_inval);
|
||||
if(ret!=MVD_STATUS_OK) goto cleanup3;
|
||||
if(ret!=MVD_STATUS_OK) goto cleanup3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -71,9 +71,9 @@ Result NEWS_GetTotalNotifications(u32* num)
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0] = IPC_MakeHeader(0x5,0,0);
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(newsHandle))) return ret;
|
||||
|
||||
|
||||
*num = cmdbuf[2];
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
@ -88,7 +88,7 @@ Result NEWS_SetNotificationHeader(u32 news_id, const NotificationHeader* header)
|
||||
cmdbuf[2] = sizeof(NotificationHeader);
|
||||
cmdbuf[3] = IPC_Desc_Buffer(sizeof(NotificationHeader),IPC_BUFFER_R);
|
||||
cmdbuf[4] = (u32)header;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(newsHandle))) return ret;
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
@ -103,7 +103,7 @@ Result NEWS_GetNotificationHeader(u32 news_id, NotificationHeader* header)
|
||||
cmdbuf[2] = sizeof(NotificationHeader);
|
||||
cmdbuf[3] = IPC_Desc_Buffer(sizeof(NotificationHeader),IPC_BUFFER_W);
|
||||
cmdbuf[4] = (u32)header;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(newsHandle))) return ret;
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
@ -118,7 +118,7 @@ Result NEWS_SetNotificationMessage(u32 news_id, const u16* message, u32 size)
|
||||
cmdbuf[2] = size;
|
||||
cmdbuf[3] = IPC_Desc_Buffer((size_t)0x1780,IPC_BUFFER_R);
|
||||
cmdbuf[4] = (u32)message;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(newsHandle))) return ret;
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
@ -133,7 +133,7 @@ Result NEWS_GetNotificationMessage(u32 news_id, u16* message, u32* size)
|
||||
cmdbuf[2] = 0x1780; // Default size used by Notifications Applet
|
||||
cmdbuf[3] = IPC_Desc_Buffer((size_t)0x1780,IPC_BUFFER_W);
|
||||
cmdbuf[4] = (u32)message;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(newsHandle))) return ret;
|
||||
if(size) *size = cmdbuf[2];
|
||||
return (Result)cmdbuf[1];
|
||||
@ -149,7 +149,7 @@ Result NEWS_SetNotificationImage(u32 news_id, const void* buffer, u32 size)
|
||||
cmdbuf[2] = size;
|
||||
cmdbuf[3] = IPC_Desc_Buffer((size_t)0x10000,IPC_BUFFER_R);
|
||||
cmdbuf[4] = (u32)buffer;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(newsHandle))) return ret;
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
@ -164,7 +164,7 @@ Result NEWS_GetNotificationImage(u32 news_id, void* buffer, u32* size)
|
||||
cmdbuf[2] = 0x10000; // Default size used by Notifications Applet
|
||||
cmdbuf[3] = IPC_Desc_Buffer((size_t)0x10000,IPC_BUFFER_W);
|
||||
cmdbuf[4] = (u32)buffer;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(newsHandle))) return ret;
|
||||
if(size) *size = cmdbuf[2];
|
||||
return (Result)cmdbuf[1];
|
||||
|
@ -1,438 +1,438 @@
|
||||
#include <string.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/result.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/synchronization.h>
|
||||
#include <3ds/services/nfc.h>
|
||||
#include <3ds/services/apt.h>
|
||||
#include <3ds/ipc.h>
|
||||
|
||||
static Handle nfcHandle;
|
||||
static int nfcRefCount;
|
||||
static NFC_OpType nfc_optype = NFC_OpType_NFCTag;
|
||||
|
||||
static Result NFC_Initialize(NFC_OpType type);
|
||||
static Result NFC_Shutdown(NFC_OpType type);
|
||||
|
||||
static Result NFC_StartCommunication(void);
|
||||
static Result NFC_StopCommunication(void);
|
||||
static Result NFC_CommunicationGetStatus(u8 *out);
|
||||
static Result NFC_CommunicationGetResult(Result *out);
|
||||
|
||||
static Result NFC_StartTagScanning(u16 unknown);
|
||||
static Result NFC_StopTagScanning(void);
|
||||
|
||||
static Result NFC_InitializeWriteAppData(u32 amiibo_appid, NFC_AppDataInitStruct *initstruct, const void *buf, size_t size);
|
||||
static Result NFC_GetAppDataInitStruct(NFC_AppDataInitStruct *out);
|
||||
|
||||
Result nfcInit(NFC_OpType type)
|
||||
{
|
||||
Result ret=0;
|
||||
|
||||
if (AtomicPostIncrement(&nfcRefCount)) return 0;
|
||||
|
||||
ret = srvGetServiceHandle(&nfcHandle, "nfc:m");
|
||||
if (R_FAILED(ret))ret = srvGetServiceHandle(&nfcHandle, "nfc:u");
|
||||
if (R_SUCCEEDED(ret))
|
||||
{
|
||||
nfc_optype = type;
|
||||
ret = NFC_Initialize(type);
|
||||
if (R_FAILED(ret)) svcCloseHandle(nfcHandle);
|
||||
}
|
||||
if (R_FAILED(ret)) AtomicDecrement(&nfcRefCount);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nfcExit(void)
|
||||
{
|
||||
if (AtomicDecrement(&nfcRefCount)) return;
|
||||
NFC_Shutdown(nfc_optype);
|
||||
svcCloseHandle(nfcHandle);
|
||||
}
|
||||
|
||||
Handle nfcGetSessionHandle(void)
|
||||
{
|
||||
return nfcHandle;
|
||||
}
|
||||
|
||||
Result nfcStartScanning(u16 inval)
|
||||
{
|
||||
Result ret, ret2;
|
||||
bool new3ds_flag = false;
|
||||
u8 status;
|
||||
|
||||
APT_CheckNew3DS(&new3ds_flag);
|
||||
|
||||
if(!new3ds_flag)
|
||||
{
|
||||
ret = NFC_StartCommunication();
|
||||
if(R_FAILED(ret))return ret;
|
||||
|
||||
while(1)
|
||||
{
|
||||
status = 0;
|
||||
ret = NFC_CommunicationGetStatus(&status);
|
||||
if(R_FAILED(ret))break;
|
||||
|
||||
if(status==1)//"Attempting to initialize Old3DS NFC adapter communication."
|
||||
{
|
||||
svcSleepThread(1000000*100);
|
||||
continue;
|
||||
}
|
||||
else if(status==2)//"Old3DS NFC adapter communication initialization successfully finished."
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//An error occured with Old3DS NFC-adapter communication initialization.
|
||||
|
||||
ret = NFC_CommunicationGetResult(&ret2);
|
||||
if(R_FAILED(ret))break;
|
||||
|
||||
return ret2;
|
||||
}
|
||||
|
||||
if(R_FAILED(ret))return ret;
|
||||
}
|
||||
|
||||
return NFC_StartTagScanning(inval);
|
||||
}
|
||||
|
||||
void nfcStopScanning(void)
|
||||
{
|
||||
bool new3ds_flag = false;
|
||||
|
||||
APT_CheckNew3DS(&new3ds_flag);
|
||||
|
||||
NFC_StopTagScanning();
|
||||
|
||||
if(!new3ds_flag)
|
||||
{
|
||||
NFC_StopCommunication();
|
||||
}
|
||||
}
|
||||
|
||||
static Result NFC_Initialize(NFC_OpType type)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x1,1,0); // 0x10040
|
||||
cmdbuf[1]=type & 0xff;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_Shutdown(NFC_OpType type)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x2,1,0); // 0x20040
|
||||
cmdbuf[1]=type & 0xff;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_StartCommunication(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x3,0,0); // 0x30000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_StopCommunication(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x4,0,0); // 0x40000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_StartTagScanning(u16 unknown)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x5,1,0); // 0x50040
|
||||
cmdbuf[1]=unknown;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_StopTagScanning(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x6,0,0); // 0x60000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcLoadAmiiboData(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x7,0,0); // 0x70000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcResetTagScanState(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x8,0,0); // 0x80000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcUpdateStoredAmiiboData(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x9,0,2); // 0x90002
|
||||
cmdbuf[1]=IPC_Desc_CurProcessHandle();
|
||||
|
||||
if(R_FAILED(ret=svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcGetTagState(NFC_TagState *state)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0xD,0,0); // 0xD0000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && state)*state = cmdbuf[2] & 0xff;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_CommunicationGetStatus(u8 *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0xF,0,0); // 0xF0000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)*out = cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcGetTagInfo(NFC_TagInfo *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x11,0,0); // 0x110000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)memcpy(out, &cmdbuf[2], sizeof(NFC_TagInfo));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_CommunicationGetResult(Result *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x12,0,0); // 0x120000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)*out = cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcOpenAppData(u32 amiibo_appid)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x13,1,0); // 0x130040
|
||||
cmdbuf[1]=amiibo_appid;
|
||||
|
||||
if(R_FAILED(ret=svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcInitializeWriteAppData(u32 amiibo_appid, const void *buf, size_t size)
|
||||
{
|
||||
Result ret=0;
|
||||
NFC_AppDataInitStruct initstruct;
|
||||
|
||||
ret = NFC_GetAppDataInitStruct(&initstruct);
|
||||
if(R_FAILED(ret))return ret;
|
||||
|
||||
return NFC_InitializeWriteAppData(amiibo_appid, &initstruct, buf, size);
|
||||
}
|
||||
|
||||
static Result NFC_InitializeWriteAppData(u32 amiibo_appid, NFC_AppDataInitStruct *initstruct, const void *buf, size_t size)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x14,14,4); // 0x140384
|
||||
cmdbuf[1]=amiibo_appid;
|
||||
cmdbuf[2]=size;
|
||||
memcpy(&cmdbuf[3], initstruct->data_xc, sizeof(initstruct->data_xc));
|
||||
cmdbuf[15]=IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[17]=IPC_Desc_StaticBuffer(size, 0);
|
||||
cmdbuf[18]=(u32)buf;
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(nfcHandle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result nfcReadAppData(void *buf, size_t size)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x15,1,0); // 0x150040
|
||||
cmdbuf[1]=size;
|
||||
|
||||
u32 * staticbufs = getThreadStaticBuffers();
|
||||
saved_threadstorage[0] = staticbufs[0];
|
||||
saved_threadstorage[1] = staticbufs[1];
|
||||
|
||||
staticbufs[0] = IPC_Desc_StaticBuffer(size,0);
|
||||
staticbufs[1] = (u32)buf;
|
||||
|
||||
Result ret=0;
|
||||
ret=svcSendSyncRequest(nfcHandle);
|
||||
|
||||
staticbufs[0] = saved_threadstorage[0];
|
||||
staticbufs[1] = saved_threadstorage[1];
|
||||
|
||||
if(R_FAILED(ret))return ret;
|
||||
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcWriteAppData(const void *buf, size_t size, NFC_TagInfo *taginfo)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
NFC_AppDataWriteStruct writestruct;
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x16,9,2); // 0x160242
|
||||
cmdbuf[1]=size;
|
||||
cmdbuf[10]=IPC_Desc_StaticBuffer(size, 0);
|
||||
cmdbuf[11]=(u32)buf;
|
||||
|
||||
if(taginfo==NULL)return -1;
|
||||
if(taginfo->id_offset_size>10)return -2;
|
||||
|
||||
memset(&writestruct, 0, sizeof(NFC_AppDataWriteStruct));
|
||||
writestruct.id_size = taginfo->id_offset_size;
|
||||
memcpy(writestruct.id, taginfo->id, sizeof(writestruct.id));
|
||||
|
||||
memcpy(&cmdbuf[2], &writestruct, sizeof(NFC_AppDataWriteStruct));
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(nfcHandle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result nfcGetAmiiboSettings(NFC_AmiiboSettings *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x17,0,0); // 0x170000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)memcpy(out, &cmdbuf[2], sizeof(NFC_AmiiboSettings));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcGetAmiiboConfig(NFC_AmiiboConfig *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x18,0,0); // 0x180000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)memcpy(out, &cmdbuf[2], sizeof(NFC_AmiiboConfig));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_GetAppDataInitStruct(NFC_AppDataInitStruct *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x19,0,0); // 0x190000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)memcpy(out, &cmdbuf[2], sizeof(NFC_AppDataInitStruct));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/result.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/synchronization.h>
|
||||
#include <3ds/services/nfc.h>
|
||||
#include <3ds/services/apt.h>
|
||||
#include <3ds/ipc.h>
|
||||
|
||||
static Handle nfcHandle;
|
||||
static int nfcRefCount;
|
||||
static NFC_OpType nfc_optype = NFC_OpType_NFCTag;
|
||||
|
||||
static Result NFC_Initialize(NFC_OpType type);
|
||||
static Result NFC_Shutdown(NFC_OpType type);
|
||||
|
||||
static Result NFC_StartCommunication(void);
|
||||
static Result NFC_StopCommunication(void);
|
||||
static Result NFC_CommunicationGetStatus(u8 *out);
|
||||
static Result NFC_CommunicationGetResult(Result *out);
|
||||
|
||||
static Result NFC_StartTagScanning(u16 unknown);
|
||||
static Result NFC_StopTagScanning(void);
|
||||
|
||||
static Result NFC_InitializeWriteAppData(u32 amiibo_appid, NFC_AppDataInitStruct *initstruct, const void *buf, size_t size);
|
||||
static Result NFC_GetAppDataInitStruct(NFC_AppDataInitStruct *out);
|
||||
|
||||
Result nfcInit(NFC_OpType type)
|
||||
{
|
||||
Result ret=0;
|
||||
|
||||
if (AtomicPostIncrement(&nfcRefCount)) return 0;
|
||||
|
||||
ret = srvGetServiceHandle(&nfcHandle, "nfc:m");
|
||||
if (R_FAILED(ret))ret = srvGetServiceHandle(&nfcHandle, "nfc:u");
|
||||
if (R_SUCCEEDED(ret))
|
||||
{
|
||||
nfc_optype = type;
|
||||
ret = NFC_Initialize(type);
|
||||
if (R_FAILED(ret)) svcCloseHandle(nfcHandle);
|
||||
}
|
||||
if (R_FAILED(ret)) AtomicDecrement(&nfcRefCount);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nfcExit(void)
|
||||
{
|
||||
if (AtomicDecrement(&nfcRefCount)) return;
|
||||
NFC_Shutdown(nfc_optype);
|
||||
svcCloseHandle(nfcHandle);
|
||||
}
|
||||
|
||||
Handle nfcGetSessionHandle(void)
|
||||
{
|
||||
return nfcHandle;
|
||||
}
|
||||
|
||||
Result nfcStartScanning(u16 inval)
|
||||
{
|
||||
Result ret, ret2;
|
||||
bool new3ds_flag = false;
|
||||
u8 status;
|
||||
|
||||
APT_CheckNew3DS(&new3ds_flag);
|
||||
|
||||
if(!new3ds_flag)
|
||||
{
|
||||
ret = NFC_StartCommunication();
|
||||
if(R_FAILED(ret))return ret;
|
||||
|
||||
while(1)
|
||||
{
|
||||
status = 0;
|
||||
ret = NFC_CommunicationGetStatus(&status);
|
||||
if(R_FAILED(ret))break;
|
||||
|
||||
if(status==1)//"Attempting to initialize Old3DS NFC adapter communication."
|
||||
{
|
||||
svcSleepThread(1000000*100);
|
||||
continue;
|
||||
}
|
||||
else if(status==2)//"Old3DS NFC adapter communication initialization successfully finished."
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//An error occured with Old3DS NFC-adapter communication initialization.
|
||||
|
||||
ret = NFC_CommunicationGetResult(&ret2);
|
||||
if(R_FAILED(ret))break;
|
||||
|
||||
return ret2;
|
||||
}
|
||||
|
||||
if(R_FAILED(ret))return ret;
|
||||
}
|
||||
|
||||
return NFC_StartTagScanning(inval);
|
||||
}
|
||||
|
||||
void nfcStopScanning(void)
|
||||
{
|
||||
bool new3ds_flag = false;
|
||||
|
||||
APT_CheckNew3DS(&new3ds_flag);
|
||||
|
||||
NFC_StopTagScanning();
|
||||
|
||||
if(!new3ds_flag)
|
||||
{
|
||||
NFC_StopCommunication();
|
||||
}
|
||||
}
|
||||
|
||||
static Result NFC_Initialize(NFC_OpType type)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x1,1,0); // 0x10040
|
||||
cmdbuf[1]=type & 0xff;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_Shutdown(NFC_OpType type)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x2,1,0); // 0x20040
|
||||
cmdbuf[1]=type & 0xff;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_StartCommunication(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x3,0,0); // 0x30000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_StopCommunication(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x4,0,0); // 0x40000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_StartTagScanning(u16 unknown)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x5,1,0); // 0x50040
|
||||
cmdbuf[1]=unknown;
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_StopTagScanning(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x6,0,0); // 0x60000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcLoadAmiiboData(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x7,0,0); // 0x70000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcResetTagScanState(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x8,0,0); // 0x80000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcUpdateStoredAmiiboData(void)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x9,0,2); // 0x90002
|
||||
cmdbuf[1]=IPC_Desc_CurProcessHandle();
|
||||
|
||||
if(R_FAILED(ret=svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcGetTagState(NFC_TagState *state)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0xD,0,0); // 0xD0000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && state)*state = cmdbuf[2] & 0xff;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_CommunicationGetStatus(u8 *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0xF,0,0); // 0xF0000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)*out = cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcGetTagInfo(NFC_TagInfo *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x11,0,0); // 0x110000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)memcpy(out, &cmdbuf[2], sizeof(NFC_TagInfo));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_CommunicationGetResult(Result *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x12,0,0); // 0x120000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)*out = cmdbuf[2];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcOpenAppData(u32 amiibo_appid)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x13,1,0); // 0x130040
|
||||
cmdbuf[1]=amiibo_appid;
|
||||
|
||||
if(R_FAILED(ret=svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcInitializeWriteAppData(u32 amiibo_appid, const void *buf, size_t size)
|
||||
{
|
||||
Result ret=0;
|
||||
NFC_AppDataInitStruct initstruct;
|
||||
|
||||
ret = NFC_GetAppDataInitStruct(&initstruct);
|
||||
if(R_FAILED(ret))return ret;
|
||||
|
||||
return NFC_InitializeWriteAppData(amiibo_appid, &initstruct, buf, size);
|
||||
}
|
||||
|
||||
static Result NFC_InitializeWriteAppData(u32 amiibo_appid, NFC_AppDataInitStruct *initstruct, const void *buf, size_t size)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x14,14,4); // 0x140384
|
||||
cmdbuf[1]=amiibo_appid;
|
||||
cmdbuf[2]=size;
|
||||
memcpy(&cmdbuf[3], initstruct->data_xc, sizeof(initstruct->data_xc));
|
||||
cmdbuf[15]=IPC_Desc_CurProcessHandle();
|
||||
cmdbuf[17]=IPC_Desc_StaticBuffer(size, 0);
|
||||
cmdbuf[18]=(u32)buf;
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(nfcHandle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result nfcReadAppData(void *buf, size_t size)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
u32 saved_threadstorage[2];
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x15,1,0); // 0x150040
|
||||
cmdbuf[1]=size;
|
||||
|
||||
u32 * staticbufs = getThreadStaticBuffers();
|
||||
saved_threadstorage[0] = staticbufs[0];
|
||||
saved_threadstorage[1] = staticbufs[1];
|
||||
|
||||
staticbufs[0] = IPC_Desc_StaticBuffer(size,0);
|
||||
staticbufs[1] = (u32)buf;
|
||||
|
||||
Result ret=0;
|
||||
ret=svcSendSyncRequest(nfcHandle);
|
||||
|
||||
staticbufs[0] = saved_threadstorage[0];
|
||||
staticbufs[1] = saved_threadstorage[1];
|
||||
|
||||
if(R_FAILED(ret))return ret;
|
||||
|
||||
ret = cmdbuf[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcWriteAppData(const void *buf, size_t size, NFC_TagInfo *taginfo)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
NFC_AppDataWriteStruct writestruct;
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x16,9,2); // 0x160242
|
||||
cmdbuf[1]=size;
|
||||
cmdbuf[10]=IPC_Desc_StaticBuffer(size, 0);
|
||||
cmdbuf[11]=(u32)buf;
|
||||
|
||||
if(taginfo==NULL)return -1;
|
||||
if(taginfo->id_offset_size>10)return -2;
|
||||
|
||||
memset(&writestruct, 0, sizeof(NFC_AppDataWriteStruct));
|
||||
writestruct.id_size = taginfo->id_offset_size;
|
||||
memcpy(writestruct.id, taginfo->id, sizeof(writestruct.id));
|
||||
|
||||
memcpy(&cmdbuf[2], &writestruct, sizeof(NFC_AppDataWriteStruct));
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(nfcHandle)))return ret;
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result nfcGetAmiiboSettings(NFC_AmiiboSettings *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x17,0,0); // 0x170000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)memcpy(out, &cmdbuf[2], sizeof(NFC_AmiiboSettings));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Result nfcGetAmiiboConfig(NFC_AmiiboConfig *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x18,0,0); // 0x180000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)memcpy(out, &cmdbuf[2], sizeof(NFC_AmiiboConfig));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Result NFC_GetAppDataInitStruct(NFC_AppDataInitStruct *out)
|
||||
{
|
||||
Result ret=0;
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x19,0,0); // 0x190000
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nfcHandle)))return ret;
|
||||
ret = cmdbuf[1];
|
||||
|
||||
if(R_SUCCEEDED(ret) && out)memcpy(out, &cmdbuf[2], sizeof(NFC_AppDataInitStruct));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,9 @@ Result NS_LaunchFIRM(u64 titleid)
|
||||
cmdbuf[0] = IPC_MakeHeader(0x1,3,0); // 0x100C0
|
||||
cmdbuf[1] = titleid & 0xffffffff;
|
||||
cmdbuf[2] = (titleid >> 32) & 0xffffffff;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nsHandle)))return ret;
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -48,11 +48,11 @@ Result NS_LaunchTitle(u64 titleid, u32 launch_flags, u32 *procid)
|
||||
cmdbuf[1] = titleid & 0xffffffff;
|
||||
cmdbuf[2] = (titleid >> 32) & 0xffffffff;
|
||||
cmdbuf[3] = launch_flags;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nsHandle)))return ret;
|
||||
|
||||
if(procid != NULL) *procid = cmdbuf[2];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -65,9 +65,9 @@ Result NS_LaunchApplicationFIRM(u64 titleid, u32 flags)
|
||||
cmdbuf[1] = titleid & 0xffffffff;
|
||||
cmdbuf[2] = (titleid >> 32) & 0xffffffff;
|
||||
cmdbuf[3] = flags;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nsHandle)))return ret;
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ Result NS_RebootToTitle(u8 mediatype, u64 titleid)
|
||||
cmdbuf[4] = mediatype;
|
||||
cmdbuf[5] = 0x0; // reserved
|
||||
cmdbuf[6] = 0x0;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(nsHandle)))return ret;
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
|
@ -37,9 +37,9 @@ Result PM_LaunchTitle(u8 mediatype, u64 titleid, u32 launch_flags)
|
||||
cmdbuf[3] = mediatype;
|
||||
cmdbuf[4] = 0x0;
|
||||
cmdbuf[5] = launch_flags;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -53,11 +53,11 @@ Result PM_GetTitleExheaderFlags(u8 mediatype, u64 titleid, u8* out)
|
||||
cmdbuf[2] = (titleid >> 32) & 0xffffffff;
|
||||
cmdbuf[3] = mediatype;
|
||||
cmdbuf[4] = 0x0;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
|
||||
memcpy(out, (u8*)(&cmdbuf[2]), 8);
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -70,9 +70,9 @@ Result PM_SetFIRMLaunchParams(u32 size, u8* in)
|
||||
cmdbuf[1] = size;
|
||||
cmdbuf[2] = IPC_Desc_Buffer(size,IPC_BUFFER_R);
|
||||
cmdbuf[3] = (u32)in;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -85,9 +85,9 @@ Result PM_GetFIRMLaunchParams(u32 size, u8* out)
|
||||
cmdbuf[1] = size;
|
||||
cmdbuf[2] = IPC_Desc_Buffer(size,IPC_BUFFER_W);
|
||||
cmdbuf[3] = (u32)out;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -101,8 +101,8 @@ Result PM_LaunchFIRMSetParams(u32 firm_titleid_low, u32 size, u8* in)
|
||||
cmdbuf[2] = size;
|
||||
cmdbuf[3] = IPC_Desc_Buffer(size,IPC_BUFFER_R);
|
||||
cmdbuf[4] = (u32)in;
|
||||
|
||||
|
||||
if(R_FAILED(ret = svcSendSyncRequest(pmHandle)))return ret;
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
@ -50,10 +50,10 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
staticbufs[1] = (u32)tmpaddr;
|
||||
|
||||
ret = svcSendSyncRequest(SOCU_handle);
|
||||
|
||||
|
||||
staticbufs[0] = saved_threadstorage[0];
|
||||
staticbufs[1] = saved_threadstorage[1];
|
||||
|
||||
|
||||
if(ret != 0) {
|
||||
__release_handle(fd);
|
||||
errno = SYNC_ERROR;
|
||||
|
@ -140,7 +140,7 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi
|
||||
Result ret;
|
||||
addrinfo_3ds_t *info = NULL, *tmp;
|
||||
s32 count = DEFAULT_NUM_ADDRINFO, info_count;
|
||||
|
||||
|
||||
if(node == NULL && service == NULL)
|
||||
{
|
||||
return EAI_NONAME;
|
||||
|
@ -57,7 +57,7 @@ int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_
|
||||
if(R_FAILED(ret)) {
|
||||
errno = SYNC_ERROR;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = cmdbuf[1];
|
||||
if(R_FAILED(ret)) {
|
||||
|
@ -38,9 +38,9 @@ int SOCU_GetNetworkOpt(int level, NetworkOpt optname, void * optval, socklen_t *
|
||||
{
|
||||
errno = SYNC_ERROR;
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
ret = _net_convert_error(cmdbuf[2]);
|
||||
|
||||
if(ret < 0) {
|
||||
|
@ -29,10 +29,10 @@ int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
staticbufs[1] = (u32)tmpaddr;
|
||||
|
||||
ret = svcSendSyncRequest(SOCU_handle);
|
||||
|
||||
|
||||
staticbufs[0] = saved_threadstorage[0];
|
||||
staticbufs[1] = saved_threadstorage[1];
|
||||
|
||||
|
||||
if(ret != 0) {
|
||||
errno = SYNC_ERROR;
|
||||
return ret;
|
||||
|
@ -30,10 +30,10 @@ int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optl
|
||||
staticbufs[1] = (u32)optval;
|
||||
|
||||
ret = svcSendSyncRequest(SOCU_handle);
|
||||
|
||||
|
||||
staticbufs[0] = saved_threadstorage[0];
|
||||
staticbufs[1] = saved_threadstorage[1];
|
||||
|
||||
|
||||
if(ret != 0) {
|
||||
errno = SYNC_ERROR;
|
||||
return ret;
|
||||
|
@ -122,7 +122,7 @@ Result socExit(void)
|
||||
{
|
||||
Result ret = 0;
|
||||
int dev;
|
||||
|
||||
|
||||
svcCloseHandle(socMemhandle);
|
||||
socMemhandle = 0;
|
||||
|
||||
@ -154,7 +154,7 @@ soc_close(struct _reent *r,
|
||||
int fd)
|
||||
{
|
||||
Handle sockfd = *(Handle*)fd;
|
||||
|
||||
|
||||
int ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
@ -29,7 +29,7 @@ int ioctl(int sockfd, int request, ...)
|
||||
}
|
||||
|
||||
flags = fcntl(sockfd, F_GETFL, 0);
|
||||
if(flags == -1)
|
||||
if(flags == -1)
|
||||
return -1;
|
||||
|
||||
if(*value)
|
||||
|
@ -51,10 +51,10 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
staticbufs[1] = (u32)tmp_fds;
|
||||
|
||||
ret = svcSendSyncRequest(SOCU_handle);
|
||||
|
||||
|
||||
staticbufs[0] = saved_threadstorage[0];
|
||||
staticbufs[1] = saved_threadstorage[1];
|
||||
|
||||
|
||||
if(ret != 0) {
|
||||
free(tmp_fds);
|
||||
errno = SYNC_ERROR;
|
||||
|
@ -33,10 +33,10 @@ ssize_t socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struct sockad
|
||||
staticbufs[1] = (u32)tmpaddr;
|
||||
|
||||
ret = svcSendSyncRequest(SOCU_handle);
|
||||
|
||||
|
||||
staticbufs[0] = saved_threadstorage[0];
|
||||
staticbufs[1] = saved_threadstorage[1];
|
||||
|
||||
|
||||
if(ret != 0) {
|
||||
errno = SYNC_ERROR;
|
||||
return -1;
|
||||
@ -64,7 +64,7 @@ ssize_t socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struct sockad
|
||||
ssize_t socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
u32 tmp_addrlen = 0;
|
||||
u8 tmpaddr[0x1c];
|
||||
u32 saved_threadstorage[4];
|
||||
@ -85,7 +85,7 @@ ssize_t socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockad
|
||||
saved_threadstorage[1] = cmdbuf[0x104>>2];
|
||||
saved_threadstorage[2] = cmdbuf[0x108>>2];
|
||||
saved_threadstorage[3] = cmdbuf[0x10c>>2];
|
||||
|
||||
|
||||
cmdbuf[0x100>>2] = (((u32)len)<<14) | 2;
|
||||
cmdbuf[0x104>>2] = (u32)buf;
|
||||
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
|
||||
|
@ -45,7 +45,7 @@ static Result sslcipc_Initialize(void)
|
||||
|
||||
cmdbuf[0]=IPC_MakeHeader(0x1,0,2); // 0x10002
|
||||
cmdbuf[1]=IPC_Desc_CurProcessHandle();
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(__sslc_servhandle)))return ret;
|
||||
|
||||
@ -235,7 +235,7 @@ static Result sslcipc_InitializeConnectionSession(sslcContext *context)
|
||||
cmdbuf[0]=IPC_MakeHeader(0x12,1,2); // 0x120042
|
||||
cmdbuf[1]=context->sslchandle;
|
||||
cmdbuf[2]=IPC_Desc_CurProcessHandle();
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
@ -371,7 +371,7 @@ static Result sslcipc_ContextInitSharedmem(sslcContext *context, u32 size)
|
||||
cmdbuf[2]=size;
|
||||
cmdbuf[3]=IPC_Desc_SharedHandles(1);
|
||||
cmdbuf[4]=context->sharedmem_handle;
|
||||
|
||||
|
||||
Result ret=0;
|
||||
if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret;
|
||||
|
||||
|
@ -69,11 +69,11 @@ SVC_BEGIN svcGetThreadPriority
|
||||
ldr r3, [sp], #4
|
||||
str r1, [r3]
|
||||
bx lr
|
||||
|
||||
|
||||
SVC_BEGIN svcSetThreadPriority
|
||||
svc 0x0C
|
||||
bx lr
|
||||
|
||||
|
||||
SVC_BEGIN svcGetThreadAffinityMask
|
||||
svc 0x0D
|
||||
bx lr
|
||||
@ -81,14 +81,14 @@ SVC_BEGIN svcGetThreadAffinityMask
|
||||
SVC_BEGIN svcSetThreadAffinityMask
|
||||
svc 0x0E
|
||||
bx lr
|
||||
|
||||
|
||||
SVC_BEGIN svcGetThreadIdealProcessor
|
||||
str r0, [sp, #-0x4]!
|
||||
svc 0x0F
|
||||
ldr r3, [sp], #4
|
||||
str r1, [r3]
|
||||
bx lr
|
||||
|
||||
|
||||
SVC_BEGIN svcSetThreadIdealProcessor
|
||||
svc 0x10
|
||||
bx lr
|
||||
@ -281,7 +281,7 @@ SVC_BEGIN svcOpenThread
|
||||
pop {r2}
|
||||
str r1, [r2]
|
||||
bx lr
|
||||
|
||||
|
||||
SVC_BEGIN svcGetProcessId
|
||||
str r0, [sp, #-0x4]!
|
||||
svc 0x35
|
||||
@ -295,7 +295,7 @@ SVC_BEGIN svcGetProcessIdOfThread
|
||||
ldr r3, [sp], #4
|
||||
str r1, [r3]
|
||||
bx lr
|
||||
|
||||
|
||||
SVC_BEGIN svcGetThreadId
|
||||
str r0, [sp, #-0x4]!
|
||||
svc 0x37
|
||||
@ -407,7 +407,7 @@ SVC_BEGIN svcTerminateDebugProcess
|
||||
SVC_BEGIN svcGetProcessDebugEvent
|
||||
svc 0x63
|
||||
bx lr
|
||||
|
||||
|
||||
SVC_BEGIN svcContinueDebugEvent
|
||||
svc 0x64
|
||||
bx lr
|
||||
|
@ -25,6 +25,6 @@ rbtree_find(const rbtree_t *tree,
|
||||
tmp = tmp->child[LEFT];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return save;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user