Merge branch 'master' of github.com:smealum/ctrulib

This commit is contained in:
smea 2015-09-26 17:03:46 -07:00
commit c6192c331b
40 changed files with 2510 additions and 107 deletions

View File

@ -0,0 +1,7 @@
SUBDIRS:= `ls | egrep -v '^(CVS)$$'`
all:
@for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i || { exit 1;} fi; done;
clean:
@for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i clean || { exit 1;} fi; done;
install:
@for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i install || { exit 1;} fi; done;

View File

@ -164,7 +164,7 @@ $(OUTPUT).elf : $(OFILES)
@echo $(notdir $<)
$(eval CURBIN := $(patsubst %.pica,%.shbin,$(notdir $<)))
$(eval CURH := $(patsubst %.pica,%.psh.h,$(notdir $<)))
@picasso $(CURBIN) $< $(CURH)
@picasso -h $(CURH) -o $(CURBIN) $<
@bin2s $(CURBIN) | $(AS) -o $@
@echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h
@echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h

View File

@ -45,7 +45,7 @@ void gpuFrameBegin(void)
// Configure some boilerplate
GPU_SetFaceCulling(GPU_CULL_BACK_CCW);
GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00);
GPU_SetStencilOp(GPU_KEEP, GPU_KEEP, GPU_KEEP);
GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP);
GPU_SetBlendingColor(0,0,0,0);
GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL);

View File

@ -83,7 +83,7 @@ static void sceneRender(void)
GPU_SetFloatUniformMatrix(GPU_GEOMETRY_SHADER, uLoc_projection, &projection);
// Draw the VBO - GPU_UNKPRIM allows the geoshader to control primitive emission
GPU_DrawArray(GPU_UNKPRIM, vertex_list_count);
GPU_DrawArray(GPU_UNKPRIM, 0, vertex_list_count);
}
static void sceneExit(void)

View File

@ -164,7 +164,7 @@ $(OUTPUT).elf : $(OFILES)
@echo $(notdir $<)
$(eval CURBIN := $(patsubst %.pica,%.shbin,$(notdir $<)))
$(eval CURH := $(patsubst %.pica,%.psh.h,$(notdir $<)))
@picasso $(CURBIN) $< $(CURH)
@picasso -h $(CURH) -o $(CURBIN) $<
@bin2s $(CURBIN) | $(AS) -o $@
@echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h
@echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h

View File

@ -45,7 +45,7 @@ void gpuFrameBegin(void)
// Configure some boilerplate
GPU_SetFaceCulling(GPU_CULL_BACK_CCW);
GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00);
GPU_SetStencilOp(GPU_KEEP, GPU_KEEP, GPU_KEEP);
GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP);
GPU_SetBlendingColor(0,0,0,0);
GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL);

View File

@ -76,7 +76,7 @@ static void sceneRender(void)
GPU_SetFloatUniformMatrix(GPU_VERTEX_SHADER, uLoc_projection, &projection);
// Draw the VBO
GPU_DrawArray(GPU_TRIANGLES, vertex_list_count);
GPU_DrawArray(GPU_TRIANGLES, 0, vertex_list_count);
}
static void sceneExit(void)

View File

@ -164,7 +164,7 @@ $(OUTPUT).elf : $(OFILES)
@echo $(notdir $<)
$(eval CURBIN := $(patsubst %.pica,%.shbin,$(notdir $<)))
$(eval CURH := $(patsubst %.pica,%.psh.h,$(notdir $<)))
@picasso $(CURBIN) $< $(CURH)
@picasso -h $(CURH) -o $(CURBIN) $<
@bin2s $(CURBIN) | $(AS) -o $@
@echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h
@echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h

View File

@ -45,7 +45,7 @@ void gpuFrameBegin(void)
// Configure some boilerplate
GPU_SetFaceCulling(GPU_CULL_BACK_CCW);
GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00);
GPU_SetStencilOp(GPU_KEEP, GPU_KEEP, GPU_KEEP);
GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP);
GPU_SetBlendingColor(0,0,0,0);
GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL);

View File

@ -186,7 +186,7 @@ static void sceneRender(void)
GPU_SetFloatUniform(GPU_VERTEX_SHADER, uLoc_lightClr, (u32*)(float[]){1.0f, 1.0f, 1.0f, 1.0f}, 1);
// Draw the VBO
GPU_DrawArray(GPU_TRIANGLES, vertex_list_count);
GPU_DrawArray(GPU_TRIANGLES, 0, vertex_list_count);
}
static void sceneExit(void)

181
examples/romfs/Makefile Normal file
View File

@ -0,0 +1,181 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
TOPDIR ?= $(CURDIR)
include $(DEVKITARM)/3ds_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
#
# NO_SMDH: if set to anything, no SMDH file is generated.
# ROMFS is the directory which contains the RomFS, relative to the Makefile (Optional)
# APP_TITLE is the name of the app stored in the SMDH file (Optional)
# APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional)
# APP_AUTHOR is the author of the app stored in the SMDH file (Optional)
# ICON is the filename of the icon (.png), relative to the project folder.
# If not set, it attempts to use one of the following (in this order):
# - <Project name>.png
# - icon.png
# - <libctru folder>/default_icon.png
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
DATA := data
INCLUDES := include
ROMFS := romfs
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard
CFLAGS := -g -Wall -O2 -mword-relocations \
-fomit-frame-pointer -ffast-math \
$(ARCH)
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -lctru -lm
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(CTRULIB)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.png)
ifneq (,$(findstring $(TARGET).png,$(icons)))
export APP_ICON := $(TOPDIR)/$(TARGET).png
else
ifneq (,$(findstring icon.png,$(icons)))
export APP_ICON := $(TOPDIR)/icon.png
endif
endif
else
export APP_ICON := $(TOPDIR)/$(ICON)
endif
ifeq ($(strip $(NO_SMDH)),)
export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh
endif
ifneq ($(ROMFS),)
export _3DSXFLAGS += --romfs=$(CURDIR)/$(ROMFS)
endif
.PHONY: $(BUILD) clean all
#---------------------------------------------------------------------------------
all: $(BUILD)
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
ifeq ($(strip $(NO_SMDH)),)
$(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh
else
$(OUTPUT).3dsx : $(OUTPUT).elf
endif
$(OUTPUT).elf : $(OFILES)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
# WARNING: This is not the right way to do this! TODO: Do it right!
#---------------------------------------------------------------------------------
%.vsh.o : %.vsh
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@python $(AEMSTRO)/aemstro_as.py $< ../$(notdir $<).shbin
@bin2s ../$(notdir $<).shbin | $(PREFIX)as -o $@
@echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h
@echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h
@echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h
@rm ../$(notdir $<).shbin
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -0,0 +1,6 @@
Hello, this is the libctru romfs example.
This text is being read off a file in romfs.
>>3DS Homebrew is Cool<<
Signed off, fincs

View File

@ -0,0 +1,2 @@
The path to this file contains UTF-16
characters that fall outside ASCII.

View File

@ -0,0 +1,58 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <3ds.h>
void printfile(const char* path)
{
FILE* f = fopen(path, "r");
if (f)
{
char mystring[100];
while (fgets(mystring, sizeof(mystring), f))
{
int a = strlen(mystring);
if (mystring[a-1] == '\n')
{
mystring[a-1] = 0;
if (mystring[a-2] == '\r')
mystring[a-2] = 0;
}
puts(mystring);
}
printf(">>EOF<<\n");
fclose(f);
}
}
int main()
{
gfxInitDefault();
consoleInit(GFX_TOP, NULL);
Result rc = romfsInit();
if (rc)
printf("romfsInit: %08lX\n", rc);
else
{
printf("romfs Init Successful!\n");
printfile("folder/file.txt");
// Test reading a file with non-ASCII characters in the name
printfile("フォルダ/ファイル.txt");
}
// Main loop
while (aptMainLoop())
{
gspWaitForVBlank();
hidScanInput();
u32 kDown = hidKeysDown();
if (kDown & KEY_START)
break; // break in order to return to hbmenu
}
romfsExit();
gfxExit();
return 0;
}

View File

@ -113,7 +113,7 @@ dist: dist-src dist-bin
install: dist-bin
mkdir -p $(DEVKITPRO)/libctru
bzip2 -cd libctru-$(VERSION).tar.bz2 | tar -x -C $(DEVKITPRO)/libctru
bzip2 -cd libctru-$(VERSION).tar.bz2 | tar -xf - -C $(DEVKITPRO)/libctru
dox:
@doxygen Doxyfile

View File

@ -18,6 +18,7 @@ extern "C" {
#include <3ds/services/ac.h>
#include <3ds/services/am.h>
#include <3ds/services/apt.h>
#include <3ds/services/cam.h>
#include <3ds/services/cfgnor.h>
#include <3ds/services/cfgu.h>
#include <3ds/services/csnd.h>
@ -45,6 +46,7 @@ extern "C" {
#include <3ds/gpu/shaderProgram.h>
#include <3ds/sdmc.h>
#include <3ds/romfs.h>
#ifdef __cplusplus
}
@ -109,4 +111,4 @@ extern "C" {
* @example threads/event/source/main.c
* @example time/rtc/source/main.c
*/

View File

@ -33,6 +33,9 @@ void GPUCMD_Finalize();
#define GPU_TEXTURE_WRAP_S(v) (((v)&0x3)<<12) //takes a GPU_TEXTURE_WRAP_PARAM
#define GPU_TEXTURE_WRAP_T(v) (((v)&0x3)<<8) //takes a GPU_TEXTURE_WRAP_PARAM
// Combiner buffer write config
#define GPU_TEV_BUFFER_WRITE_CONFIG(stage0, stage1, stage2, stage3) (stage0 | (stage1 << 1) | (stage2 << 2) | (stage3 << 3))
typedef enum
{
GPU_NEAREST = 0x0,
@ -93,10 +96,14 @@ typedef enum
typedef enum
{
GPU_KEEP = 0, // keep destination value
GPU_AND_NOT = 1, // destination & ~source
GPU_XOR = 5, // destination ^ source
// 2 is the same as 1. Other values are too weird to even be usable.
GPU_STENCIL_KEEP = 0, // old_stencil
GPU_STENCIL_ZERO = 1, // 0
GPU_STENCIL_REPLACE = 2, // ref
GPU_STENCIL_INCR = 3, // old_stencil + 1 saturated to [0, 255]
GPU_STENCIL_DECR = 4, // old_stencil - 1 saturated to [0, 255]
GPU_STENCIL_INVERT = 5, // ~old_stencil
GPU_STENCIL_INCR_WRAP = 6, // old_stencil + 1
GPU_STENCIL_DECR_WRAP = 7 // old_stencil - 1
} GPU_STENCILOP;
typedef enum
@ -184,6 +191,7 @@ typedef enum{
GPU_TEXTURE1 = 0x04,
GPU_TEXTURE2 = 0x05,
GPU_TEXTURE3 = 0x06,
GPU_PREVIOUS_BUFFER = 0x0D,
GPU_CONSTANT = 0x0E,
GPU_PREVIOUS = 0x0F,
}GPU_TEVSRC;
@ -259,9 +267,11 @@ void GPU_SetScissorTest(GPU_SCISSORMODE mode, u32 x, u32 y, u32 w, u32 h);
void GPU_DepthMap(float zScale, float zOffset);
void GPU_SetAlphaTest(bool enable, GPU_TESTFUNC function, u8 ref);
void GPU_SetDepthTestAndWriteMask(bool enable, GPU_TESTFUNC function, GPU_WRITEMASK writemask); // GPU_WRITEMASK values can be ORed together
void GPU_SetStencilTest(bool enable, GPU_TESTFUNC function, u8 ref, u8 mask, u8 replace);
void GPU_SetStencilTest(bool enable, GPU_TESTFUNC function, u8 ref, u8 input_mask, u8 write_mask);
void GPU_SetStencilOp(GPU_STENCILOP sfail, GPU_STENCILOP dfail, GPU_STENCILOP pass);
void GPU_SetFaceCulling(GPU_CULLMODE mode);
// Only the first four tev stages can write to the combiner buffer, use GPU_TEV_BUFFER_WRITE_CONFIG to build the parameters
void GPU_SetCombinerBufferWrite(u8 rgb_config, u8 alpha_config);
// these two can't be used together
void GPU_SetAlphaBlending(GPU_BLENDEQUATION colorEquation, GPU_BLENDEQUATION alphaEquation,
@ -281,10 +291,10 @@ void GPU_SetTexture(GPU_TEXUNIT unit, u32* data, u16 width, u16 height, u32 para
/**
* @param borderColor The color used for the border when using the @ref GPU_CLAMP_TO_BORDER wrap mode
*/
void GPU_SetTextureBorderColor(GPU_TEXUNIT unit,u32 borderColor);
void GPU_SetTextureBorderColor(GPU_TEXUNIT unit,u32 borderColor);
void GPU_SetTexEnv(u8 id, u16 rgbSources, u16 alphaSources, u16 rgbOperands, u16 alphaOperands, GPU_COMBINEFUNC rgbCombine, GPU_COMBINEFUNC alphaCombine, u32 constantColor);
void GPU_DrawArray(GPU_Primitive_t primitive, u32 n);
void GPU_DrawArray(GPU_Primitive_t primitive, u32 first, u32 count);
void GPU_DrawElements(GPU_Primitive_t primitive, u32* indexArray, u32 n);
void GPU_FinishDrawing();

View File

@ -224,7 +224,7 @@
#define GPUREG_00DD 0x00DD
#define GPUREG_00DE 0x00DE
#define GPUREG_00DF 0x00DF
#define GPUREG_00E0 0x00E0
#define GPUREG_TEXENV_BUFFER_CONFIG 0x00E0
#define GPUREG_00E1 0x00E1
#define GPUREG_00E2 0x00E2
#define GPUREG_00E3 0x00E3
@ -253,7 +253,7 @@
#define GPUREG_TEXENV5_CONFIG2 0x00FA
#define GPUREG_TEXENV5_CONFIG3 0x00FB
#define GPUREG_TEXENV5_CONFIG4 0x00FC
#define GPUREG_00FD 0x00FD
#define GPUREG_TEXENV_BUFFER_COLOR 0x00FD
#define GPUREG_00FE 0x00FE
#define GPUREG_00FF 0x00FF
#define GPUREG_COLOROUTPUT_CONFIG 0x0100
@ -554,7 +554,7 @@
#define GPUREG_INDEXBUFFER_CONFIG 0x0227
#define GPUREG_NUMVERTICES 0x0228
#define GPUREG_GEOSTAGE_CONFIG 0x0229
#define GPUREG_022A 0x022A
#define GPUREG_DRAW_VERTEX_OFFSET 0x022A
#define GPUREG_022B 0x022B
#define GPUREG_022C 0x022C
#define GPUREG_022D 0x022D

View File

@ -0,0 +1,35 @@
#pragma once
#include <3ds/types.h>
typedef struct
{
u32 headerSize;
u32 dirHashTableOff, dirHashTableSize;
u32 dirTableOff, dirTableSize;
u32 fileHashTableOff, fileHashTableSize;
u32 fileTableOff, fileTableSize;
u32 fileDataOff;
} romfs_header;
typedef struct
{
u32 parent, sibling;
u32 childDir, childFile;
u32 nextHash;
u32 nameLen;
u16 name[];
} romfs_dir;
typedef struct
{
u32 parent, sibling;
u64 dataOff, dataSize;
u32 nextHash;
u32 nameLen;
u16 name[];
} romfs_file;
Result romfsInit(void);
Result romfsInitFromFile(Handle file, u32 offset);
Result romfsExit(void);

View File

@ -12,8 +12,11 @@ typedef enum{
APPID_WEB = 0x114, // Internet Browser
APPID_INSTRUCTION_MANUAL = 0x115, // Instruction Manual applet
APPID_NOTIFICATIONS = 0x116, // Notifications applet
APPID_MIIVERSE = 0x117, // Miiverse applet
APPID_MIIVERSE = 0x117, // Miiverse applet (olv)
APPID_MIIVERSE_POSTING = 0x118, // Miiverse posting applet (solv3)
APPID_AMIIBO_SETTINGS = 0x119, // Amiibo settings applet (cabinet)
APPID_APPLICATION = 0x300, // Application
APPID_ESHOP = 0x301, // eShop (tiger)
APPID_SOFTWARE_KEYBOARD = 0x401, // Software Keyboard
APPID_APPLETED = 0x402, // appletEd
APPID_PNOTE_AP = 0x404, // PNOTE_AP
@ -94,6 +97,7 @@ Result APT_Finalize(Handle* handle, NS_APPID appId);
Result APT_HardwareResetAsync(Handle* handle);
Result APT_Enable(Handle* handle, u32 a);
Result APT_GetAppletManInfo(Handle* handle, u8 inval, u8 *outval8, u32 *outval32, NS_APPID *menu_appid, NS_APPID *active_appid);
Result APT_GetAppletProgramInfo(Handle* handle, u32 id, u32 flags, u16 *titleversion);
Result APT_PrepareToJumpToHomeMenu(Handle* handle);
Result APT_JumpToHomeMenu(Handle* handle, u32 a, u32 b, u32 c);
Result APT_PrepareToJumpToApplication(Handle* handle, u32 a);

View File

@ -0,0 +1,570 @@
/**
* @file cam.h
* @brief CAM service for using the 3DS's front and back cameras.
*/
#pragma once
#include <3ds/services/y2r.h>
#include <3ds/types.h>
/**
* @brief Camera connection target ports.
*/
typedef enum {
PORT_NONE = 0x0,
PORT_CAM1 = BIT(0),
PORT_CAM2 = BIT(1),
// Port combinations.
PORT_BOTH = PORT_CAM1 | PORT_CAM2,
} CAMU_Port;
/**
* @brief Camera combinations.
*/
typedef enum {
SELECT_NONE = 0x0,
SELECT_OUT1 = BIT(0),
SELECT_IN1 = BIT(1),
SELECT_OUT2 = BIT(2),
// Camera combinations.
SELECT_IN1_OUT1 = SELECT_OUT1 | SELECT_IN1,
SELECT_OUT1_OUT2 = SELECT_OUT1 | SELECT_OUT2,
SELECT_IN1_OUT2 = SELECT_IN1 | SELECT_OUT2,
SELECT_ALL = SELECT_OUT1 | SELECT_IN1 | SELECT_OUT2,
} CAMU_CameraSelect;
/**
* @brief Camera contexts.
*/
typedef enum {
CONTEXT_NONE = 0x0,
CONTEXT_A = BIT(0),
CONTEXT_B = BIT(1),
// Context combinations.
CONTEXT_BOTH = CONTEXT_A | CONTEXT_B,
} CAMU_Context;
/**
* @brief Ways to flip the camera image.
*/
typedef enum {
FLIP_NONE = 0x0,
FLIP_HORIZONTAL = 0x1,
FLIP_VERTICAL = 0x2,
FLIP_REVERSE = 0x3,
} CAMU_Flip;
/**
* @brief Camera image resolutions.
*/
typedef enum {
SIZE_VGA = 0x0,
SIZE_QVGA = 0x1,
SIZE_QQVGA = 0x2,
SIZE_CIF = 0x3,
SIZE_QCIF = 0x4,
SIZE_DS_LCD = 0x5,
SIZE_DS_LCDx4 = 0x6,
SIZE_CTR_TOP_LCD = 0x7,
// Alias for bottom screen to match top screen naming.
SIZE_CTR_BOTTOM_LCD = SIZE_QVGA,
} CAMU_Size;
/**
* @brief Camera capture frame rates.
*/
typedef enum {
FRAME_RATE_15 = 0x0,
FRAME_RATE_15_TO_5 = 0x1,
FRAME_RATE_15_TO_2 = 0x2,
FRAME_RATE_10 = 0x3,
FRAME_RATE_8_5 = 0x4,
FRAME_RATE_5 = 0x5,
FRAME_RATE_20 = 0x6,
FRAME_RATE_20_TO_5 = 0x7,
FRAME_RATE_30 = 0x8,
FRAME_RATE_30_TO_5 = 0x9,
FRAME_RATE_15_TO_10 = 0xA,
FRAME_RATE_20_TO_10 = 0xB,
FRAME_RATE_30_TO_10 = 0xC,
} CAMU_FrameRate;
/**
* @brief Camera white balance modes.
*/
typedef enum {
WHITE_BALANCE_AUTO = 0x0,
WHITE_BALANCE_3200K = 0x1,
WHITE_BALANCE_4150K = 0x2,
WHITE_BALANCE_5200K = 0x3,
WHITE_BALANCE_6000K = 0x4,
WHITE_BALANCE_7000K = 0x5,
WHITE_BALANCE_MAX = 0x6,
// White balance aliases.
WHITE_BALANCE_NORMAL = WHITE_BALANCE_AUTO,
WHITE_BALANCE_TUNGSTEN = WHITE_BALANCE_3200K,
WHITE_BALANCE_WHITE_FLUORESCENT_LIGHT = WHITE_BALANCE_4150K,
WHITE_BALANCE_DAYLIGHT = WHITE_BALANCE_5200K,
WHITE_BALANCE_CLOUDY = WHITE_BALANCE_6000K,
WHITE_BALANCE_HORIZON = WHITE_BALANCE_6000K,
WHITE_BALANCE_SHADE = WHITE_BALANCE_7000K,
} CAMU_WhiteBalance;
/**
* @brief Camera photo modes.
*/
typedef enum {
PHOTO_MODE_NORMAL = 0x0,
PHOTO_MODE_PORTRAIT = 0x1,
PHOTO_MODE_LANDSCAPE = 0x2,
PHOTO_MODE_NIGHTVIEW = 0x3,
PHOTO_MODE_LETTER = 0x4,
} CAMU_PhotoMode;
/**
* @brief Camera special effects.
*/
typedef enum {
EFFECT_NONE = 0x0,
EFFECT_MONO = 0x1,
EFFECT_SEPIA = 0x2,
EFFECT_NEGATIVE = 0x3,
EFFECT_NEGAFILM = 0x4,
EFFECT_SEPIA01 = 0x5,
} CAMU_Effect;
/**
* @brief Camera contrast patterns.
*/
typedef enum {
CONTRAST_PATTERN_01 = 0x0,
CONTRAST_PATTERN_02 = 0x1,
CONTRAST_PATTERN_03 = 0x2,
CONTRAST_PATTERN_04 = 0x3,
CONTRAST_PATTERN_05 = 0x4,
CONTRAST_PATTERN_06 = 0x5,
CONTRAST_PATTERN_07 = 0x6,
CONTRAST_PATTERN_08 = 0x7,
CONTRAST_PATTERN_09 = 0x8,
CONTRAST_PATTERN_10 = 0x9,
CONTRAST_PATTERN_11 = 0xA,
// Contrast aliases.
CONTRAST_LOW = CONTRAST_PATTERN_05,
CONTRAST_NORMAL = CONTRAST_PATTERN_06,
CONTRAST_HIGH = CONTRAST_PATTERN_07,
} CAMU_Contrast;
/**
* @brief Camera lens correction modes.
*/
typedef enum {
LENS_CORRECTION_OFF = 0x0,
LENS_CORRECTION_ON_70 = 0x1,
LENS_CORRECTION_ON_90 = 0x2,
// Lens correction aliases.
LENS_CORRECTION_DARK = LENS_CORRECTION_OFF,
LENS_CORRECTION_NORMAL = LENS_CORRECTION_ON_70,
LENS_CORRECTION_BRIGHT = LENS_CORRECTION_ON_90,
} CAMU_LensCorrection;
/**
* @brief Camera image output formats.
*/
typedef enum {
OUTPUT_YUV_422 = 0x0,
OUTPUT_RGB_565 = 0x1,
} CAMU_OutputFormat;
/**
* @brief Camera shutter sounds.
*/
typedef enum {
SHUTTER_SOUND_TYPE_NORMAL = 0x0,
SHUTTER_SOUND_TYPE_MOVIE = 0x1,
SHUTTER_SOUND_TYPE_MOVIE_END = 0x2,
} CAMU_ShutterSoundType;
/**
* @brief Image quality calibration data.
*/
typedef struct {
s16 aeBaseTarget; ///< Auto exposure base target brightness.
s16 kRL; ///< Left color correction matrix red normalization coefficient.
s16 kGL; ///< Left color correction matrix green normalization coefficient.
s16 kBL; ///< Left color correction matrix blue normalization coefficient.
s16 ccmPosition; ///< Color correction matrix position.
u16 awbCcmL9Right; ///< Right camera, left color correction matrix red/green gain.
u16 awbCcmL9Left; ///< Left camera, left color correction matrix red/green gain.
u16 awbCcmL10Right; ///< Right camera, left color correction matrix blue/green gain.
u16 awbCcmL10Left; ///< Left camera, left color correction matrix blue/green gain.
u16 awbX0Right; ///< Right camera, color correction matrix position threshold.
u16 awbX0Left; ///< Left camera, color correction matrix position threshold.
} CAMU_ImageQualityCalibrationData;
/**
* @brief Stereo camera calibration data.
*/
typedef struct {
u8 isValidRotationXY; ///< #bool Whether the X and Y rotation data is valid.
u8 padding[3]; ///< Padding. (Aligns isValidRotationXY to 4 bytes)
float scale; ///< Scale to match the left camera image with the right.
float rotationZ; ///< Z axis rotation to match the left camera image with the right.
float translationX; ///< X axis translation to match the left camera image with the right.
float translationY; ///< Y axis translation to match the left camera image with the right.
float rotationX; ///< X axis rotation to match the left camera image with the right.
float rotationY; ///< Y axis rotation to match the left camera image with the right.
float angleOfViewRight; ///< Right camera angle of view.
float angleOfViewLeft; ///< Left camera angle of view.
float distanceToChart; ///< Distance between cameras and measurement chart.
float distanceCameras; ///< Distance between left and right cameras.
s16 imageWidth; ///< Image width.
s16 imageHeight; ///< Image height.
u8 reserved[16]; ///< Reserved for future use. (unused)
} CAMU_StereoCameraCalibrationData;
/**
* @brief Batch camera configuration for use without a context.
*/
typedef struct {
u8 camera; ///< #CAMU_CameraSelect Selected camera.
s8 exposure; ///< Camera exposure.
u8 whiteBalance; ///< #CAMU_WhiteBalance Camera white balance.
s8 sharpness; ///< Camera sharpness.
u8 autoExposureOn; ///< #bool Whether to automatically determine the proper exposure.
u8 autoWhiteBalanceOn; ///< #bool Whether to automatically determine the white balance mode.
u8 frameRate; ///< #CAMU_FrameRate Camera frame rate.
u8 photoMode; ///< #CAMU_PhotoMode Camera photo mode.
u8 contrast; ///< #CAMU_Contrast Camera contrast.
u8 lensCorrection; ///< #CAMU_LensCorrection Camera lens correction.
u8 noiseFilterOn; ///< #bool Whether to enable the camera's noise filter.
u8 padding; ///< Padding. (Aligns last 3 fields to 4 bytes)
s16 autoExposureWindowX; ///< X of the region to use for auto exposure.
s16 autoExposureWindowY; ///< Y of the region to use for auto exposure.
s16 autoExposureWindowWidth; ///< Width of the region to use for auto exposure.
s16 autoExposureWindowHeight; ///< Height of the region to use for auto exposure.
s16 autoWhiteBalanceWindowX; ///< X of the region to use for auto white balance.
s16 autoWhiteBalanceWindowY; ///< Y of the region to use for auto white balance.
s16 autoWhiteBalanceWindowWidth; ///< Width of the region to use for auto white balance.
s16 autoWhiteBalanceWindowHeight; ///< Height of the region to use for auto white balance.
} CAMU_PackageParameterCameraSelect;
/**
* @brief Batch camera configuration for use with a context.
*/
typedef struct {
u8 camera; ///< #CAMU_CameraSelect Selected camera.
u8 context; ///< #CAMU_Context Selected context.
u8 flip; ///< #CAMU_Flip Camera image flip mode.
u8 effect; ///< #CAMU_Effect Camera image special effects.
u8 size; ///< #CAMU_Size Camera image resolution.
} CAMU_PackageParameterContext;
/**
* @brief Batch camera configuration for use with a context and with detailed size information.
*/
typedef struct {
u8 camera; ///< #CAMU_CameraSelect Selected camera.
u8 context; ///< #CAMU_Context Selected context.
u8 flip; ///< #CAMU_Flip Camera image flip mode.
u8 effect; ///< #CAMU_Effect Camera image special effects.
s16 width; ///< Image width.
s16 height; ///< Image height.
s16 cropX0; ///< First crop point X.
s16 cropY0; ///< First crop point Y.
s16 cropX1; ///< Second crop point X.
s16 cropY1; ///< Second crop point Y.
} CAMU_PackageParameterContextDetail;
/**
* @brief Initializes the cam service.
*
* This will internally get the handle of the service, and on success call CAMU_DriverInitialize.
*/
Result camInit();
/**
* @brief Closes the cam service.
*
* This will internally call CAMU_DriverFinalize and close the handle of the service.
*/
Result camExit();
/// Begins capture on the specified camera port.
Result CAMU_StartCapture(CAMU_Port port);
///Terminates capture on the specified camera port.
Result CAMU_StopCapture(CAMU_Port port);
/**
* @brief Gets whether the specified camera port is busy.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_IsBusy(bool* busy, CAMU_Port port);
///Clears the buffer and error flags of the specified camera port.
Result CAMU_ClearBuffer(CAMU_Port port);
/**
* @brief Gets a handle to the event signaled on vsync interrupts.
*
* Writes the event handle to the provided output pointer.
*/
Result CAMU_GetVsyncInterruptEvent(Handle* event, CAMU_Port port);
/**
* @brief Gets a handle to the event signaled on camera buffer errors.
*
* Writes the event handle to the provided output pointer.
*/
Result CAMU_GetBufferErrorInterruptEvent(Handle* event, CAMU_Port port);
/**
* @brief Initiates the process of receiving a camera frame.
*
* Writes a completion event handle to the provided pointer and writes image data to the provided buffer.
*/
Result CAMU_SetReceiving(Handle* event, void* dst, CAMU_Port port, u32 imageSize, s16 transferUnit);
/**
* @brief Gets whether the specified camera port has finished receiving image data.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_IsFinishedReceiving(bool* finishedReceiving, CAMU_Port port);
///Sets the number of lines to transfer into an image buffer.
Result CAMU_SetTransferLines(CAMU_Port port, s16 lines, s16 width, s16 height);
/**
* @brief Gets the maximum number of lines that can be saved to an image buffer.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_GetMaxLines(s16* maxLines, s16 width, s16 height);
///Sets the number of bytes to transfer into an image buffer.
Result CAMU_SetTransferBytes(CAMU_Port port, u32 bytes, s16 width, s16 height);
/**
* @brief Gets the number of bytes to transfer into an image buffer.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_GetTransferBytes(u32* transferBytes, CAMU_Port port);
/**
* @brief Gets the maximum number of bytes that can be saved to an image buffer.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_GetMaxBytes(u32* maxBytes, s16 width, s16 height);
///Sets whether image trimming is enabled.
Result CAMU_SetTrimming(CAMU_Port port, bool trimming);
/**
* @brief Gets whether image trimming is enabled.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_IsTrimming(bool* trimming, CAMU_Port port);
///Sets the parameters used for trimming images.
Result CAMU_SetTrimmingParams(CAMU_Port port, s16 xStart, s16 yStart, s16 xEnd, s16 yEnd);
/**
* @brief Gets the parameters used for trimming images.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_GetTrimmingParams(s16* xStart, s16* yStart, s16* xEnd, s16* yEnd, CAMU_Port port);
///Sets the parameters used for trimming images, relative to the center of the image.
Result CAMU_SetTrimmingParamsCenter(CAMU_Port port, s16 trimWidth, s16 trimHeight, s16 camWidth, s16 camHeight);
///Activates the specified camera.
Result CAMU_Activate(CAMU_CameraSelect select);
///Switches the specified camera's active context.
Result CAMU_SwitchContext(CAMU_CameraSelect select, CAMU_Context context);
///Sets the exposure value of the specified camera.
Result CAMU_SetExposure(CAMU_CameraSelect select, s8 exposure);
///Sets the white balance mode of the specified camera.
Result CAMU_SetWhiteBalance(CAMU_CameraSelect select, CAMU_WhiteBalance whiteBalance);
/**
* @brief Sets the white balance mode of the specified camera.
*
* TODO: Explain "without base up"?
*/
Result CAMU_SetWhiteBalanceWithoutBaseUp(CAMU_CameraSelect select, CAMU_WhiteBalance whiteBalance);
///Sets the sharpness of the specified camera.
Result CAMU_SetSharpness(CAMU_CameraSelect select, s8 sharpness);
///Sets whether auto exposure is enabled on the specified camera.
Result CAMU_SetAutoExposure(CAMU_CameraSelect select, bool autoExposure);
/**
* @brief Gets whether auto exposure is enabled on the specified camera.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_IsAutoExposure(bool* autoExposure, CAMU_CameraSelect select);
///Sets whether auto white balance is enabled on the specified camera.
Result CAMU_SetAutoWhiteBalance(CAMU_CameraSelect select, bool autoWhiteBalance);
/**
* @brief Gets whether auto white balance is enabled on the specified camera.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_IsAutoWhiteBalance(bool* autoWhiteBalance, CAMU_CameraSelect select);
///Flips the image of the specified camera in the specified context.
Result CAMU_FlipImage(CAMU_CameraSelect select, CAMU_Flip flip, CAMU_Context context);
///Sets the image resolution of the given camera in the given context, in detail.
Result CAMU_SetDetailSize(CAMU_CameraSelect select, s16 width, s16 height, s16 cropX0, s16 cropY0, s16 cropX1, s16 cropY1, CAMU_Context context);
///Sets the image resolution of the given camera in the given context.
Result CAMU_SetSize(CAMU_CameraSelect select, CAMU_Size size, CAMU_Context context);
///Sets the frame rate of the given camera.
Result CAMU_SetFrameRate(CAMU_CameraSelect select, CAMU_FrameRate frameRate);
///Sets the photo mode of the given camera.
Result CAMU_SetPhotoMode(CAMU_CameraSelect select, CAMU_PhotoMode photoMode);
///Sets the special effects of the given camera in the given context.
Result CAMU_SetEffect(CAMU_CameraSelect select, CAMU_Effect effect, CAMU_Context context);
///Sets the contrast mode of the given camera.
Result CAMU_SetContrast(CAMU_CameraSelect select, CAMU_Contrast contrast);
///Sets the lens correction mode of the given camera.
Result CAMU_SetLensCorrection(CAMU_CameraSelect select, CAMU_LensCorrection lensCorrection);
///Sets the output format of the given camera in the given context.
Result CAMU_SetOutputFormat(CAMU_CameraSelect select, CAMU_OutputFormat format, CAMU_Context context);
///Sets the region to base auto exposure off of for the specified camera.
Result CAMU_SetAutoExposureWindow(CAMU_CameraSelect select, s16 x, s16 y, s16 width, s16 height);
///Sets the region to base auto white balance off of for the specified camera.
Result CAMU_SetAutoWhiteBalanceWindow(CAMU_CameraSelect select, s16 x, s16 y, s16 width, s16 height);
///Sets whether the specified camera's noise filter is enabled.
Result CAMU_SetNoiseFilter(CAMU_CameraSelect select, bool noiseFilter);
///Synchronizes the specified cameras' vsync timing.
Result CAMU_SynchronizeVsyncTiming(CAMU_CameraSelect select1, CAMU_CameraSelect select2);
/**
* @brief Gets the vsync timing record of the specified camera for the specified number of signals.
*
* Writes the result to the provided output pointer, which should be of size "past * sizeof(s64)".
*/
Result CAMU_GetLatestVsyncTiming(s64* timing, CAMU_Port port, u32 past);
/**
* @brief Gets the specified camera's stereo camera calibration data.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_GetStereoCameraCalibrationData(CAMU_StereoCameraCalibrationData* data);
///Sets the specified camera's stereo camera calibration data.
Result CAMU_SetStereoCameraCalibrationData(CAMU_StereoCameraCalibrationData data);
/**
* @brief Writes to the specified I2C register of the specified camera.
*
* Use with caution.
*/
Result CAMU_WriteRegisterI2c(CAMU_CameraSelect select, u16 addr, u16 data);
/**
* @brief Writes to the specified MCU variable of the specified camera.
*
* Use with caution.
*/
Result CAMU_WriteMcuVariableI2c(CAMU_CameraSelect select, u16 addr, u16 data);
/**
* @brief Reads the specified I2C register of the specified camera.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_ReadRegisterI2cExclusive(u16* data, CAMU_CameraSelect select, u16 addr);
/**
* @brief Reads the specified MCU variable of the specified camera.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_ReadMcuVariableI2cExclusive(u16* data, CAMU_CameraSelect select, u16 addr);
/**
* @brief Sets the specified camera's image quality calibration data.
*/
Result CAMU_SetImageQualityCalibrationData(CAMU_ImageQualityCalibrationData data);
/**
* @brief Gets the specified camera's image quality calibration data.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_GetImageQualityCalibrationData(CAMU_ImageQualityCalibrationData* data);
///Configures a camera with pre-packaged configuration data without a context.
Result CAMU_SetPackageParameterWithoutContext(CAMU_PackageParameterCameraSelect param);
///Configures a camera with pre-packaged configuration data with a context.
Result CAMU_SetPackageParameterWithContext(CAMU_PackageParameterContext param);
///Configures a camera with pre-packaged configuration data without a context and extra resolution details.
Result CAMU_SetPackageParameterWithContextDetail(CAMU_PackageParameterContextDetail param);
///Gets the Y2R coefficient applied to image data by the camera.
Result CAMU_GetSuitableY2rStandardCoefficient(Y2R_StandardCoefficient* coefficient);
///Plays the specified shutter sound.
Result CAMU_PlayShutterSound(CAMU_ShutterSoundType sound);
///Initializes the camera driver.
Result CAMU_DriverInitialize();
///Finalizes the camera driver.
Result CAMU_DriverFinalize();
/**
* @brief Gets the current activated camera.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_GetActivatedCamera(CAMU_CameraSelect* select);
/**
* @brief Gets the current sleep camera.
*
* Writes the result to the provided output pointer.
*/
Result CAMU_GetSleepCamera(CAMU_CameraSelect* select);
///Sets the current sleep camera.
Result CAMU_SetSleepCamera(CAMU_CameraSelect select);
///Sets whether to enable synchronization of left and right camera brightnesses.
Result CAMU_SetBrightnessSynchronization(bool brightnessSynchronization);

View File

@ -23,7 +23,7 @@ Result httpcReceiveData(httpcContext *context, u8* buffer, u32 size);
Result httpcGetRequestState(httpcContext *context, httpcReqStatus* out);
Result httpcGetDownloadSizeState(httpcContext *context, u32* downloadedsize, u32* contentsize);
Result httpcGetResponseStatusCode(httpcContext *context, u32* out, u64 delay);//delay isn't used yet. This writes the HTTP status code from the server to out.
Result httpcGetResponseHeader(httpcContext *context, char* name, char* value, u32 valuebuf_maxsize);
Result httpcDownloadData(httpcContext *context, u8* buffer, u32 size, u32 *downloadedsize);//The *entire* content must be downloaded before using httpcCloseContext(), otherwise httpcCloseContext() will hang.
//Using the below functions directly is not recommended, use the above functions. See also the http example.
@ -38,5 +38,6 @@ Result HTTPC_BeginRequest(Handle handle, Handle contextHandle);
Result HTTPC_ReceiveData(Handle handle, Handle contextHandle, u8* buffer, u32 size);
Result HTTPC_GetRequestState(Handle handle, Handle contextHandle, httpcReqStatus* out);
Result HTTPC_GetDownloadSizeState(Handle handle, Handle contextHandle, u32* downloadedsize, u32* contentsize);
Result HTTPC_GetResponseHeader(Handle handle, Handle contextHandle, char* name, char* value, u32 valuebuf_maxsize);
Result HTTPC_GetResponseStatusCode(Handle handle, Handle contextHandle, u32* out);

View File

@ -17,10 +17,11 @@ typedef enum
ps_KEYSLOT_31,
ps_KEYSLOT_38,
ps_KEYSLOT_32,
ps_KEYSLOT_39,
ps_KEYSLOT_39_DLP,
ps_KEYSLOT_2E,
ps_KEYSLOT_INVALID,
ps_KEYSLOT_36
ps_KEYSLOT_36,
ps_KEYSLOT_39_NFC
} ps_aes_keytypes;
/*
@ -73,4 +74,4 @@ About: Gets a 32bit device id, it's used for some key slot inits
device_id ptr to where the device id is written to
*/
Result PS_GetDeviceId(u32* device_id);
Result PS_GetDeviceId(u32* device_id);

View File

@ -1,7 +1,23 @@
/**
* @file soc.h
* @brief SOC service for sockets communications
*
* After initializing this service you will be able to use system calls from netdb.h, sys/socket.h etc.
*/
#pragma once
Result SOC_Initialize(u32 *context_addr, u32 context_size);//Example context_size: 0x48000. The specified context buffer can no longer be accessed by the process which called this function, since the userland permissions for this block are set to no-access.
/**
* @brief Initializes the SOC service.
* @param context_addr Address of a page-aligned (0x1000) buffer to be used.
* @param context_size Size of the buffer, a multiple of 0x1000.
* @note The specified context buffer can no longer be accessed by the process which called this function, since the userland permissions for this block are set to no-access.
*/
Result SOC_Initialize(u32 *context_addr, u32 context_size);
/**
* @brief Closes the soc service.
* @note You need to call this in order to be able to use the buffer again.
*/
Result SOC_Shutdown(void);
/* this is supposed to be in unistd.h but newlib only puts it for cygwin */

View File

@ -265,11 +265,25 @@ Result svcControlMemory(u32* addr_out, u32 addr0, u32 addr1, u32 size, MemOp op,
*/
Result svcControlProcessMemory(Handle process, u32 addr0, u32 addr1, u32 size, u32 type, u32 perm);
/**
* @brief Creates a block of shared memory
* @param memblock Pointer to store the handle of the block
* @param addr Address of the memory to map, page-aligned. So its alignment must be 0x1000.
* @param size Size of the memory to map, a multiple of 0x1000.
* @param my_perm Memory permissions for the current process
* @param my_perm Memory permissions for the other processes
*
* @note The shared memory block, and its rights, are destroyed when the handle is closed.
*/
Result svcCreateMemoryBlock(Handle* memblock, u32 addr, u32 size, MemPerm my_perm, MemPerm other_perm);
Result svcMapMemoryBlock(Handle memblock, u32 addr, MemPerm my_perm, MemPerm other_perm);
Result svcMapProcessMemory(Handle process, u32 startAddr, u32 endAddr);
Result svcUnmapProcessMemory(Handle process, u32 startAddr, u32 endAddr);
Result svcUnmapMemoryBlock(Handle memblock, u32 addr);
Result svcStartInterProcessDma(Handle* dma, Handle dstProcess, void* dst, Handle srcProcess, const void* src, u32 size, void* dmaConfig);
Result svcStopDma(Handle dma);
Result svcGetDmaState(void* dmaState, Handle dma);
/**
* @brief Memory information query
* @param addr Virtual memory address
@ -280,6 +294,9 @@ Result svcQueryProcessMemory(MemInfo* info, PageInfo* out, Handle process, u32 a
Result svcCreateAddressArbiter(Handle *arbiter);
Result svcArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds);
Result svcInvalidateProcessDataCache(Handle process, void* addr, u32 size);
Result svcFlushProcessDataCache(Handle process, void const* addr, u32 size);
Result svcReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size);
Result svcWriteProcessMemory(Handle debug, const void* buffer, u32 addr, u32 size);
///@}
@ -295,6 +312,7 @@ Result svcWriteProcessMemory(Handle debug, const void* buffer, u32 addr, u32 siz
*/
Result svcOpenProcess(Handle* process, u32 processId);
void svcExitProcess() __attribute__((noreturn));
Result svcTerminateProcess(Handle process);
Result svcGetProcessInfo(s64* out, Handle process, u32 type);
Result svcGetProcessId(u32 *out, Handle handle);
@ -312,7 +330,7 @@ Result svcConnectToPort(volatile Handle* out, const char* portName);
* @param arg The argument passed to @p entrypoint
* @param stack_top The top of the thread's stack. Must be 0x8 bytes mem-aligned.
* @param thread_priority Low values gives the thread higher priority.
* For userland app, this has to be withing the range [0x18;0x3F]
* For userland apps, this has to be within the range [0x18;0x3F]
* @param processor_id The id of the processor the thread should be ran on. Those are labelled starting from 0.
* For old 3ds it has to be <2, and for new 3DS <4.
* Value -1 means all CPUs and -2 read from the Exheader.
@ -355,7 +373,7 @@ Result svcGetThreadPriority(s32 *out, Handle handle);
/**
* @brief Changes the priority of a thread
* @param prio For userland apps, this has to be withing the range [0x18;0x3F]
* @param prio For userland apps, this has to be within the range [0x18;0x3F]
*
* Low values gives the thread higher priority.
*/
@ -396,14 +414,20 @@ Result svcGetThreadInfo(s64* out, Handle thread, ThreadInfoType type);
///@{
Result svcCreateMutex(Handle* mutex, bool initially_locked);
Result svcReleaseMutex(Handle handle);
Result svcCreateSemaphore(Handle* semaphore, s32 initial_count, s32 max_count);
Result svcReleaseSemaphore(s32* count, Handle semaphore, s32 release_count);
Result svcCreateEvent(Handle* event, u8 reset_type);
Result svcSignalEvent(Handle handle);
Result svcClearEvent(Handle handle);
Result svcWaitSynchronization(Handle handle, s64 nanoseconds);
Result svcWaitSynchronizationN(s32* out, Handle* handles, s32 handles_num, bool wait_all, s64 nanoseconds);
Result svcSendSyncRequest(Handle session);
Result svcAcceptSession(Handle* session, Handle port);
Result svcReplyAndReceive(s32* index, Handle* handles, s32 handleCount, Handle replyTarget);
///@}
///@name Time
@ -420,11 +444,13 @@ u64 svcGetSystemTick();
Result svcCloseHandle(Handle handle);
Result svcDuplicateHandle(Handle* out, Handle original);
Result svcGetSystemInfo(s64* out, u32 type, s32 param);
Result svcKernelSetState(u32 type, u32 param0, u32 param1, u32 param2);
///@}
///@name Debugging
///@{
void svcBreak(UserBreakType breakReason);
Result svcOutputDebugString(const char* str, int length);
Result svcDebugActiveProcess(Handle* debug, u32 processId);
Result svcBreakDebugProcess(Handle debug);

View File

@ -14,6 +14,7 @@ struct hostent {
int h_addrtype;
int h_length;
char **h_addr_list;
char *h_addr;
};
#ifdef __cplusplus
@ -22,6 +23,7 @@ extern "C" {
extern int h_errno;
struct hostent* gethostbyname(const char *name);
struct hostent* gethostbyaddr(const void *addr, socklen_t len, int type);
void herror(const char *s);
const char* hstrerror(int err);

View File

@ -61,7 +61,7 @@ void* linearMemAlign(size_t size, size_t alignment)
void* linearAlloc(size_t size)
{
return linearMemAlign(size, 16);
return linearMemAlign(size, 0x80);
}
void* linearRealloc(void* mem, size_t size)

View File

@ -59,7 +59,7 @@ void* vramMemAlign(size_t size, size_t alignment)
void* vramAlloc(size_t size)
{
return vramMemAlign(size, 16);
return vramMemAlign(size, 0x80);
}
void* vramRealloc(void* mem, size_t size)

View File

@ -229,40 +229,65 @@ void GPU_SetFloatUniform(GPU_SHADER_TYPE type, u32 startreg, u32* data, u32 numr
GPUCMD_AddWrites(GPUREG_VSH_FLOATUNIFORM_DATA+regOffset, data, numreg*4);
}
//TODO : fix
u32 f32tof24(float f)
// f24 has:
// - 1 sign bit
// - 7 exponent bits
// - 16 mantissa bits
static u32 f32tof24(float f)
{
if(!f)return 0;
u32 v=*((u32*)&f);
u8 s=v>>31;
u32 exp=((v>>23)&0xFF)-0x40;
u32 man=(v>>7)&0xFFFF;
u32 i;
memcpy(&i, &f, 4);
if(exp>=0)return man|(exp<<16)|(s<<23);
else return s<<23;
u32 mantissa = (i << 9) >> 9;
s32 exponent = (i << 1) >> 24;
u32 sign = (i << 0) >> 31;
// Truncate mantissa
mantissa >>= 7;
// Re-bias exponent
exponent = exponent - 127 + 63;
if (exponent < 0)
{
// Underflow: flush to zero
return sign << 23;
}
else if (exponent > 0x7F)
{
// Overflow: saturate to infinity
return sign << 23 | 0x7F << 16;
}
return sign << 23 | exponent << 16 | mantissa;
}
u32 computeInvValue(u32 val)
// f31 has:
// - 1 sign bit
// - 7 exponent bits
// - 23 mantissa bits
static u32 f32tof31(float f)
{
//usual values
if(val==240)return 0x38111111;
if(val==480)return 0x37111111;
if(val==400)return 0x3747ae14;
//but let's not limit ourselves to the usual
float fval=2.0/val;
u32 tmp1,tmp2;
u32 tmp3=*((u32*)&fval);
tmp1=(tmp3<<9)>>9;
tmp2=tmp3&(~0x80000000);
if(tmp2)
u32 i;
memcpy(&i, &f, 4);
u32 mantissa = (i << 9) >> 9;
s32 exponent = (i << 1) >> 24;
u32 sign = (i << 0) >> 31;
// Re-bias exponent
exponent = exponent - 127 + 63;
if (exponent < 0)
{
tmp1=(tmp3<<9)>>9;
int tmp=((tmp3<<1)>>24)-0x40;
if(tmp<0)return ((tmp3>>31)<<30)<<1;
else tmp2=tmp;
// Underflow: flush to zero
return sign << 30;
}
tmp3>>=31;
return (tmp1|(tmp2<<23)|(tmp3<<30))<<1;
else if (exponent > 0x7F)
{
// Overflow: saturate to infinity
return sign << 30 | 0x7F << 23;
}
return sign << 30 | exponent << 23 | mantissa;
}
//takes PAs as arguments
@ -288,9 +313,9 @@ void GPU_SetViewport(u32* depthBuffer, u32* colorBuffer, u32 x, u32 y, u32 w, u3
GPUCMD_AddWrite(GPUREG_011B, 0x00000000); //?
param[0x0]=f32tof24(fw/2);
param[0x1]=computeInvValue(fw);
param[0x1]=f32tof31(2.0f / fw) << 1;
param[0x2]=f32tof24(fh/2);
param[0x3]=computeInvValue(fh);
param[0x3]=f32tof31(2.0f / fh) << 1;
GPUCMD_AddIncrementalWrites(GPUREG_0041, param, 0x00000004);
GPUCMD_AddWrite(GPUREG_0068, (y<<16)|(x&0xFFFF));
@ -330,9 +355,9 @@ void GPU_SetAlphaTest(bool enable, GPU_TESTFUNC function, u8 ref)
GPUCMD_AddWrite(GPUREG_ALPHATEST_CONFIG, (enable&1)|((function&7)<<4)|(ref<<8));
}
void GPU_SetStencilTest(bool enable, GPU_TESTFUNC function, u8 ref, u8 mask, u8 replace)
void GPU_SetStencilTest(bool enable, GPU_TESTFUNC function, u8 ref, u8 input_mask, u8 write_mask)
{
GPUCMD_AddWrite(GPUREG_STENCILTEST_CONFIG, (enable&1)|((function&7)<<4)|(replace<<8)|(ref<<16)|(mask<<24));
GPUCMD_AddWrite(GPUREG_STENCILTEST_CONFIG, (enable&1)|((function&7)<<4)|(write_mask<<8)|(ref<<16)|(input_mask<<24));
}
void GPU_SetStencilOp(GPU_STENCILOP sfail, GPU_STENCILOP dfail, GPU_STENCILOP pass)
@ -463,6 +488,11 @@ void GPU_SetFaceCulling(GPU_CULLMODE mode)
GPUCMD_AddWrite(GPUREG_FACECULLING_CONFIG, mode&0x3);
}
void GPU_SetCombinerBufferWrite(u8 rgb_config, u8 alpha_config)
{
GPUCMD_AddMaskedWrite(GPUREG_TEXENV_BUFFER_CONFIG, 0x2, (rgb_config << 8) | (alpha_config << 12));
}
const u8 GPU_TEVID[]={0xC0,0xC8,0xD0,0xD8,0xF0,0xF8};
void GPU_SetTexEnv(u8 id, u16 rgbSources, u16 alphaSources, u16 rgbOperands, u16 alphaOperands, GPU_COMBINEFUNC rgbCombine, GPU_COMBINEFUNC alphaCombine, u32 constantColor)
@ -480,7 +510,7 @@ void GPU_SetTexEnv(u8 id, u16 rgbSources, u16 alphaSources, u16 rgbOperands, u16
GPUCMD_AddIncrementalWrites(GPUREG_0000|GPU_TEVID[id], param, 0x00000005);
}
void GPU_DrawArray(GPU_Primitive_t primitive, u32 n)
void GPU_DrawArray(GPU_Primitive_t primitive, u32 first, u32 count)
{
//set primitive type
GPUCMD_AddMaskedWrite(GPUREG_PRIMITIVE_CONFIG, 0x2, primitive);
@ -488,7 +518,9 @@ void GPU_DrawArray(GPU_Primitive_t primitive, u32 n)
//index buffer address register should be cleared (except bit 31) before drawing
GPUCMD_AddWrite(GPUREG_INDEXBUFFER_CONFIG, 0x80000000);
//pass number of vertices
GPUCMD_AddWrite(GPUREG_NUMVERTICES, n);
GPUCMD_AddWrite(GPUREG_NUMVERTICES, count);
//set first vertex
GPUCMD_AddWrite(GPUREG_DRAW_VERTEX_OFFSET, first);
//all the following except 0x000F022E might be useless
GPUCMD_AddMaskedWrite(GPUREG_0253, 0x1, 0x00000001);
@ -508,7 +540,9 @@ void GPU_DrawElements(GPU_Primitive_t primitive, u32* indexArray, u32 n)
GPUCMD_AddWrite(GPUREG_INDEXBUFFER_CONFIG, 0x80000000|((u32)indexArray));
//pass number of vertices
GPUCMD_AddWrite(GPUREG_NUMVERTICES, n);
GPUCMD_AddWrite(GPUREG_DRAW_VERTEX_OFFSET, 0x00000000);
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0x2, 0x00000100);
GPUCMD_AddMaskedWrite(GPUREG_0253, 0x2, 0x00000100);

484
libctru/source/romfs_dev.c Normal file
View File

@ -0,0 +1,484 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dirent.h>
#include <sys/iosupport.h>
#include <sys/param.h>
#include <unistd.h>
#include <3ds/types.h>
#include <3ds/svc.h>
#include <3ds/romfs.h>
#include <3ds/services/fs.h>
#include <3ds/util/utf.h>
static bool romFS_active;
static Handle romFS_file;
static u32 romFS_offset;
static romfs_header romFS_header;
static romfs_dir* romFS_cwd;
static u32 *dirHashTable, *fileHashTable;
static void *dirTable, *fileTable;
extern u32 __service_ptr;
extern int __system_argc;
extern char** __system_argv;
static char __component[PATH_MAX+1];
static uint16_t __utf16path[PATH_MAX+1];
#define romFS_root ((romfs_dir*)dirTable)
#define romFS_dir(x) ((romfs_dir*) ((u8*)dirTable + (x)))
#define romFS_file(x) ((romfs_file*)((u8*)fileTable + (x)))
#define romFS_none ((u32)~0)
static ssize_t _romfs_read(u64 offset, void* buffer, u32 size)
{
u64 pos = (u64)romFS_offset + offset;
u32 read = 0;
Result rc = FSFILE_Read(romFS_file, &read, pos, buffer, size);
if (rc) return -1;
return read;
}
static bool _romfs_read_chk(u64 offset, void* buffer, u32 size)
{
return _romfs_read(offset, buffer, size) == size;
}
//-----------------------------------------------------------------------------
static int romfs_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode);
static int romfs_close(struct _reent *r, int fd);
static ssize_t romfs_read(struct _reent *r, int fd, char *ptr, size_t len);
static off_t romfs_seek(struct _reent *r, int fd, off_t pos, int dir);
static int romfs_fstat(struct _reent *r, int fd, struct stat *st);
static int romfs_stat(struct _reent *r, const char *file, struct stat *st);
static int romfs_chdir(struct _reent *r, const char *name);
static DIR_ITER* romfs_diropen(struct _reent *r, DIR_ITER *dirState, const char *path);
static int romfs_dirreset(struct _reent *r, DIR_ITER *dirState);
static int romfs_dirnext(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat);
static int romfs_dirclose(struct _reent *r, DIR_ITER *dirState);
typedef struct
{
u64 offset, size, pos;
} romfs_fileobj;
typedef struct
{
} romfs_diriter;
static devoptab_t romFS_devoptab =
{
.name = "romfs",
.structSize = sizeof(romfs_fileobj),
.open_r = romfs_open,
.close_r = romfs_close,
.read_r = romfs_read,
.seek_r = romfs_seek,
.fstat_r = romfs_fstat,
.stat_r = romfs_stat,
.chdir_r = romfs_chdir,
.dirStateSize = sizeof(romfs_diriter),
.diropen_r = romfs_diropen,
.dirreset_r = romfs_dirreset,
.dirnext_r = romfs_dirnext,
.dirclose_r = romfs_dirclose,
.deviceData = NULL,
};
//-----------------------------------------------------------------------------
// File header
#define _3DSX_MAGIC 0x58534433 // '3DSX'
typedef struct
{
u32 magic;
u16 headerSize, relocHdrSize;
u32 formatVer;
u32 flags;
// Sizes of the code, rodata and data segments +
// size of the BSS section (uninitialized latter half of the data segment)
u32 codeSegSize, rodataSegSize, dataSegSize, bssSize;
// offset and size of smdh
u32 smdhOffset, smdhSize;
// offset to filesystem
u32 fsOffset;
} _3DSX_Header;
static Result romfsInitCommon(void);
Result romfsInit(void)
{
if (romFS_active) return 0;
if (__service_ptr)
{
// RomFS appended to a 3DSX file
if (__system_argc == 0 || !__system_argv[0]) return 1;
const char* filename = __system_argv[0];
if (strncmp(filename, "sdmc:/", 6) == 0)
filename += 5;
else if (strncmp(filename, "3dslink:/", 9) == 0)
{
strncpy(__component, "/3ds", PATH_MAX);
strncat(__component, filename+8, PATH_MAX);
__component[PATH_MAX] = 0;
filename = __component;
} else
return 2;
size_t units = utf8_to_utf16(__utf16path, (const uint8_t*)filename, PATH_MAX+1);
if (units == (size_t)-1) return 3;
__utf16path[units] = 0;
FS_archive arch = { ARCH_SDMC, { PATH_EMPTY, 1, (u8*)"" }, 0, 0 };
FS_path path = { PATH_WCHAR, units+1, (u8*)__utf16path };
Result rc = FSUSER_OpenFileDirectly(NULL, &romFS_file, arch, path, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
if (rc) return rc;
_3DSX_Header hdr;
if (!_romfs_read_chk(0, &hdr, sizeof(hdr))) goto _fail0;
if (hdr.magic != _3DSX_MAGIC) goto _fail0;
if (hdr.headerSize < sizeof(hdr)) goto _fail0;
romFS_offset = hdr.fsOffset;
if (!romFS_offset) goto _fail0;
} else
{
// Regular RomFS
u8 zeros[0xC];
memset(zeros, 0, sizeof(zeros));
FS_archive arch = { ARCH_ROMFS, { PATH_EMPTY, 1, (u8*)"" }, 0, 0 };
FS_path path = { PATH_BINARY, sizeof(zeros), zeros };
Result rc = FSUSER_OpenFileDirectly(NULL, &romFS_file, arch, path, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
if (rc) return rc;
}
return romfsInitCommon();
_fail0:
FSFILE_Close(romFS_file);
return 10;
}
Result romfsInitFromFile(Handle file, u32 offset)
{
if (romFS_active) return 0;
romFS_file = file;
romFS_offset = offset;
return romfsInitCommon();
}
Result romfsInitCommon(void)
{
if (_romfs_read(0, &romFS_header, sizeof(romFS_header)) != sizeof(romFS_header))
goto _fail0;
dirHashTable = (u32*)malloc(romFS_header.dirHashTableSize);
if (!dirHashTable) goto _fail0;
if (!_romfs_read_chk(romFS_header.dirHashTableOff, dirHashTable, romFS_header.dirHashTableSize)) goto _fail1;
dirTable = malloc(romFS_header.dirTableSize);
if (!dirTable) goto _fail1;
if (!_romfs_read_chk(romFS_header.dirTableOff, dirTable, romFS_header.dirTableSize)) goto _fail2;
fileHashTable = (u32*)malloc(romFS_header.fileHashTableSize);
if (!fileHashTable) goto _fail2;
if (!_romfs_read_chk(romFS_header.fileHashTableOff, fileHashTable, romFS_header.fileHashTableSize)) goto _fail3;
fileTable = malloc(romFS_header.fileTableSize);
if (!fileTable) goto _fail3;
if (!_romfs_read_chk(romFS_header.fileTableOff, fileTable, romFS_header.fileTableSize)) goto _fail4;
romFS_cwd = romFS_root;
romFS_active = true;
AddDevice(&romFS_devoptab);
chdir("romfs:/");
return 0;
_fail4:
free(fileTable);
_fail3:
free(fileHashTable);
_fail2:
free(dirTable);
_fail1:
free(dirHashTable);
_fail0:
FSFILE_Close(romFS_file);
return 10;
}
Result romfsExit(void)
{
if (!romFS_active) return 0;
romFS_active = false;
RemoveDevice("romfs");
FSFILE_Close(romFS_file);
free(dirHashTable);
free(fileHashTable);
free(dirTable);
free(fileTable);
return 0;
}
//-----------------------------------------------------------------------------
static u32 calcHash(u32 parent, u16* name, u32 namelen, u32 total)
{
u32 hash = parent ^ 123456789;
u32 i;
for (i = 0; i < namelen; i ++)
{
hash = (hash >> 5) | (hash << 27);
hash ^= name[i];
}
return hash % total;
}
static romfs_dir* searchForDir(romfs_dir* parent, u16* name, u32 namelen)
{
u32 parentOff = (u32)parent - (u32)dirTable;
u32 hash = calcHash(parentOff, name, namelen, romFS_header.dirHashTableSize/4);
romfs_dir* curDir = NULL;
u32 curOff;
for (curOff = dirHashTable[hash]; curOff != romFS_none; curOff = curDir->nextHash)
{
curDir = romFS_dir(curOff);
if (curDir->parent != parentOff) continue;
if (curDir->nameLen != namelen*2) continue;
if (memcmp(curDir->name, name, namelen*2) != 0) continue;
return curDir;
}
return NULL;
}
static romfs_file* searchForFile(romfs_dir* parent, u16* name, u32 namelen)
{
u32 parentOff = (u32)parent - (u32)dirTable;
u32 hash = calcHash(parentOff, name, namelen, romFS_header.fileHashTableSize/4);
romfs_file* curFile = NULL;
u32 curOff;
for (curOff = fileHashTable[hash]; curOff != romFS_none; curOff = curFile->nextHash)
{
curFile = romFS_file(curOff);
if (curFile->parent != parentOff) continue;
if (curFile->nameLen != namelen*2) continue;
if (memcmp(curFile->name, name, namelen*2) != 0) continue;
return curFile;
}
return NULL;
}
static int navigateToDir(romfs_dir** ppDir, const char** pPath, bool isDir)
{
size_t units;
char* colonPos = strchr(*pPath, ':');
if (colonPos) *pPath = colonPos+1;
if (!**pPath)
return EILSEQ;
*ppDir = romFS_cwd;
if (**pPath == '/')
{
*ppDir = romFS_root;
(*pPath)++;
}
while (**pPath)
{
char* slashPos = strchr(*pPath, '/');
char* component = __component;
if (slashPos)
{
u32 len = slashPos - *pPath;
if (!len)
return EILSEQ;
if (len > PATH_MAX)
return ENAMETOOLONG;
memcpy(component, *pPath, len);
component[len] = 0;
*pPath = slashPos+1;
} else if (isDir)
{
component = (char*)*pPath;
*pPath += strlen(component);
} else
return 0;
if (component[0]=='.')
{
if (!component[1]) continue;
if (component[1]=='.' && !component[2])
{
*ppDir = romFS_dir((*ppDir)->parent);
continue;
}
}
units = utf8_to_utf16(__utf16path, (const uint8_t*)component, PATH_MAX+1);
if (units == (size_t)-1)
return EILSEQ;
*ppDir = searchForDir(*ppDir, __utf16path, units);
if (!*ppDir)
return EEXIST;
}
if (!isDir && !**pPath)
return EILSEQ;
return 0;
}
//-----------------------------------------------------------------------------
int romfs_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode)
{
romfs_fileobj* fileobj = (romfs_fileobj*)fileStruct;
if ((flags & O_ACCMODE) != O_RDONLY)
{
r->_errno = EINVAL;
return -1;
}
romfs_dir* curDir = NULL;
r->_errno = navigateToDir(&curDir, &path, false);
if (r->_errno != 0)
return -1;
size_t units = utf8_to_utf16(__utf16path, (const uint8_t*)path, PATH_MAX+1);
if (!units || units == (size_t)-1)
{
r->_errno = EILSEQ;
return -1;
}
romfs_file* file = searchForFile(curDir, __utf16path, units);
if (!file)
{
r->_errno = EEXIST;
return -1;
}
fileobj->offset = (u64)romFS_header.fileDataOff + file->dataOff;
fileobj->size = file->dataSize;
fileobj->pos = 0;
return 0;
}
int romfs_close(struct _reent *r, int fd)
{
return 0;
}
ssize_t romfs_read(struct _reent *r, int fd, char *ptr, size_t len)
{
romfs_fileobj* file = (romfs_fileobj*)fd;
u64 endPos = file->pos + len;
if (endPos > file->size)
endPos = file->size;
len = endPos - file->pos;
ssize_t adv = _romfs_read(file->offset + file->pos, ptr, len);
if (adv >= 0)
{
file->pos += adv;
return adv;
}
r->_errno = EIO;
return -1;
}
off_t romfs_seek(struct _reent *r, int fd, off_t pos, int dir)
{
romfs_fileobj* file = (romfs_fileobj*)fd;
switch (dir)
{
case SEEK_SET:
file->pos = pos;
break;
case SEEK_CUR:
file->pos += pos;
break;
case SEEK_END:
file->pos = file->size + pos;
break;
default:
r->_errno = EINVAL;
return -1;
}
if (file->pos > file->size)
file->pos = file->size;
return file->pos;
}
int romfs_fstat(struct _reent *r, int fd, struct stat *st)
{
romfs_fileobj* file = (romfs_fileobj*)fd;
memset(st, 0, sizeof(struct stat));
st->st_size = (off_t)file->size;
st->st_nlink = 1;
st->st_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
return 0;
}
int romfs_stat(struct _reent *r, const char *file, struct stat *st)
{
r->_errno = ENOTSUP;
return 1;
}
int romfs_chdir(struct _reent *r, const char *name)
{
romfs_dir* curDir = NULL;
r->_errno = navigateToDir(&curDir, &name, true);
if (r->_errno != 0)
return -1;
romFS_cwd = curDir;
return 0;
}
DIR_ITER* romfs_diropen(struct _reent *r, DIR_ITER *dirState, const char *path)
{
//romfs_diriter* dir = (romfs_diriter*)(dirState->dirStruct);
r->_errno = ENOTSUP;
return NULL;
}
int romfs_dirreset(struct _reent *r, DIR_ITER *dirState)
{
//romfs_diriter* dir = (romfs_diriter*)(dirState->dirStruct);
r->_errno = ENOTSUP;
return 1;
}
int romfs_dirnext(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat)
{
//romfs_diriter* dir = (romfs_diriter*)(dirState->dirStruct);
r->_errno = ENOTSUP;
return 1;
}
int romfs_dirclose(struct _reent *r, DIR_ITER *dirState)
{
return 0;
}

View File

@ -798,6 +798,22 @@ Result APT_GetAppletManInfo(Handle* handle, u8 inval, u8 *outval8, u32 *outval32
return cmdbuf[1];
}
Result APT_GetAppletProgramInfo(Handle* handle, u32 id, u32 flags, u16 *titleversion)
{
if(!handle)handle=&aptuHandle;
u32* cmdbuf=getThreadCommandBuffer();
cmdbuf[0]=0x004D0080; //request header code
cmdbuf[1]=id;
cmdbuf[2]=flags;
Result ret=0;
if((ret=svcSendSyncRequest(*handle)))return ret;
if(titleversion)*titleversion=cmdbuf[2];
return cmdbuf[1];
}
Result APT_IsRegistered(Handle* handle, NS_APPID appID, u8* out)
{
if(!handle)handle=&aptuHandle;

View File

@ -0,0 +1,738 @@
#include <3ds/services/cam.h>
#include <3ds/services/y2r.h>
#include <3ds/srv.h>
#include <3ds/svc.h>
#include <3ds/types.h>
Handle camHandle;
static bool initialized = false;
Result camInit() {
Result ret = 0;
if (initialized) return 0;
if (camHandle == 0)
{
ret = srvGetServiceHandle(&camHandle, "cam:u");
if (ret < 0) return ret;
}
ret = CAMU_DriverInitialize();
if (ret < 0) return ret;
initialized = true;
return 0;
}
Result camExit() {
Result ret = 0;
if (initialized)
{
ret = CAMU_DriverFinalize();
if (ret < 0) return ret;
}
if (camHandle != 0)
{
ret = svcCloseHandle(camHandle);
if (ret < 0) return ret;
camHandle = 0;
}
return 0;
}
Result CAMU_StartCapture(CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00010040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_StopCapture(CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00020040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_IsBusy(bool* busy, CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00030040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*busy = (bool) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_ClearBuffer(CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00040040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_GetVsyncInterruptEvent(Handle* event, CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00050040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*event = cmdbuf[3];
return cmdbuf[1];
}
Result CAMU_GetBufferErrorInterruptEvent(Handle* event, CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00060040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*event = cmdbuf[3];
return cmdbuf[1];
}
Result CAMU_SetReceiving(Handle* event, void* dst, CAMU_Port port, u32 imageSize, s16 transferUnit) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00070102;
cmdbuf[1] = (u32) dst;
cmdbuf[2] = port;
cmdbuf[3] = imageSize;
cmdbuf[4] = transferUnit;
cmdbuf[5] = 0;
cmdbuf[6] = 0xFFFF8001;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*event = cmdbuf[3];
return cmdbuf[1];
}
Result CAMU_IsFinishedReceiving(bool* finishedReceiving, CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00080040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*finishedReceiving = (bool) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_SetTransferLines(CAMU_Port port, s16 lines, s16 width, s16 height) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00090100;
cmdbuf[1] = port;
cmdbuf[2] = lines;
cmdbuf[3] = width;
cmdbuf[4] = height;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_GetMaxLines(s16* maxLines, s16 width, s16 height) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000A0080;
cmdbuf[1] = width;
cmdbuf[2] = height;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*maxLines = (s16) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_SetTransferBytes(CAMU_Port port, u32 bytes, s16 width, s16 height) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000B0100;
cmdbuf[1] = port;
cmdbuf[2] = bytes;
cmdbuf[3] = width;
cmdbuf[4] = height;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_GetTransferBytes(u32* transferBytes, CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000C0040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*transferBytes = cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_GetMaxBytes(u32* maxBytes, s16 width, s16 height) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000D0080;
cmdbuf[1] = width;
cmdbuf[2] = height;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*maxBytes = cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_SetTrimming(CAMU_Port port, bool trimming) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000E0080;
cmdbuf[1] = port;
cmdbuf[2] = trimming;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_IsTrimming(bool* trimming, CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x000F0040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*trimming = (bool) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_SetTrimmingParams(CAMU_Port port, s16 xStart, s16 yStart, s16 xEnd, s16 yEnd) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00100140;
cmdbuf[1] = port;
cmdbuf[2] = xStart;
cmdbuf[3] = yStart;
cmdbuf[4] = xEnd;
cmdbuf[5] = yEnd;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_GetTrimmingParams(s16* xStart, s16* yStart, s16* xEnd, s16* yEnd, CAMU_Port port) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00110040;
cmdbuf[1] = port;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*xStart = (s16) cmdbuf[2];
*yStart = (s16) cmdbuf[3];
*xEnd = (s16) cmdbuf[4];
*yEnd = (s16) cmdbuf[5];
return cmdbuf[1];
}
Result CAMU_SetTrimmingParamsCenter(CAMU_Port port, s16 trimWidth, s16 trimHeight, s16 camWidth, s16 camHeight) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00120140;
cmdbuf[1] = port;
cmdbuf[2] = trimWidth;
cmdbuf[3] = trimHeight;
cmdbuf[4] = camWidth;
cmdbuf[5] = camHeight;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_Activate(CAMU_CameraSelect select) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00130040;
cmdbuf[1] = select;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SwitchContext(CAMU_CameraSelect select, CAMU_Context context) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00140080;
cmdbuf[1] = select;
cmdbuf[2] = context;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetExposure(CAMU_CameraSelect select, s8 exposure) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00150080;
cmdbuf[1] = select;
cmdbuf[2] = exposure;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetWhiteBalance(CAMU_CameraSelect select, CAMU_WhiteBalance whiteBalance) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00160080;
cmdbuf[1] = select;
cmdbuf[2] = whiteBalance;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetWhiteBalanceWithoutBaseUp(CAMU_CameraSelect select, CAMU_WhiteBalance whiteBalance) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00170080;
cmdbuf[1] = select;
cmdbuf[2] = whiteBalance;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetSharpness(CAMU_CameraSelect select, s8 sharpness) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00180080;
cmdbuf[1] = select;
cmdbuf[2] = sharpness;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetAutoExposure(CAMU_CameraSelect select, bool autoExposure) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00190080;
cmdbuf[1] = select;
cmdbuf[2] = autoExposure;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_IsAutoExposure(bool* autoExposure, CAMU_CameraSelect select) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x001A0040;
cmdbuf[1] = select;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*autoExposure = (bool) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_SetAutoWhiteBalance(CAMU_CameraSelect select, bool autoWhiteBalance) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x001B0080;
cmdbuf[1] = select;
cmdbuf[2] = autoWhiteBalance;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_IsAutoWhiteBalance(bool* autoWhiteBalance, CAMU_CameraSelect select) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x001C0040;
cmdbuf[1] = select;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*autoWhiteBalance = (bool) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_FlipImage(CAMU_CameraSelect select, CAMU_Flip flip, CAMU_Context context) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x001D00C0;
cmdbuf[1] = select;
cmdbuf[2] = flip;
cmdbuf[3] = context;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetDetailSize(CAMU_CameraSelect select, s16 width, s16 height, s16 cropX0, s16 cropY0, s16 cropX1, s16 cropY1, CAMU_Context context) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x001E0200;
cmdbuf[1] = select;
cmdbuf[2] = width;
cmdbuf[3] = height;
cmdbuf[4] = cropX0;
cmdbuf[5] = cropY0;
cmdbuf[6] = cropX1;
cmdbuf[7] = cropY1;
cmdbuf[8] = context;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetSize(CAMU_CameraSelect select, CAMU_Size size, CAMU_Context context) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x001F00C0;
cmdbuf[1] = select;
cmdbuf[2] = size;
cmdbuf[3] = context;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetFrameRate(CAMU_CameraSelect select, CAMU_FrameRate frameRate) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00200080;
cmdbuf[1] = select;
cmdbuf[2] = frameRate;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetPhotoMode(CAMU_CameraSelect select, CAMU_PhotoMode photoMode) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00210080;
cmdbuf[1] = select;
cmdbuf[2] = photoMode;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetEffect(CAMU_CameraSelect select, CAMU_Effect effect, CAMU_Context context) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x002200C0;
cmdbuf[1] = select;
cmdbuf[2] = effect;
cmdbuf[3] = context;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetContrast(CAMU_CameraSelect select, CAMU_Contrast contrast) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00230080;
cmdbuf[1] = select;
cmdbuf[2] = contrast;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetLensCorrection(CAMU_CameraSelect select, CAMU_LensCorrection lensCorrection) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00240080;
cmdbuf[1] = select;
cmdbuf[2] = lensCorrection;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetOutputFormat(CAMU_CameraSelect select, CAMU_OutputFormat format, CAMU_Context context) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x002500C0;
cmdbuf[1] = select;
cmdbuf[2] = format;
cmdbuf[3] = context;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetAutoExposureWindow(CAMU_CameraSelect select, s16 x, s16 y, s16 width, s16 height) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00260140;
cmdbuf[1] = select;
cmdbuf[2] = x;
cmdbuf[3] = y;
cmdbuf[4] = width;
cmdbuf[5] = height;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetAutoWhiteBalanceWindow(CAMU_CameraSelect select, s16 x, s16 y, s16 width, s16 height) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00270140;
cmdbuf[1] = select;
cmdbuf[2] = x;
cmdbuf[3] = y;
cmdbuf[4] = width;
cmdbuf[5] = height;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetNoiseFilter(CAMU_CameraSelect select, bool noiseFilter) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00280080;
cmdbuf[1] = select;
cmdbuf[2] = noiseFilter;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SynchronizeVsyncTiming(CAMU_CameraSelect select1, CAMU_CameraSelect select2) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00290080;
cmdbuf[1] = select1;
cmdbuf[2] = select2;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_GetLatestVsyncTiming(s64* timing, CAMU_Port port, u32 past) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x002A0080;
cmdbuf[1] = port;
cmdbuf[2] = past;
cmdbuf[49] = (past << 17) | 2;
cmdbuf[50] = (u32) timing;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_GetStereoCameraCalibrationData(CAMU_StereoCameraCalibrationData* data) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x002B0000;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*data = *(CAMU_StereoCameraCalibrationData*) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_SetStereoCameraCalibrationData(CAMU_StereoCameraCalibrationData data) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x002C0400;
*(CAMU_StereoCameraCalibrationData*) cmdbuf[1] = data;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_WriteRegisterI2c(CAMU_CameraSelect select, u16 addr, u16 data) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x002D00C0;
cmdbuf[1] = select;
cmdbuf[2] = addr;
cmdbuf[3] = data;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_WriteMcuVariableI2c(CAMU_CameraSelect select, u16 addr, u16 data) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x002E00C0;
cmdbuf[1] = select;
cmdbuf[2] = addr;
cmdbuf[3] = data;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_ReadRegisterI2cExclusive(u16* data, CAMU_CameraSelect select, u16 addr) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x002F0080;
cmdbuf[1] = select;
cmdbuf[2] = addr;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*data = (u16) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_ReadMcuVariableI2cExclusive(u16* data, CAMU_CameraSelect select, u16 addr) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00300080;
cmdbuf[1] = select;
cmdbuf[2] = addr;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*data = (u16) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_SetImageQualityCalibrationData(CAMU_ImageQualityCalibrationData data) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00310180;
*(CAMU_ImageQualityCalibrationData*) cmdbuf[1] = data;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_GetImageQualityCalibrationData(CAMU_ImageQualityCalibrationData* data) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00320000;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*data = *(CAMU_ImageQualityCalibrationData*) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_SetPackageParameterWithoutContext(CAMU_PackageParameterCameraSelect param) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x003302C0;
*(CAMU_PackageParameterCameraSelect*) cmdbuf[1] = param;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetPackageParameterWithContext(CAMU_PackageParameterContext param) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00340140;
*(CAMU_PackageParameterContext*) cmdbuf[1] = param;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetPackageParameterWithContextDetail(CAMU_PackageParameterContextDetail param) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x003501C0;
*(CAMU_PackageParameterContextDetail*) cmdbuf[1] = param;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_GetSuitableY2rStandardCoefficient(Y2R_StandardCoefficient* coefficient) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00360000;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*coefficient = (Y2R_StandardCoefficient) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_PlayShutterSound(CAMU_ShutterSoundType sound) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00380040;
cmdbuf[1] = sound;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_DriverInitialize() {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x00390000;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_DriverFinalize() {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x003A0000;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_GetActivatedCamera(CAMU_CameraSelect* select) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x003B0000;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*select = (CAMU_CameraSelect) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_GetSleepCamera(CAMU_CameraSelect* select) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x003C0000;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
*select = (CAMU_CameraSelect) cmdbuf[2];
return cmdbuf[1];
}
Result CAMU_SetSleepCamera(CAMU_CameraSelect select) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x003D0040;
cmdbuf[1] = select;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}
Result CAMU_SetBrightnessSynchronization(bool brightnessSynchronization) {
Result ret = 0;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x003E0040;
cmdbuf[1] = brightnessSynchronization;
if ((ret = svcSendSyncRequest(camHandle)) != 0) return ret;
return cmdbuf[1];
}

View File

@ -82,6 +82,50 @@ void gspWaitForEvent(GSP_Event id, bool nextEvent)
svcClearEvent(gspEvents[id]);
}
static int popInterrupt()
{
int curEvt;
u32 strexFailed;
do {
union {
struct {
u8 cur;
u8 count;
u8 err;
u8 unused;
};
u32 as_u32;
} header;
u32* gsp_header_ptr = (u32*)(gspEventData + 0);
// Do a load on all header fields as an atomic unit
__asm__ volatile (
"ldrex %[result], %[addr]" :
[result]"=r"(header.as_u32) :
[addr]"Q"(*gsp_header_ptr));
if (__builtin_expect(header.count == 0, 0)) {
__asm__ volatile ("clrex");
return -1;
}
curEvt = gspEventData[0xC + header.cur];
header.cur += 1;
if (header.cur >= 0x34) header.cur -= 0x34;
header.count -= 1;
header.err = 0; // Should this really be set?
__asm__ volatile (
"strex %[result], %[val], %[addr]" :
[result]"=&r"(strexFailed), [addr]"=Q"(*gsp_header_ptr) :
[val]"r"(header.as_u32));
} while (__builtin_expect(strexFailed, 0));
return curEvt;
}
void gspEventThreadMain(void *arg)
{
while (gspRunEvents)
@ -89,24 +133,18 @@ void gspEventThreadMain(void *arg)
svcWaitSynchronization(gspEvent, U64_MAX);
svcClearEvent(gspEvent);
int count = gspEventData[1];
int cur = gspEventData[0];
int last = cur + count;
while (last >= 0x34) last -= 0x34;
int i;
for (i = 0; i < count; i ++)
while (true)
{
int curEvt = gspEventData[0xC + cur];
cur ++;
if (cur >= 0x34) cur -= 0x34;
if (curEvt >= GSPEVENT_MAX) continue;
svcSignalEvent(gspEvents[curEvt]);
gspEventCounts[curEvt]++;
}
int curEvt = popInterrupt();
gspEventData[0] = last;
gspEventData[1] -= count;
gspEventData[2] = 0;
if (curEvt == -1)
break;
if (curEvt < GSPEVENT_MAX) {
svcSignalEvent(gspEvents[curEvt]);
gspEventCounts[curEvt]++;
}
}
}
svcExitThread();
}

View File

@ -149,14 +149,14 @@ void hidScanInput()
if(Id>7)Id=7;
if(hidCheckSectionUpdateTime(&hidSharedMem[66], Id)==0)
{
aVec = *(accelVector*)&hidSharedMem[66 + 8 + Id*2];
aVec = ((accelVector*)&hidSharedMem[66 + 8])[Id];
}
Id = hidSharedMem[86 + 4];//Gyroscope
if(Id>31)Id=31;
if(hidCheckSectionUpdateTime(&hidSharedMem[86], Id)==0)
{
gRate = *(angularRate*)&hidSharedMem[86 + 8 + Id*2];
gRate = ((angularRate*)&hidSharedMem[86 + 8])[Id];
}
}

View File

@ -95,6 +95,11 @@ Result httpcGetDownloadSizeState(httpcContext *context, u32* downloadedsize, u32
return HTTPC_GetDownloadSizeState(context->servhandle, context->httphandle, downloadedsize, contentsize);
}
Result httpcGetResponseHeader(httpcContext *context, char* name, char* value, u32 valuebuf_maxsize)
{
return HTTPC_GetResponseHeader(context->servhandle, context->httphandle, name, value, valuebuf_maxsize);
}
Result httpcGetResponseStatusCode(httpcContext *context, u32* out, u64 delay)
{
return HTTPC_GetResponseStatusCode(context->servhandle, context->httphandle, out);
@ -294,6 +299,27 @@ Result HTTPC_GetDownloadSizeState(Handle handle, Handle contextHandle, u32* down
return cmdbuf[1];
}
Result HTTPC_GetResponseHeader(Handle handle, Handle contextHandle, char* name, char* value, u32 valuebuf_maxsize)
{
u32* cmdbuf=getThreadCommandBuffer();
int name_len=strlen(name)+1;
cmdbuf[0]=0x001e00c4; //request header code
cmdbuf[1]=contextHandle;
cmdbuf[2]=name_len;
cmdbuf[3]=valuebuf_maxsize;
cmdbuf[4]=(name_len<<14)|0xC02;
cmdbuf[5]=(u32)name;
cmdbuf[6]=(valuebuf_maxsize<<4)|0xC;
cmdbuf[7]=(u32)value;
Result ret=0;
if((ret=svcSendSyncRequest(handle)))return ret;
return cmdbuf[1];
}
Result HTTPC_GetResponseStatusCode(Handle handle, Handle contextHandle, u32* out)
{
u32* cmdbuf=getThreadCommandBuffer();

View File

@ -4,6 +4,7 @@
Handle SOCU_handle = 0;
Handle socMemhandle = 0;
int h_errno = 0;
//This is based on the array from libogc network_wii.c.
static u8 _net_error_code_map[] = {

View File

@ -0,0 +1,72 @@
#include "soc_common.h"
#include <netdb.h>
#define MAX_HOSTENT_RESULTS 16
static struct hostent SOC_hostent;
static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1];
static char *SOC_hostent_alias = NULL;
struct hostent* gethostbyaddr(const void *addr, socklen_t len, int type)
{
int ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
u32 saved_threadstorage[2];
static u8 outbuf[0x1A88];
h_errno = 0;
cmdbuf[0] = 0x000E00C2;
cmdbuf[1] = len;
cmdbuf[2] = type;
cmdbuf[3] = sizeof(outbuf);
cmdbuf[4] = (len << 14) | 0x1002;
cmdbuf[5] = (u32)addr;
saved_threadstorage[0] = cmdbuf[0x100>>2];
saved_threadstorage[1] = cmdbuf[0x104>>2];
cmdbuf[0x100>>2] = (sizeof(outbuf) << 14) | 2;
cmdbuf[0x104>>2] = (u32)outbuf;
ret = svcSendSyncRequest(SOCU_handle);
if(ret != 0) {
h_errno = NO_RECOVERY;
return NULL;
}
cmdbuf[0x100>>2] = saved_threadstorage[0];
cmdbuf[0x104>>2] = saved_threadstorage[1];
ret = (int)cmdbuf[1];
if(ret == 0)
ret = _net_convert_error(cmdbuf[2]);
if(ret < 0) {
/* TODO: set h_errno based on ret */
h_errno = HOST_NOT_FOUND;
return NULL;
}
u32 num_results, i;
memcpy(&num_results, (char*)outbuf+4, sizeof(num_results));
if(num_results > MAX_HOSTENT_RESULTS)
num_results = MAX_HOSTENT_RESULTS;
SOC_hostent.h_name = (char*)outbuf + 8;
SOC_hostent.h_aliases = &SOC_hostent_alias;
SOC_hostent.h_addrtype = AF_INET;
SOC_hostent.h_length = 4;
SOC_hostent.h_addr_list = SOC_hostent_results;
SOC_hostent_alias = NULL;
for(i = 0; i < num_results; ++i)
SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10;
SOC_hostent_results[num_results] = NULL;
SOC_hostent.h_addr = SOC_hostent.h_addr_list[0];
return &SOC_hostent;
}

View File

@ -6,8 +6,6 @@ static struct hostent SOC_hostent;
static char *SOC_hostent_results[MAX_HOSTENT_RESULTS+1];
static char *SOC_hostent_alias = NULL;
int h_errno = 0;
struct hostent* gethostbyname(const char *name)
{
int ret = 0;
@ -66,5 +64,7 @@ struct hostent* gethostbyname(const char *name)
SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10;
SOC_hostent_results[num_results] = NULL;
SOC_hostent.h_addr = SOC_hostent.h_addr_list[0];
return &SOC_hostent;
}

View File

@ -30,8 +30,7 @@ typedef struct {
extern service_list_t* __service_ptr;
// not static so that apps can actually access it if need be
Handle g_srv_handle = 0;
static Handle g_srv_handle = 0;
static int __name_cmp(const char* a, const char* b) {

View File

@ -270,7 +270,7 @@ svcDuplicateHandle:
.type svcGetSystemTick, %function
svcGetSystemTick:
svc 0x28
bx lr
bx lr
.global svcGetSystemInfo
.type svcGetSystemInfo, %function
@ -315,7 +315,7 @@ svcConnectToPort:
.type svcSendSyncRequest, %function
svcSendSyncRequest:
svc 0x32
bx lr
bx lr
.global svcOpenProcess
.type svcOpenProcess, %function
@ -324,8 +324,7 @@ svcOpenProcess:
svc 0x33
pop {r2}
str r1, [r2]
bx lr
bx lr
.global svcOpenThread
.type svcOpenThread, %function
@ -334,8 +333,7 @@ svcOpenThread:
svc 0x34
pop {r2}
str r1, [r2]
bx lr
bx lr
.global svcGetProcessId
.type svcGetProcessId, %function
@ -346,7 +344,6 @@ svcGetProcessId:
str r1, [r3]
bx lr
.global svcGetProcessIdOfThread
.type svcGetProcessIdOfThread, %function
svcGetProcessIdOfThread:
@ -365,6 +362,12 @@ svcGetThreadId:
str r1, [r3]
bx lr
.global svcBreak
.type svcBreak, %function
svcBreak:
svc 0x3C
bx lr
.global svcOutputDebugString
.type svcOutputDebugString, %function
svcOutputDebugString:
@ -381,7 +384,66 @@ svcCreatePort:
ldr r3, [sp, #4]
str r2, [r3]
add sp, sp, #8
bx lr
bx lr
.global svcAcceptSession
.type svcAcceptSession, %function
svcAcceptSession:
str r0, [sp, #-4]!
svc 0x4A
ldr r2, [sp]
str r1, [r2]
add sp, sp, #4
bx lr
.global svcReplyAndReceive
.type svcReplyAndReceive, %function
svcReplyAndReceive:
str r0, [sp, #-4]!
svc 0x4F
ldr r2, [sp]
str r1, [r2]
add sp, sp, #4
bx lr
.global svcInvalidateProcessDataCache
.type svcInvalidateProcessDataCache, %function
svcInvalidateProcessDataCache:
svc 0x52
bx lr
.global svcFlushProcessDataCache
.type svcFlushProcessDataCache, %function
svcFlushProcessDataCache:
svc 0x54
bx lr
.global svcStartInterProcessDma
.type svcStartInterProcessDma, %function
svcStartInterProcessDma:
stmfd sp!, {r0, r4, r5}
ldr r0, [sp, #0xC]
ldr r4, [sp, #0x10]
ldr r5, [sp, #0x14]
svc 0x55
ldmfd sp!, {r2, r4, r5}
str r1, [r2]
bx lr
.global svcStopDma
.type svcStopDma, %function
svcStopDma:
svc 0x56
bx lr
.global svcGetDmaState
.type svcGetDmaState, %function
svcGetDmaState:
str r0, [sp, #-4]!
svc 0x57
ldr r3, [sp], #4
str r1, [r3]
bx lr
.global svcDebugActiveProcess
.type svcDebugActiveProcess, %function
@ -390,31 +452,31 @@ svcDebugActiveProcess:
svc 0x60
pop {r2}
str r1, [r2]
bx lr
bx lr
.global svcBreakDebugProcess
.type svcBreakDebugProcess, %function
svcBreakDebugProcess:
svc 0x61
bx lr
bx lr
.global svcTerminateDebugProcess
.type svcTerminateDebugProcess, %function
svcTerminateDebugProcess:
svc 0x62
bx lr
bx lr
.global svcGetProcessDebugEvent
.type svcGetProcessDebugEvent, %function
svcGetProcessDebugEvent:
svc 0x63
bx lr
bx lr
.global svcContinueDebugEvent
.type svcContinueDebugEvent, %function
svcContinueDebugEvent:
svc 0x64
bx lr
bx lr
.global svcGetProcessList
.type svcGetProcessList, %function
@ -426,13 +488,13 @@ svcGetProcessList:
ldr r3, [sp, #4]
str r2, [r3]
add sp, sp, #8
bx lr
bx lr
.global svcReadProcessMemory
.type svcReadProcessMemory, %function
svcReadProcessMemory:
svc 0x6A
bx lr
bx lr
.global svcWriteProcessMemory
.type svcWriteProcessMemory, %function
@ -448,25 +510,37 @@ svcControlProcessMemory:
ldr r5, [sp, #0xC]
svc 0x70
pop {r4-r5}
bx lr
bx lr
.global svcMapProcessMemory
.type svcMapProcessMemory, %function
svcMapProcessMemory:
svc 0x71
bx lr
bx lr
.global svcUnmapProcessMemory
.type svcUnmapProcessMemory, %function
svcUnmapProcessMemory:
svc 0x72
bx lr
bx lr
.global svcTerminateProcess
.type svcTerminateProcess, %function
svcTerminateProcess:
svc 0x76
bx lr
.global svcBackdoor
.type svcBackdoor, %function
svcBackdoor:
svc 0x7B
bx lr
bx lr
.global svcKernelSetState
.type svcKernelSetState, %function
svcKernelSetState:
svc 0x7C
bx lr
.global svcQueryProcessMemory
.type svcQueryProcessMemory, %function
@ -479,4 +553,4 @@ svcQueryProcessMemory:
str r5, [r6]
add sp, sp, #8
pop {r4-r6}
bx lr
bx lr