Merge branch 'master' of github.com:smealum/ctrulib
This commit is contained in:
commit
c6192c331b
7
examples/graphics/gpu/Makefile
Normal file
7
examples/graphics/gpu/Makefile
Normal 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;
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
181
examples/romfs/Makefile
Normal 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
|
||||
#---------------------------------------------------------------------------------------
|
6
examples/romfs/romfs/folder/file.txt
Normal file
6
examples/romfs/romfs/folder/file.txt
Normal 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
|
2
examples/romfs/romfs/フォルダ/ファイル.txt
Normal file
2
examples/romfs/romfs/フォルダ/ファイル.txt
Normal file
@ -0,0 +1,2 @@
|
||||
The path to this file contains UTF-16
|
||||
characters that fall outside ASCII.
|
58
examples/romfs/source/main.c
Normal file
58
examples/romfs/source/main.c
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
35
libctru/include/3ds/romfs.h
Normal file
35
libctru/include/3ds/romfs.h
Normal 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);
|
@ -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);
|
||||
|
570
libctru/include/3ds/services/cam.h
Normal file
570
libctru/include/3ds/services/cam.h
Normal 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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
484
libctru/source/romfs_dev.c
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
738
libctru/source/services/cam.c
Normal file
738
libctru/source/services/cam.c
Normal 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];
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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[] = {
|
||||
|
72
libctru/source/services/soc/soc_gethostbyaddr.c
Normal file
72
libctru/source/services/soc/soc_gethostbyaddr.c
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user