Merge branch 'master' of github.com:smealum/ctrulib
This commit is contained in:
commit
f934dc0982
BIN
libctru/data/default_font.bin
Normal file
BIN
libctru/data/default_font.bin
Normal file
Binary file not shown.
@ -9,8 +9,10 @@ extern "C" {
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/linear.h>
|
||||
#include <3ds/vram.h>
|
||||
#include <3ds/os.h>
|
||||
#include <3ds/gfx.h>
|
||||
#include <3ds/console.h>
|
||||
|
||||
#include <3ds/services/ac.h>
|
||||
#include <3ds/services/apt.h>
|
||||
|
159
libctru/include/3ds/console.h
Normal file
159
libctru/include/3ds/console.h
Normal file
@ -0,0 +1,159 @@
|
||||
|
||||
|
||||
/*! \file console.h
|
||||
\brief 3ds stdio support.
|
||||
|
||||
<div class="fileHeader">
|
||||
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:
|
||||
consoleDemoInit()
|
||||
or to customize the console usage by:
|
||||
consoleInit()
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
#include <3ds/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef bool(* ConsolePrint)(void* con, char 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();
|
||||
<div class="fixedFont"><pre>
|
||||
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
|
||||
};
|
||||
</pre></div>
|
||||
*/
|
||||
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)
|
||||
#define CONSOLE_COLOR_FAINT (1<<1)
|
||||
#define CONSOLE_ITALIC (1<<2)
|
||||
#define CONSOLE_UNDERLINE (1<<3)
|
||||
#define CONSOLE_BLINK_SLOW (1<<4)
|
||||
#define CONSOLE_BLINK_FAST (1<<5)
|
||||
#define CONSOLE_COLOR_REVERSE (1<<6)
|
||||
#define CONSOLE_CONCEAL (1<<7)
|
||||
#define CONSOLE_CROSSED_OUT (1<<8)
|
||||
|
||||
//! 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, other wise 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 initialze (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
|
||||
|
||||
#endif
|
@ -2,6 +2,9 @@
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/services/gsp.h>
|
||||
|
||||
#define RGB565(r,g,b) (((b)&0x1f)|(((g)&0x3f)<<5)|(((r)&0x1f)<<11))
|
||||
#define RGB8_to_565(r,g,b) (((b)>>3)&0x1f)|((((g)>>2)&0x3f)<<5)|((((r)>>3)&0x1f)<<11)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GFX_TOP = 0,
|
||||
@ -22,7 +25,7 @@ void gfxExit();
|
||||
//control stuff
|
||||
void gfxSet3D(bool enable);
|
||||
void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format);
|
||||
void gfxSetDoubleBuffering(bool doubleBuffering);
|
||||
void gfxSetDoubleBuffering(gfxScreen_t screen, bool doubleBuffering);
|
||||
void gfxFlushBuffers();
|
||||
void gfxSwapBuffers();
|
||||
void gfxSwapBuffersGpu();
|
||||
|
@ -102,4 +102,5 @@ Result HIDUSER_EnableAccelerometer();
|
||||
Result HIDUSER_DisableAccelerometer();
|
||||
Result HIDUSER_EnableGyroscope();
|
||||
Result HIDUSER_DisableGyroscope();
|
||||
|
||||
Result HIDUSER_GetGyroscopeRawToDpsCoefficient(float *coeff);
|
||||
Result HIDUSER_GetSoundVolume(u8 *volume); //Return the volume slider value (0-63)
|
||||
|
@ -14,7 +14,7 @@ About: Launches a title
|
||||
titleid TitleId of title to launch
|
||||
launch_flags use if you know of any
|
||||
*/
|
||||
Result PM_LaunchTitle(u8 mediatype, u64 titleid);
|
||||
Result PM_LaunchTitle(u8 mediatype, u64 titleid, u32 launch_flags);
|
||||
|
||||
/* PM_GetTitleExheaderFlags()
|
||||
About: Writes to a buffer the launch flags (8 bytes) from a title exheader.
|
||||
@ -28,7 +28,7 @@ Result PM_GetTitleExheaderFlags(u8 mediatype, u64 titleid, u8* out);
|
||||
/* PM_SetFIRMLaunchParams()
|
||||
About: Sets the FIRM launch params from in
|
||||
|
||||
size size of FIRM launch params
|
||||
size size of FIRM launch params
|
||||
in ptr to location of FIRM launch params
|
||||
*/
|
||||
Result PM_SetFIRMLaunchParams(u32 size, u8* in);
|
||||
@ -36,7 +36,7 @@ Result PM_SetFIRMLaunchParams(u32 size, u8* in);
|
||||
/* PM_GetFIRMLaunchParams()
|
||||
About: Sets the FIRM launch params from in
|
||||
|
||||
size size of buffer to store FIRM launch params
|
||||
size size of buffer to store FIRM launch params
|
||||
out ptr to location to write FIRM launch params
|
||||
*/
|
||||
Result PM_GetFIRMLaunchParams(u32 size, u8* out);
|
||||
@ -45,7 +45,7 @@ Result PM_GetFIRMLaunchParams(u32 size, u8* out);
|
||||
About: Same as PM_SetFIRMLaunchParams(), but also triggers a FIRM launch
|
||||
|
||||
firm_titleid_low TitleID low of firm title to launch
|
||||
size size of FIRM launch params
|
||||
size size of FIRM launch params
|
||||
in ptr to location of FIRM launch params
|
||||
*/
|
||||
Result PM_LaunchFIRMSetParams(u64 firm_titleid_low, u32 size, u8* in);
|
||||
Result PM_LaunchFIRMSetParams(u32 firm_titleid_low, u32 size, u8* in);
|
||||
|
@ -16,10 +16,11 @@ typedef enum {
|
||||
} MemOp;
|
||||
|
||||
typedef enum {
|
||||
MEMPERM_READ =1,
|
||||
MEMPERM_WRITE =2,
|
||||
MEMPERM_EXECUTE=4,
|
||||
MEMPERM_MAX =0xFFFFFFFF //force 4-byte
|
||||
MEMPERM_READ = 1,
|
||||
MEMPERM_WRITE = 2,
|
||||
MEMPERM_EXECUTE = 4,
|
||||
MEMPERM_DONTCARE = 0x10000000,
|
||||
MEMPERM_MAX = 0xFFFFFFFF //force 4-byte
|
||||
} MemPerm;
|
||||
|
||||
typedef struct {
|
||||
|
8
libctru/include/3ds/vram.h
Normal file
8
libctru/include/3ds/vram.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// Functions for allocating/deallocating VRAM
|
||||
void* vramAlloc(size_t size); // returns a 16-byte aligned address
|
||||
void* vramMemAlign(size_t size, size_t alignment);
|
||||
void* vramRealloc(void* mem, size_t size); // not implemented yet
|
||||
void vramFree(void* mem);
|
||||
u32 vramSpaceFree(); // get free VRAM space in bytes
|
48
libctru/source/allocator/addrmap.h
Normal file
48
libctru/source/allocator/addrmap.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
static rbtree_t sAddrMap;
|
||||
|
||||
struct addrMapNode
|
||||
{
|
||||
rbtree_node node;
|
||||
MemChunk chunk;
|
||||
};
|
||||
|
||||
#define getAddrMapNode(x) rbtree_item((x), addrMapNode, node)
|
||||
|
||||
static int addrMapNodeComparator(const rbtree_node_t* _lhs, const rbtree_node_t* _rhs)
|
||||
{
|
||||
auto lhs = getAddrMapNode(_lhs)->chunk.addr;
|
||||
auto rhs = getAddrMapNode(_rhs)->chunk.addr;
|
||||
if (lhs < rhs)
|
||||
return -1;
|
||||
if (lhs > rhs)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void addrMapNodeDestructor(rbtree_node_t* a)
|
||||
{
|
||||
free(getAddrMapNode(a));
|
||||
}
|
||||
|
||||
static addrMapNode* getNode(void* addr)
|
||||
{
|
||||
addrMapNode n;
|
||||
n.chunk.addr = (u8*)addr;
|
||||
auto p = rbtree_find(&sAddrMap, &n.node);
|
||||
return p ? getAddrMapNode(p) : nullptr;
|
||||
}
|
||||
|
||||
static addrMapNode* newNode(const MemChunk& chunk)
|
||||
{
|
||||
auto p = (addrMapNode*)malloc(sizeof(addrMapNode));
|
||||
if (!p) return nullptr;
|
||||
p->chunk = chunk;
|
||||
return p;
|
||||
}
|
||||
|
||||
static void delNode(addrMapNode* node)
|
||||
{
|
||||
rbtree_remove(&sAddrMap, &node->node, addrMapNodeDestructor);
|
||||
}
|
@ -1,57 +1,16 @@
|
||||
#include <3ds.h>
|
||||
#include <3ds/util/rbtree.h>
|
||||
extern "C"
|
||||
{
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/linear.h>
|
||||
#include <3ds/util/rbtree.h>
|
||||
}
|
||||
|
||||
#include "mem_pool.h"
|
||||
#include "addrmap.h"
|
||||
|
||||
extern u32 __linear_heap, __linear_heap_size;
|
||||
|
||||
static MemPool sLinearPool;
|
||||
static rbtree_t sAddrMap;
|
||||
|
||||
struct addrMapNode
|
||||
{
|
||||
rbtree_node node;
|
||||
MemChunk chunk;
|
||||
};
|
||||
|
||||
#define getAddrMapNode(x) rbtree_item((x), addrMapNode, node)
|
||||
|
||||
static int addrMapNodeComparator(const rbtree_node_t* _lhs, const rbtree_node_t* _rhs)
|
||||
{
|
||||
auto lhs = getAddrMapNode(_lhs)->chunk.addr;
|
||||
auto rhs = getAddrMapNode(_rhs)->chunk.addr;
|
||||
if (lhs < rhs)
|
||||
return -1;
|
||||
if (lhs > rhs)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void addrMapNodeDestructor(rbtree_node_t* a)
|
||||
{
|
||||
free(getAddrMapNode(a));
|
||||
}
|
||||
|
||||
static addrMapNode* getNode(void* addr)
|
||||
{
|
||||
addrMapNode n;
|
||||
n.chunk.addr = (u8*)addr;
|
||||
auto p = rbtree_find(&sAddrMap, &n.node);
|
||||
return p ? getAddrMapNode(p) : nullptr;
|
||||
}
|
||||
|
||||
static addrMapNode* newNode(const MemChunk& chunk)
|
||||
{
|
||||
auto p = (addrMapNode*)malloc(sizeof(addrMapNode));
|
||||
if (!p) return nullptr;
|
||||
p->chunk = chunk;
|
||||
return p;
|
||||
}
|
||||
|
||||
static void delNode(addrMapNode* node)
|
||||
{
|
||||
rbtree_remove(&sAddrMap, &node->node, addrMapNodeDestructor);
|
||||
}
|
||||
|
||||
static bool linearInit()
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct MemChunk
|
||||
|
86
libctru/source/allocator/vram.cpp
Normal file
86
libctru/source/allocator/vram.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
extern "C"
|
||||
{
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/vram.h>
|
||||
#include <3ds/util/rbtree.h>
|
||||
}
|
||||
|
||||
#include "mem_pool.h"
|
||||
#include "addrmap.h"
|
||||
|
||||
static MemPool sVramPool;
|
||||
|
||||
static bool vramInit()
|
||||
{
|
||||
auto blk = MemBlock::Create((u8*)0x1F000000, 0x00600000);
|
||||
if (blk)
|
||||
{
|
||||
sVramPool.AddBlock(blk);
|
||||
rbtree_init(&sAddrMap, addrMapNodeComparator);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void* vramMemAlign(size_t size, size_t alignment)
|
||||
{
|
||||
// Enforce minimum alignment
|
||||
if (alignment < 16)
|
||||
alignment = 16;
|
||||
|
||||
// Convert alignment to shift amount
|
||||
int shift;
|
||||
for (shift = 4; shift < 32; shift ++)
|
||||
{
|
||||
if ((1U<<shift) == alignment)
|
||||
break;
|
||||
}
|
||||
if (shift == 32) // Invalid alignment
|
||||
return nullptr;
|
||||
|
||||
// Initialize the pool if it is not ready
|
||||
if (!sVramPool.Ready() && !vramInit())
|
||||
return nullptr;
|
||||
|
||||
// Allocate the chunk
|
||||
MemChunk chunk;
|
||||
if (!sVramPool.Allocate(chunk, size, shift))
|
||||
return nullptr;
|
||||
|
||||
auto node = newNode(chunk);
|
||||
if (!node)
|
||||
{
|
||||
sVramPool.Deallocate(chunk);
|
||||
return nullptr;
|
||||
}
|
||||
if (rbtree_insert(&sAddrMap, &node->node));
|
||||
return chunk.addr;
|
||||
}
|
||||
|
||||
void* vramAlloc(size_t size)
|
||||
{
|
||||
return vramMemAlign(size, 16);
|
||||
}
|
||||
|
||||
void* vramRealloc(void* mem, size_t size)
|
||||
{
|
||||
// TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vramFree(void* mem)
|
||||
{
|
||||
auto node = getNode(mem);
|
||||
if (!node) return;
|
||||
|
||||
// Free the chunk
|
||||
sVramPool.Deallocate(node->chunk);
|
||||
|
||||
// Free the node
|
||||
delNode(node);
|
||||
}
|
||||
|
||||
u32 vramSpaceFree()
|
||||
{
|
||||
return sVramPool.GetFreeSpace();
|
||||
}
|
751
libctru/source/console.c
Normal file
751
libctru/source/console.c
Normal file
@ -0,0 +1,751 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <3ds/gfx.h>
|
||||
#include <3ds/console.h>
|
||||
#include <3ds/svc.h>
|
||||
|
||||
#include "default_font_bin.h"
|
||||
|
||||
//set up the palette for color printing
|
||||
static u16 colorTable[] = {
|
||||
RGB8_to_565( 0, 0, 0), // black
|
||||
RGB8_to_565(128, 0, 0), // red
|
||||
RGB8_to_565( 0,128, 0), // green
|
||||
RGB8_to_565(128,128, 0), // yellow
|
||||
RGB8_to_565( 0, 0,128), // blue
|
||||
RGB8_to_565(128, 0,128), // magenta
|
||||
RGB8_to_565( 0,128,128), // cyan
|
||||
RGB8_to_565(192,192,192), // white
|
||||
|
||||
RGB8_to_565(128,128,128), // bright black
|
||||
RGB8_to_565(255, 0, 0), // bright red
|
||||
RGB8_to_565( 0,255, 0), // bright green
|
||||
RGB8_to_565(255,255, 0), // bright yellow
|
||||
RGB8_to_565( 0, 0,255), // bright blue
|
||||
RGB8_to_565(255, 0,255), // bright magenta
|
||||
RGB8_to_565( 0,255,255), // bright cyan
|
||||
RGB8_to_565(255,255,255), // bright white
|
||||
|
||||
RGB8_to_565( 0, 0, 0), // faint black
|
||||
RGB8_to_565( 64, 0, 0), // faint red
|
||||
RGB8_to_565( 0, 64, 0), // faint green
|
||||
RGB8_to_565( 64, 64, 0), // faint yellow
|
||||
RGB8_to_565( 0, 0, 64), // faint blue
|
||||
RGB8_to_565( 64, 0, 64), // faint magenta
|
||||
RGB8_to_565( 0, 64, 64), // faint cyan
|
||||
RGB8_to_565( 96, 96, 96), // faint white
|
||||
};
|
||||
|
||||
PrintConsole defaultConsole =
|
||||
{
|
||||
//Font:
|
||||
{
|
||||
(u8*)default_font_bin, //font gfx
|
||||
0, //first ascii character in the set
|
||||
128 //number of characters in the font set
|
||||
},
|
||||
(u16*)NULL,
|
||||
0,0, //cursorX cursorY
|
||||
0,0, //prevcursorX prevcursorY
|
||||
40, //console width
|
||||
30, //console height
|
||||
0, //window x
|
||||
0, //window y
|
||||
40, //window width
|
||||
30, //window height
|
||||
3, //tab size
|
||||
7, // foreground color
|
||||
0, // background color
|
||||
0, // flags
|
||||
0, //print callback
|
||||
false //console initialized
|
||||
};
|
||||
|
||||
PrintConsole currentCopy;
|
||||
|
||||
PrintConsole* currentConsole = ¤tCopy;
|
||||
|
||||
PrintConsole* consoleGetDefault(void){return &defaultConsole;}
|
||||
|
||||
void consolePrintChar(char c);
|
||||
void consoleDrawChar(int c);
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
static void consoleCls(char mode) {
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
int i = 0;
|
||||
int colTemp,rowTemp;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case '[':
|
||||
case '0':
|
||||
{
|
||||
colTemp = currentConsole->cursorX ;
|
||||
rowTemp = currentConsole->cursorY ;
|
||||
|
||||
while(i++ < ((currentConsole->windowHeight * currentConsole->windowWidth) - (rowTemp * currentConsole->consoleWidth + colTemp)))
|
||||
consolePrintChar(' ');
|
||||
|
||||
currentConsole->cursorX = colTemp;
|
||||
currentConsole->cursorY = rowTemp;
|
||||
break;
|
||||
}
|
||||
case '1':
|
||||
{
|
||||
colTemp = currentConsole->cursorX ;
|
||||
rowTemp = currentConsole->cursorY ;
|
||||
|
||||
currentConsole->cursorY = 0;
|
||||
currentConsole->cursorX = 0;
|
||||
|
||||
while (i++ < (rowTemp * currentConsole->windowWidth + colTemp))
|
||||
consolePrintChar(' ');
|
||||
|
||||
currentConsole->cursorX = colTemp;
|
||||
currentConsole->cursorY = rowTemp;
|
||||
break;
|
||||
}
|
||||
case '2':
|
||||
{
|
||||
currentConsole->cursorY = 0;
|
||||
currentConsole->cursorX = 0;
|
||||
|
||||
while(i++ < currentConsole->windowHeight * currentConsole->windowWidth)
|
||||
consolePrintChar(' ');
|
||||
|
||||
currentConsole->cursorY = 0;
|
||||
currentConsole->cursorX = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
static void consoleClearLine(char mode) {
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
int i = 0;
|
||||
int colTemp;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case '[':
|
||||
case '0':
|
||||
{
|
||||
colTemp = currentConsole->cursorX ;
|
||||
|
||||
while(i++ < (currentConsole->windowWidth - colTemp)) {
|
||||
consolePrintChar(' ');
|
||||
}
|
||||
|
||||
currentConsole->cursorX = colTemp;
|
||||
|
||||
break;
|
||||
}
|
||||
case '1':
|
||||
{
|
||||
colTemp = currentConsole->cursorX ;
|
||||
|
||||
currentConsole->cursorX = 0;
|
||||
|
||||
while(i++ < ((currentConsole->windowWidth - colTemp)-2)) {
|
||||
consolePrintChar(' ');
|
||||
}
|
||||
|
||||
currentConsole->cursorX = colTemp;
|
||||
|
||||
break;
|
||||
}
|
||||
case '2':
|
||||
{
|
||||
colTemp = currentConsole->cursorX ;
|
||||
|
||||
currentConsole->cursorX = 0;
|
||||
|
||||
while(i++ < currentConsole->windowWidth) {
|
||||
consolePrintChar(' ');
|
||||
}
|
||||
|
||||
currentConsole->cursorX = colTemp;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
ssize_t con_write(struct _reent *r,int fd,const char *ptr, size_t len) {
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
char chr;
|
||||
|
||||
int i, count = 0;
|
||||
char *tmp = (char*)ptr;
|
||||
|
||||
if(!tmp || len<=0) return -1;
|
||||
|
||||
i = 0;
|
||||
|
||||
while(i<len) {
|
||||
|
||||
chr = *(tmp++);
|
||||
i++; count++;
|
||||
|
||||
if ( chr == 0x1b && *tmp == '[' ) {
|
||||
bool escaping = true;
|
||||
char *escapeseq = tmp++;
|
||||
int escapelen = 1;
|
||||
i++; count++;
|
||||
|
||||
do {
|
||||
chr = *(tmp++);
|
||||
i++; count++; escapelen++;
|
||||
int parameter, assigned, consumed;
|
||||
|
||||
// make sure parameters are positive values and delimited by semicolon
|
||||
if((chr >= '0' && chr <= '9') || chr == ';')
|
||||
continue;
|
||||
|
||||
switch (chr) {
|
||||
//---------------------------------------
|
||||
// Cursor directional movement
|
||||
//---------------------------------------
|
||||
case 'A':
|
||||
consumed = 0;
|
||||
assigned = sscanf(escapeseq,"[%dA%n", ¶meter, &consumed);
|
||||
if (assigned==0) parameter = 1;
|
||||
if (consumed)
|
||||
currentConsole->cursorY = (currentConsole->cursorY - parameter) < 0 ? 0 : currentConsole->cursorY - parameter;
|
||||
escaping = false;
|
||||
break;
|
||||
case 'B':
|
||||
consumed = 0;
|
||||
assigned = sscanf(escapeseq,"[%dB%n", ¶meter, &consumed);
|
||||
if (assigned==0) parameter = 1;
|
||||
if (consumed)
|
||||
currentConsole->cursorY = (currentConsole->cursorY + parameter) > currentConsole->windowHeight - 1 ? currentConsole->windowHeight - 1 : currentConsole->cursorY + parameter;
|
||||
escaping = false;
|
||||
break;
|
||||
case 'C':
|
||||
consumed = 0;
|
||||
assigned = sscanf(escapeseq,"[%dC%n", ¶meter, &consumed);
|
||||
if (assigned==0) parameter = 1;
|
||||
if (consumed)
|
||||
currentConsole->cursorX = (currentConsole->cursorX + parameter) > currentConsole->windowWidth - 1 ? currentConsole->windowWidth - 1 : currentConsole->cursorX + parameter;
|
||||
escaping = false;
|
||||
break;
|
||||
case 'D':
|
||||
consumed = 0;
|
||||
assigned = sscanf(escapeseq,"[%dD%n", ¶meter, &consumed);
|
||||
if (assigned==0) parameter = 1;
|
||||
if (consumed)
|
||||
currentConsole->cursorX = (currentConsole->cursorX - parameter) < 0 ? 0 : currentConsole->cursorX - parameter;
|
||||
escaping = false;
|
||||
break;
|
||||
//---------------------------------------
|
||||
// Cursor position movement
|
||||
//---------------------------------------
|
||||
case 'H':
|
||||
case 'f':
|
||||
{
|
||||
int x, y;
|
||||
char c;
|
||||
if(sscanf(escapeseq,"[%d;%d%c", &y, &x, &c) == 3 && (c == 'f' || c == 'H')) {
|
||||
currentConsole->cursorX = x;
|
||||
currentConsole->cursorY = y;
|
||||
escaping = false;
|
||||
break;
|
||||
}
|
||||
|
||||
x = y = 1;
|
||||
if(sscanf(escapeseq,"[%d;%c", &y, &c) == 2 && (c == 'f' || c == 'H')) {
|
||||
currentConsole->cursorX = x;
|
||||
currentConsole->cursorY = y;
|
||||
escaping = false;
|
||||
break;
|
||||
}
|
||||
|
||||
x = y = 1;
|
||||
if(sscanf(escapeseq,"[;%d%c", &x, &c) == 2 && (c == 'f' || c == 'H')) {
|
||||
currentConsole->cursorX = x;
|
||||
currentConsole->cursorY = y;
|
||||
escaping = false;
|
||||
break;
|
||||
}
|
||||
|
||||
x = y = 1;
|
||||
if(sscanf(escapeseq,"[;%c", &c) == 1 && (c == 'f' || c == 'H')) {
|
||||
currentConsole->cursorX = x;
|
||||
currentConsole->cursorY = y;
|
||||
escaping = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// invalid format
|
||||
escaping = false;
|
||||
break;
|
||||
}
|
||||
//---------------------------------------
|
||||
// Screen clear
|
||||
//---------------------------------------
|
||||
case 'J':
|
||||
if(escapelen <= 3)
|
||||
consoleCls(escapeseq[escapelen-2]);
|
||||
escaping = false;
|
||||
break;
|
||||
//---------------------------------------
|
||||
// Line clear
|
||||
//---------------------------------------
|
||||
case 'K':
|
||||
if(escapelen <= 3)
|
||||
consoleClearLine(escapeseq[escapelen-2]);
|
||||
escaping = false;
|
||||
break;
|
||||
//---------------------------------------
|
||||
// Save cursor position
|
||||
//---------------------------------------
|
||||
case 's':
|
||||
if(escapelen == 2) {
|
||||
currentConsole->prevCursorX = currentConsole->cursorX ;
|
||||
currentConsole->prevCursorY = currentConsole->cursorY ;
|
||||
}
|
||||
escaping = false;
|
||||
break;
|
||||
//---------------------------------------
|
||||
// Load cursor position
|
||||
//---------------------------------------
|
||||
case 'u':
|
||||
if(escapelen == 2) {
|
||||
currentConsole->cursorX = currentConsole->prevCursorX ;
|
||||
currentConsole->cursorY = currentConsole->prevCursorY ;
|
||||
}
|
||||
escaping = false;
|
||||
break;
|
||||
//---------------------------------------
|
||||
// Color scan codes
|
||||
//---------------------------------------
|
||||
case 'm':
|
||||
escapeseq++;
|
||||
escapelen--;
|
||||
|
||||
do {
|
||||
parameter = 0;
|
||||
if (escapelen == 1) {
|
||||
consumed = 1;
|
||||
} else if (strchr(escapeseq,';')) {
|
||||
sscanf(escapeseq,"%d;%n", ¶meter, &consumed);
|
||||
} else {
|
||||
sscanf(escapeseq,"%dm%n", ¶meter, &consumed);
|
||||
}
|
||||
|
||||
escapeseq += consumed;
|
||||
escapelen -= consumed;
|
||||
|
||||
switch(parameter) {
|
||||
case 0: // reset
|
||||
currentConsole->flags = 0;
|
||||
currentConsole->bg = 0;
|
||||
currentConsole->fg = 7;
|
||||
break;
|
||||
|
||||
case 1: // bold
|
||||
currentConsole->flags &= ~CONSOLE_COLOR_FAINT;
|
||||
currentConsole->flags |= CONSOLE_COLOR_BOLD;
|
||||
break;
|
||||
|
||||
case 2: // faint
|
||||
currentConsole->flags &= ~CONSOLE_COLOR_BOLD;
|
||||
currentConsole->flags |= CONSOLE_COLOR_FAINT;
|
||||
break;
|
||||
|
||||
case 3: // italic
|
||||
currentConsole->flags |= CONSOLE_ITALIC;
|
||||
break;
|
||||
|
||||
case 4: // underline
|
||||
currentConsole->flags |= CONSOLE_UNDERLINE;
|
||||
break;
|
||||
|
||||
case 5: // blink slow
|
||||
currentConsole->flags &= ~CONSOLE_BLINK_FAST;
|
||||
currentConsole->flags |= CONSOLE_BLINK_SLOW;
|
||||
break;
|
||||
|
||||
case 6: // blink fast
|
||||
currentConsole->flags &= ~CONSOLE_BLINK_SLOW;
|
||||
currentConsole->flags |= CONSOLE_BLINK_FAST;
|
||||
break;
|
||||
|
||||
case 7: // reverse video
|
||||
currentConsole->flags |= CONSOLE_COLOR_REVERSE;
|
||||
break;
|
||||
|
||||
case 8: // conceal
|
||||
currentConsole->flags |= CONSOLE_CONCEAL;
|
||||
break;
|
||||
|
||||
case 9: // crossed-out
|
||||
currentConsole->flags |= CONSOLE_CROSSED_OUT;
|
||||
break;
|
||||
|
||||
case 21: // bold off
|
||||
currentConsole->flags &= ~CONSOLE_COLOR_BOLD;
|
||||
break;
|
||||
|
||||
case 22: // normal color
|
||||
currentConsole->flags &= ~CONSOLE_COLOR_BOLD;
|
||||
currentConsole->flags &= ~CONSOLE_COLOR_FAINT;
|
||||
break;
|
||||
|
||||
case 23: // italic off
|
||||
currentConsole->flags &= ~CONSOLE_ITALIC;
|
||||
break;
|
||||
|
||||
case 24: // underline off
|
||||
currentConsole->flags &= ~CONSOLE_UNDERLINE;
|
||||
break;
|
||||
|
||||
case 25: // blink off
|
||||
currentConsole->flags &= ~CONSOLE_BLINK_SLOW;
|
||||
currentConsole->flags &= ~CONSOLE_BLINK_FAST;
|
||||
break;
|
||||
|
||||
case 27: // reverse off
|
||||
currentConsole->flags &= ~CONSOLE_COLOR_REVERSE;
|
||||
break;
|
||||
|
||||
case 29: // crossed-out off
|
||||
currentConsole->flags &= ~CONSOLE_CROSSED_OUT;
|
||||
break;
|
||||
|
||||
case 30 ... 37: // writing color
|
||||
currentConsole->fg = parameter - 30;
|
||||
break;
|
||||
|
||||
case 39: // reset foreground color
|
||||
currentConsole->fg = 7;
|
||||
break;
|
||||
|
||||
case 40 ... 47: // screen color
|
||||
currentConsole->bg = parameter - 40;
|
||||
break;
|
||||
|
||||
case 49: // reset background color
|
||||
currentConsole->fg = 0;
|
||||
break;
|
||||
}
|
||||
} while (escapelen > 0);
|
||||
|
||||
escaping = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
// some sort of unsupported escape; just gloss over it
|
||||
escaping = false;
|
||||
break;
|
||||
}
|
||||
} while (escaping);
|
||||
continue;
|
||||
}
|
||||
|
||||
consolePrintChar(chr);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const devoptab_t dotab_stdout = {
|
||||
"con",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
con_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
ssize_t debug_write(struct _reent *r, int fd, const char *ptr, size_t len) {
|
||||
//---------------------------------------------------------------------------------
|
||||
svcOutputDebugString(ptr,len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static const devoptab_t dotab_3dmoo = {
|
||||
"3dmoo",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
debug_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static const devoptab_t dotab_null = {
|
||||
"null",
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
PrintConsole* consoleInit(gfxScreen_t screen, PrintConsole* console) {
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
static bool firstConsoleInit = true;
|
||||
|
||||
if(firstConsoleInit) {
|
||||
devoptab_list[STD_OUT] = &dotab_stdout;
|
||||
devoptab_list[STD_ERR] = &dotab_stdout;
|
||||
|
||||
setvbuf(stdout, NULL , _IONBF, 0);
|
||||
setvbuf(stderr, NULL , _IONBF, 0);
|
||||
|
||||
firstConsoleInit = false;
|
||||
}
|
||||
|
||||
if(console) {
|
||||
currentConsole = console;
|
||||
} else {
|
||||
console = currentConsole;
|
||||
}
|
||||
|
||||
*currentConsole = defaultConsole;
|
||||
|
||||
console->consoleInitialised = 1;
|
||||
|
||||
gfxSetScreenFormat(screen,GSP_RGB565_OES);
|
||||
gfxSetDoubleBuffering(screen,false);
|
||||
console->frameBuffer = (u16*)gfxGetFramebuffer(screen, GFX_LEFT, NULL, NULL);
|
||||
|
||||
if(screen==GFX_TOP) {
|
||||
console->consoleWidth = 50;
|
||||
console->windowWidth = 50;
|
||||
}
|
||||
|
||||
|
||||
consoleCls('2');
|
||||
|
||||
return currentConsole;
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void consoleDebugInit(debugDevice device){
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
int buffertype = _IONBF;
|
||||
|
||||
switch(device) {
|
||||
|
||||
case debugDevice_3DMOO:
|
||||
devoptab_list[STD_ERR] = &dotab_3dmoo;
|
||||
buffertype = _IOLBF;
|
||||
break;
|
||||
case debugDevice_CONSOLE:
|
||||
devoptab_list[STD_ERR] = &dotab_stdout;
|
||||
break;
|
||||
case debugDevice_NULL:
|
||||
devoptab_list[STD_ERR] = &dotab_null;
|
||||
break;
|
||||
}
|
||||
setvbuf(stderr, NULL , buffertype, 0);
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
PrintConsole *consoleSelect(PrintConsole* console){
|
||||
//---------------------------------------------------------------------------------
|
||||
PrintConsole *tmp = currentConsole;
|
||||
currentConsole = console;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void consoleSetFont(PrintConsole* console, ConsoleFont* font){
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
if(!console) console = currentConsole;
|
||||
|
||||
console->font = *font;
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
static void newRow() {
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
currentConsole->cursorY ++;
|
||||
|
||||
|
||||
if(currentConsole->cursorY >= currentConsole->windowHeight) {
|
||||
currentConsole->cursorY --;
|
||||
u16 *dst = ¤tConsole->frameBuffer[(currentConsole->windowX * 8 * 240) + (239 - (currentConsole->windowY * 8))];
|
||||
u16 *src = dst - 8;
|
||||
|
||||
int i,j;
|
||||
|
||||
for (i=0; i<currentConsole->windowWidth*8; i++) {
|
||||
u32 *from = (u32*)((int)src & ~3);
|
||||
u32 *to = (u32*)((int)dst & ~3);
|
||||
for (j=0;j<(((currentConsole->windowHeight-1)*8)/2);j++) *(to--) = *(from--);
|
||||
dst += 240;
|
||||
src += 240;
|
||||
}
|
||||
|
||||
consoleClearLine('2');
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
void consoleDrawChar(int c) {
|
||||
//---------------------------------------------------------------------------------
|
||||
c -= currentConsole->font.asciiOffset;
|
||||
if ( c < 0 || c > currentConsole->font.numChars ) return;
|
||||
|
||||
u8 *fontdata = currentConsole->font.gfx + (8 * c);
|
||||
|
||||
int writingColor = currentConsole->fg;
|
||||
int screenColor = currentConsole->bg;
|
||||
|
||||
if (currentConsole->flags & CONSOLE_COLOR_BOLD) {
|
||||
writingColor += 8;
|
||||
} else if (currentConsole->flags & CONSOLE_COLOR_FAINT) {
|
||||
writingColor += 16;
|
||||
}
|
||||
|
||||
if (currentConsole->flags & CONSOLE_COLOR_REVERSE) {
|
||||
int tmp = writingColor;
|
||||
writingColor = screenColor;
|
||||
screenColor = tmp;
|
||||
}
|
||||
|
||||
u16 bg = colorTable[screenColor];
|
||||
u16 fg = colorTable[writingColor];
|
||||
|
||||
u8 b1 = *(fontdata++);
|
||||
u8 b2 = *(fontdata++);
|
||||
u8 b3 = *(fontdata++);
|
||||
u8 b4 = *(fontdata++);
|
||||
u8 b5 = *(fontdata++);
|
||||
u8 b6 = *(fontdata++);
|
||||
u8 b7 = *(fontdata++);
|
||||
u8 b8 = *(fontdata++);
|
||||
|
||||
if (currentConsole->flags & CONSOLE_UNDERLINE) b8 = 0xff;
|
||||
|
||||
if (currentConsole->flags & CONSOLE_CROSSED_OUT) b4 = 0xff;
|
||||
|
||||
u8 mask = 0x80;
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
int x = (currentConsole->cursorX + currentConsole->windowX) * 8;
|
||||
int y = ((currentConsole->cursorY + currentConsole->windowY) *8 );
|
||||
|
||||
u16 *screen = ¤tConsole->frameBuffer[(x * 240) + (239 - (y + 7))];
|
||||
|
||||
for (i=0;i<8;i++) {
|
||||
if (b8 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; }
|
||||
if (b7 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; }
|
||||
if (b6 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; }
|
||||
if (b5 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; }
|
||||
if (b4 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; }
|
||||
if (b3 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; }
|
||||
if (b2 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; }
|
||||
if (b1 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; }
|
||||
mask >>= 1;
|
||||
screen += 240 - 8;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void consolePrintChar(char c) {
|
||||
//---------------------------------------------------------------------------------
|
||||
if (c==0) return;
|
||||
|
||||
if(currentConsole->PrintChar)
|
||||
if(currentConsole->PrintChar(currentConsole, c))
|
||||
return;
|
||||
|
||||
if(currentConsole->cursorX >= currentConsole->windowWidth) {
|
||||
currentConsole->cursorX = 0;
|
||||
|
||||
newRow();
|
||||
}
|
||||
|
||||
switch(c) {
|
||||
/*
|
||||
The only special characters we will handle are tab (\t), carriage return (\r), line feed (\n)
|
||||
and backspace (\b).
|
||||
Carriage return & line feed will function the same: go to next line and put cursor at the beginning.
|
||||
For everything else, use VT sequences.
|
||||
|
||||
Reason: VT sequences are more specific to the task of cursor placement.
|
||||
The special escape sequences \b \f & \v are archaic and non-portable.
|
||||
*/
|
||||
case 8:
|
||||
currentConsole->cursorX--;
|
||||
|
||||
if(currentConsole->cursorX < 0) {
|
||||
if(currentConsole->cursorY > 0) {
|
||||
currentConsole->cursorX = currentConsole->windowX - 1;
|
||||
currentConsole->cursorY--;
|
||||
} else {
|
||||
currentConsole->cursorX = 0;
|
||||
}
|
||||
}
|
||||
|
||||
consoleDrawChar(' ');
|
||||
break;
|
||||
|
||||
case 9:
|
||||
currentConsole->cursorX += currentConsole->tabSize - ((currentConsole->cursorX)%(currentConsole->tabSize));
|
||||
break;
|
||||
case 10:
|
||||
newRow();
|
||||
case 13:
|
||||
currentConsole->cursorX = 0;
|
||||
break;
|
||||
default:
|
||||
consoleDrawChar(c);
|
||||
++currentConsole->cursorX ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void consoleClear(void) {
|
||||
//---------------------------------------------------------------------------------
|
||||
iprintf("\x1b[2J");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height){
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
if(!console) console = currentConsole;
|
||||
|
||||
console->windowWidth = width;
|
||||
console->windowHeight = height;
|
||||
console->windowX = x;
|
||||
console->windowY = y;
|
||||
|
||||
console->cursorX = 0;
|
||||
console->cursorY = 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/gfx.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/linear.h>
|
||||
|
||||
GSP_FramebufferInfo topFramebufferInfo, bottomFramebufferInfo;
|
||||
|
||||
@ -12,9 +15,9 @@ u8* gfxTopLeftFramebuffers[2];
|
||||
u8* gfxTopRightFramebuffers[2];
|
||||
u8* gfxBottomFramebuffers[2];
|
||||
|
||||
static u8 currentBuffer;
|
||||
static bool enable3d;
|
||||
static int doubleBuf = 1;
|
||||
static u8 currentBuffer[2];
|
||||
static int doubleBuf[2] = {1,1};
|
||||
|
||||
Handle gspEvent, gspSharedMemHandle;
|
||||
|
||||
@ -33,8 +36,8 @@ void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format) {
|
||||
botFormat = format;
|
||||
}
|
||||
|
||||
void gfxSetDoubleBuffering(bool doubleBuffering) {
|
||||
doubleBuf = doubleBuffering ? 1 : 0; // make sure they're the integer values '1' and '0'
|
||||
void gfxSetDoubleBuffering( gfxScreen_t screen, bool doubleBuffering) {
|
||||
doubleBuf[screen] = doubleBuffering ? 1 : 0; // make sure they're the integer values '1' and '0'
|
||||
}
|
||||
|
||||
static u32 __get_bytes_per_pixel(GSP_FramebufferFormats format) {
|
||||
@ -81,7 +84,7 @@ void gfxWriteFramebufferInfo(gfxScreen_t screen)
|
||||
u8* framebufferInfoHeader=gfxSharedMemory+0x200+gfxThreadID*0x80;
|
||||
if(screen==GFX_BOTTOM)framebufferInfoHeader+=0x40;
|
||||
GSP_FramebufferInfo* framebufferInfo=(GSP_FramebufferInfo*)&framebufferInfoHeader[0x4];
|
||||
framebufferInfoHeader[0x0]^=doubleBuf;
|
||||
framebufferInfoHeader[0x0]^=doubleBuf[screen];
|
||||
framebufferInfo[framebufferInfoHeader[0x0]]=(screen==GFX_TOP)?(topFramebufferInfo):(bottomFramebufferInfo);
|
||||
framebufferInfoHeader[0x1]=1;
|
||||
}
|
||||
@ -93,7 +96,6 @@ void gfxInit()
|
||||
gfxSharedMemory=(u8*)0x10002000;
|
||||
|
||||
GSPGPU_AcquireRight(NULL, 0x0);
|
||||
GSPGPU_SetLcdForceBlack(NULL, 0x0);
|
||||
|
||||
//setup our gsp shared mem section
|
||||
svcCreateEvent(&gspEvent, 0x0);
|
||||
@ -124,11 +126,14 @@ void gfxInit()
|
||||
//GSP shared mem : 0x2779F000
|
||||
gxCmdBuf=(u32*)(gfxSharedMemory+0x800+gfxThreadID*0x200);
|
||||
|
||||
currentBuffer=0;
|
||||
currentBuffer[0]=0;
|
||||
currentBuffer[1]=0;
|
||||
|
||||
// Initialize event handler and wait for VBlank
|
||||
gspInitEventHandler(gspEvent, (vu8*)gfxSharedMemory, gfxThreadID);
|
||||
gspWaitForVBlank();
|
||||
|
||||
GSPGPU_SetLcdForceBlack(NULL, 0x0);
|
||||
}
|
||||
|
||||
void gfxExit()
|
||||
@ -153,7 +158,7 @@ void gfxExit()
|
||||
svcCloseHandle(gspEvent);
|
||||
|
||||
GSPGPU_ReleaseRight(NULL);
|
||||
|
||||
|
||||
gspExit();
|
||||
}
|
||||
|
||||
@ -164,10 +169,10 @@ u8* gfxGetFramebuffer(gfxScreen_t screen, gfx3dSide_t side, u16* width, u16* hei
|
||||
if(screen==GFX_TOP)
|
||||
{
|
||||
if(height)*height=400;
|
||||
return (side==GFX_LEFT || !enable3d)?(gfxTopLeftFramebuffers[currentBuffer^doubleBuf]):(gfxTopRightFramebuffers[currentBuffer^doubleBuf]);
|
||||
return (side==GFX_LEFT || !enable3d)?(gfxTopLeftFramebuffers[currentBuffer[0]^doubleBuf[0]]):(gfxTopRightFramebuffers[currentBuffer[0]^doubleBuf[0]]);
|
||||
}else{
|
||||
if(height)*height=320;
|
||||
return gfxBottomFramebuffers[currentBuffer^doubleBuf];
|
||||
return gfxBottomFramebuffers[currentBuffer[1]^doubleBuf[1]];
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,18 +185,20 @@ void gfxFlushBuffers()
|
||||
|
||||
void gfxSwapBuffers()
|
||||
{
|
||||
currentBuffer^=doubleBuf;
|
||||
gfxSetFramebufferInfo(GFX_TOP, currentBuffer);
|
||||
gfxSetFramebufferInfo(GFX_BOTTOM, currentBuffer);
|
||||
currentBuffer[0]^=doubleBuf[0];
|
||||
currentBuffer[1]^=doubleBuf[1];
|
||||
gfxSetFramebufferInfo(GFX_TOP, currentBuffer[0]);
|
||||
gfxSetFramebufferInfo(GFX_BOTTOM, currentBuffer[1]);
|
||||
GSPGPU_SetBufferSwap(NULL, GFX_TOP, &topFramebufferInfo);
|
||||
GSPGPU_SetBufferSwap(NULL, GFX_BOTTOM, &bottomFramebufferInfo);
|
||||
}
|
||||
|
||||
void gfxSwapBuffersGpu()
|
||||
{
|
||||
currentBuffer^=doubleBuf;
|
||||
gfxSetFramebufferInfo(GFX_TOP, currentBuffer);
|
||||
gfxSetFramebufferInfo(GFX_BOTTOM, currentBuffer);
|
||||
currentBuffer[0]^=doubleBuf[0];
|
||||
currentBuffer[1]^=doubleBuf[1];
|
||||
gfxSetFramebufferInfo(GFX_TOP, currentBuffer[0]);
|
||||
gfxSetFramebufferInfo(GFX_BOTTOM, currentBuffer[1]);
|
||||
gfxWriteFramebufferInfo(GFX_TOP);
|
||||
gfxWriteFramebufferInfo(GFX_BOTTOM);
|
||||
}
|
||||
|
@ -4,7 +4,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/gpu/gpu.h>
|
||||
#include <3ds/gpu/gx.h>
|
||||
#include <3ds/gpu/shdr.h>
|
||||
|
||||
u32* gpuCmdBuf;
|
||||
u32 gpuCmdBufSize;
|
||||
|
@ -4,8 +4,9 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/gpu/gpu.h>
|
||||
#include <3ds/gpu/shdr.h>
|
||||
|
||||
//please don't feed this an invalid SHBIN
|
||||
DVLB_s* SHDR_ParseSHBIN(u32* shbinData, u32 shbinSize)
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <sys/iosupport.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
|
||||
// System globals we define here
|
||||
int __system_argc;
|
||||
|
@ -1,4 +1,7 @@
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/os.h>
|
||||
#include <3ds/svc.h>
|
||||
|
||||
|
||||
#define TICKS_PER_MSEC 268123.480
|
||||
|
||||
|
@ -6,7 +6,11 @@
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/sdmc.h>
|
||||
#include <3ds/services/fs.h>
|
||||
|
||||
|
||||
|
||||
/*! @internal
|
||||
*
|
||||
@ -240,7 +244,18 @@ sdmc_open(struct _reent *r,
|
||||
if(flags & O_CREAT)
|
||||
sdmc_flags |= FS_OPEN_CREATE;
|
||||
|
||||
/* TODO: Test O_EXCL. */
|
||||
/* Test O_EXCL. */
|
||||
if((flags & O_CREAT) && (flags & O_EXCL))
|
||||
{
|
||||
rc = FSUSER_CreateFile(NULL, sdmcArchive, FS_makePath(PATH_CHAR, pathptr), 0);
|
||||
if(rc != 0)
|
||||
{
|
||||
r->_errno = rc;
|
||||
if(rc == 0x82044BE)
|
||||
r->_errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* set attributes */
|
||||
/*if(!(mode & S_IWUSR))
|
||||
@ -251,6 +266,16 @@ sdmc_open(struct _reent *r,
|
||||
sdmc_flags, attributes);
|
||||
if(rc == 0)
|
||||
{
|
||||
if((flags & O_ACCMODE) != O_RDONLY && (flags & O_TRUNC))
|
||||
{
|
||||
rc = FSFILE_SetSize(fd, 0);
|
||||
if(rc != 0)
|
||||
{
|
||||
FSFILE_Close(fd);
|
||||
r->_errno = rc;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
file->fd = fd;
|
||||
file->flags = (flags & (O_ACCMODE|O_APPEND|O_SYNC));
|
||||
file->offset = 0;
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/ac.h>
|
||||
|
||||
static Handle acHandle;
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/am.h>
|
||||
|
||||
static Handle amHandle = 0;
|
||||
|
||||
|
@ -4,7 +4,12 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/apt.h>
|
||||
#include <3ds/services/gsp.h>
|
||||
|
||||
|
||||
#define APT_HANDLER_STACKSIZE (0x1000)
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/cfgnor.h>
|
||||
|
||||
Handle CFGNOR_handle = 0;
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/cfgu.h>
|
||||
|
||||
static Handle CFGU_handle = 0;
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/os.h>
|
||||
#include <3ds/services/csnd.h>
|
||||
|
||||
//See here regarding CSND shared-mem commands, etc: http://3dbrew.org/wiki/CSND_Shared_Memory
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/fs.h>
|
||||
|
||||
/*! @internal
|
||||
*
|
||||
|
@ -4,7 +4,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/gsp.h>
|
||||
|
||||
#define GSP_EVENT_STACK_SIZE 0x1000
|
||||
|
||||
|
@ -3,7 +3,11 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/gpu/gx.h>
|
||||
#include <3ds/services/gsp.h>
|
||||
|
||||
u32* gxCmdBuf;
|
||||
|
||||
|
@ -3,7 +3,12 @@
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/apt.h>
|
||||
#include <3ds/services/hid.h>
|
||||
#include <3ds/services/irrst.h>
|
||||
|
||||
Handle hidHandle;
|
||||
Handle hidMemHandle;
|
||||
@ -245,3 +250,28 @@ Result HIDUSER_DisableGyroscope()
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result HIDUSER_GetGyroscopeRawToDpsCoefficient(float *coeff)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x150000; //request header code
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svcSendSyncRequest(hidHandle)))return ret;
|
||||
|
||||
*coeff = (float)cmdbuf[2];
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
||||
Result HIDUSER_GetSoundVolume(u8 *volume)
|
||||
{
|
||||
u32* cmdbuf=getThreadCommandBuffer();
|
||||
cmdbuf[0]=0x170000; //request header code
|
||||
|
||||
Result ret=0;
|
||||
if((ret=svcSendSyncRequest(hidHandle)))return ret;
|
||||
|
||||
*volume = (u8)cmdbuf[2];
|
||||
|
||||
return cmdbuf[1];
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/httpc.h>
|
||||
|
||||
Handle __httpc_servhandle = 0;
|
||||
|
||||
@ -33,15 +36,26 @@ Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy)
|
||||
if(ret!=0)return ret;
|
||||
|
||||
ret = srvGetServiceHandle(&context->servhandle, "http:C");
|
||||
if(ret!=0)return ret;
|
||||
if(ret!=0) {
|
||||
HTTPC_CloseContext(__httpc_servhandle, context->httphandle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = HTTPC_InitializeConnectionSession(context->servhandle, context->httphandle);
|
||||
if(ret!=0)return ret;
|
||||
if(ret!=0) {
|
||||
HTTPC_CloseContext(__httpc_servhandle, context->httphandle);
|
||||
svcCloseHandle(context->servhandle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(use_defaultproxy==0)return 0;
|
||||
|
||||
ret = HTTPC_SetProxyDefault(context->servhandle, context->httphandle);
|
||||
if(ret!=0)return ret;
|
||||
if(ret!=0) {
|
||||
HTTPC_CloseContext(__httpc_servhandle, context->httphandle);
|
||||
svcCloseHandle(context->servhandle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -51,7 +65,6 @@ Result httpcCloseContext(httpcContext *context)
|
||||
Result ret=0;
|
||||
|
||||
ret = HTTPC_CloseContext(context->servhandle, context->httphandle);
|
||||
|
||||
svcCloseHandle(context->servhandle);
|
||||
|
||||
return ret;
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/ir.h>
|
||||
|
||||
static Handle iru_handle=0;
|
||||
static Handle iru_sharedmem_handle=0;
|
||||
|
@ -3,7 +3,10 @@
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/irrst.h>
|
||||
|
||||
Handle irrstHandle;
|
||||
Handle irrstMemHandle;
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/mic.h>
|
||||
|
||||
//See also: http://3dbrew.org/wiki/MIC_Services
|
||||
|
||||
|
@ -4,7 +4,12 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/os.h>
|
||||
#include <3ds/linear.h>
|
||||
#include <3ds/services/mvd.h>
|
||||
|
||||
Handle mvdstdHandle;
|
||||
static u32 mvdstdInitialized = 0;
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/ns.h>
|
||||
|
||||
static Handle nsHandle;
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/pm.h>
|
||||
|
||||
static Handle pmHandle;
|
||||
|
||||
|
@ -1,11 +1,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/ps.h>
|
||||
|
||||
static Handle psHandle;
|
||||
|
||||
Result psInit()
|
||||
{
|
||||
return srvGetServiceHandle(&psHandle, "ps:ps");
|
||||
return srvGetServiceHandle(&psHandle, "ps:ps");
|
||||
}
|
||||
|
||||
Result psExit()
|
||||
@ -17,7 +20,7 @@ Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, u32 aes_algo, u32 key_typ
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
u32 *_iv = (u32*)iv;
|
||||
|
||||
cmdbuf[0] = 0x000401C4;
|
||||
@ -32,14 +35,14 @@ Result PS_EncryptDecryptAes(u32 size, u8* in, u8* out, u32 aes_algo, u32 key_typ
|
||||
cmdbuf[9] = (u32)in;
|
||||
cmdbuf[10] = (size << 0x8) | 0x14;
|
||||
cmdbuf[11] = (u32)out;
|
||||
|
||||
|
||||
if((ret = svcSendSyncRequest(psHandle))!=0)return ret;
|
||||
|
||||
_iv[0] = cmdbuf[2];
|
||||
_iv[1] = cmdbuf[3];
|
||||
_iv[2] = cmdbuf[4];
|
||||
_iv[3] = cmdbuf[5];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -47,7 +50,7 @@ Result PS_EncryptSignDecryptVerifyAesCcm(u8* in, u32 in_size, u8* out, u32 out_s
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
u32 *_nonce = (u32*)nonce;
|
||||
|
||||
cmdbuf[0] = 0x00050284;
|
||||
@ -65,9 +68,9 @@ Result PS_EncryptSignDecryptVerifyAesCcm(u8* in, u32 in_size, u8* out, u32 out_s
|
||||
cmdbuf[9] = (u32)in;
|
||||
cmdbuf[10] = (out_size << 0x8) | 0x14;
|
||||
cmdbuf[11] = (u32)out;
|
||||
|
||||
|
||||
if((ret = svcSendSyncRequest(psHandle))!=0)return ret;
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -75,13 +78,13 @@ Result PS_GetLocalFriendCodeSeed(u64* seed)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
cmdbuf[0] = 0x000A0000;
|
||||
|
||||
|
||||
if((ret = svcSendSyncRequest(psHandle))!=0)return ret;
|
||||
|
||||
*seed = (u64)cmdbuf[2] | (u64)cmdbuf[3] << 32;
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
|
||||
@ -89,12 +92,12 @@ Result PS_GetDeviceId(u32* device_id)
|
||||
{
|
||||
Result ret = 0;
|
||||
u32 *cmdbuf = getThreadCommandBuffer();
|
||||
|
||||
|
||||
cmdbuf[0] = 0x000B0000;
|
||||
|
||||
|
||||
if((ret = svcSendSyncRequest(psHandle))!=0)return ret;
|
||||
|
||||
*device_id = cmdbuf[2];
|
||||
|
||||
|
||||
return (Result)cmdbuf[1];
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/ptm.h>
|
||||
|
||||
|
||||
static Handle ptmHandle;
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/svc.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/services/soc.h>
|
||||
|
||||
extern Handle SOCU_handle;
|
||||
extern int SOCU_errno;
|
||||
|
@ -54,23 +54,20 @@ int inet_aton(const char *cp, struct in_addr *inp)
|
||||
|
||||
switch(num_bytes) {
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
if(val > 0xFFFFFF) return 0;
|
||||
val |= bytes[0] << 24;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 2:
|
||||
if(val > 0xFFFF) return 0;
|
||||
val |= bytes[0] << 24;
|
||||
val |= bytes[1] << 16;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
if(val > 0xFF) return 0;
|
||||
val |= bytes[0] << 24;
|
||||
val |= bytes[1] << 16;
|
||||
|
@ -3,7 +3,9 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/svc.h>
|
||||
|
||||
|
||||
/*
|
||||
|
@ -100,7 +100,7 @@ svcSignalEvent:
|
||||
svcClearEvent:
|
||||
svc 0x19
|
||||
bx lr
|
||||
|
||||
|
||||
.global svcCreateTimer
|
||||
.type svcCreateTimer, %function
|
||||
svcCreateTimer:
|
||||
@ -109,19 +109,19 @@ svcCreateTimer:
|
||||
ldr r2, [sp], #4
|
||||
str r1, [r2]
|
||||
bx lr
|
||||
|
||||
|
||||
.global svcSetTimer
|
||||
.type svcSetTimer, %function
|
||||
svcSetTimer:
|
||||
svc 0x1B
|
||||
bx lr
|
||||
|
||||
|
||||
.global svcCancelTimer
|
||||
.type svcCancelTimer, %function
|
||||
svcCancelTimer:
|
||||
svc 0x1C
|
||||
bx lr
|
||||
|
||||
|
||||
.global svcClearTimer
|
||||
.type svcClearTimer, %function
|
||||
svcClearTimer:
|
||||
@ -259,10 +259,7 @@ svcGetProcessId:
|
||||
.global svcOutputDebugString
|
||||
.type svcOutputDebugString, %function
|
||||
svcOutputDebugString:
|
||||
str r0, [sp, #-0x4]!
|
||||
svc 0x3D
|
||||
ldr r2, [sp], #4
|
||||
str r1, [r2]
|
||||
bx lr
|
||||
|
||||
.global svcCreateSemaphore
|
||||
|
Loading…
Reference in New Issue
Block a user