diff --git a/examples/gpu/Makefile b/examples/gpu/Makefile index f0728dc..bdda1a3 100644 --- a/examples/gpu/Makefile +++ b/examples/gpu/Makefile @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- diff --git a/examples/gpu/README.md b/examples/gpu/README.md index 7d7ecf7..2a118cc 100644 --- a/examples/gpu/README.md +++ b/examples/gpu/README.md @@ -4,8 +4,8 @@ gpu example of how to use the GPU with libctru before trying to compile, make sure to download aemstro -( https://github.com/smealum/aemstro reflog: 55bf5056d199e0e9ec3d136dc830ac45a49da074 ) -and update Makefile's AEMSTROPATH definition with the proper path +( https://github.com/smealum/aemstro reflog: 51bfeef9e1a0149726dca43b50919bd45917015a ) +and update AEMSTRO environment variable with the proper path You'll also need to install Python 3 and have that in your path. diff --git a/examples/gpu/data/test.vsh b/examples/gpu/data/test.vsh index 0da0e64..37293ae 100644 --- a/examples/gpu/data/test.vsh +++ b/examples/gpu/data/test.vsh @@ -1,56 +1,57 @@ -; make sure you update aemstro_as for this (15/11/14) - ; setup constants - .const 20, 1.0, 0.0, 0.5, 1.0 + .const c20, 1.0, 0.0, 0.5, 1.0 ; setup outmap - .out o0, result.position - .out o1, result.color - .out o2, result.texcoord0 - .out o3, result.texcoord1 - .out o4, result.texcoord2 - -; setup uniform map (required to use SHDR_GetUniformRegister) - .uniform 0, 3, projection ; c0-c3 = projection matrix - .uniform 4, 7, modelview ; c4-c7 = modelview matrix - .uniform 8, 8, lightDirection ; c8 = light direction vector - .uniform 9, 9, lightAmbient ; c9 = light ambient color + .out o0, result.position, 0x0 + .out o1, result.color, 0x0 + .out o2, result.texcoord0, 0x0 + .out o3, result.texcoord1, 0x0 + .out o4, result.texcoord2, 0x0 + +; setup uniform map (not required) + .uniform c0, c3, projection + .uniform c4, c7, modelview + .uniform c8, c8, lightDirection + .uniform c9, c9, lightAmbient + + .vsh vmain, end_vmain ;code - main: - mov r1, v0 (0x6) - mov r1, c20 (0x3) - ; tempreg = mdlvMtx * in.pos - dp4 r0, c4, r1 (0x0) - dp4 r0, c5, r1 (0x1) - dp4 r0, c6, r1 (0x2) - mov r0, c20 (0x3) - ; result.pos = projMtx * tempreg - dp4 o0, c0, r0 (0x0) - dp4 o0, c1, r0 (0x1) - dp4 o0, c2, r0 (0x2) - dp4 o0, c3, r0 (0x3) + vmain: + mov r1, v0 (0x4) + mov r1, c20 (0x3) + ; temp = modvMtx * in.pos + dp4 r0, c4, r1 (0x0) + dp4 r0, c5, r1 (0x1) + dp4 r0, c6, r1 (0x2) + mov r0, c20 (0x3) + ; result.pos = projMtx * temp + dp4 o0, c0, r0 (0x0) + dp4 o0, c1, r0 (0x1) + dp4 o0, c2, r0 (0x2) + dp4 o0, c3, r0 (0x3) ; result.texcoord = in.texcoord - mov o2, v1 (0x5) - mov o3, c20 (0x7) - mov o4, c20 (0x7) + mov o2, v1 (0x5) + mov o3, c20 (0x7) + mov o4, c20 (0x7) ; result.color = crappy lighting - dp3 r0, c8, v2 (0x6) - max r0, c20, r0 (0x4) - mul r0, c9, r0 (0x8) - add o1, c9, r0 (0x6) - mov o1, c20 (0x3) - flush + dp3 r0, c8, v2 (0x4) + max r0, c20, r0 (0x9) + mul r0, c9, r0 (0x4) + add o1, c9, r0 (0x4) + mov o1, c20 (0x3) + nop end - endmain: + end_vmain: ;operand descriptors .opdesc x___, xyzw, xyzw ; 0x0 .opdesc _y__, xyzw, xyzw ; 0x1 .opdesc __z_, xyzw, xyzw ; 0x2 .opdesc ___w, xyzw, xyzw ; 0x3 - .opdesc xyz_, yyyy, xyzw ; 0x4 + .opdesc xyz_, xyzw, xyzw ; 0x4 .opdesc xyzw, xyzw, xyzw ; 0x5 - .opdesc xyz_, xyzw, xyzw ; 0x6 + .opdesc x_zw, xyzw, xyzw ; 0x6 .opdesc xyzw, yyyw, xyzw ; 0x7 - .opdesc xyz_, wwww, xyzw ; 0x8 + .opdesc xyz_, wwww, wwww ; 0x8 + .opdesc xyz_, yyyy, xyzw ; 0x9 diff --git a/examples/graphics/bitmap/24bit-color/Makefile b/examples/graphics/bitmap/24bit-color/Makefile index acbfaf4..d91ef1b 100755 --- a/examples/graphics/bitmap/24bit-color/Makefile +++ b/examples/graphics/bitmap/24bit-color/Makefile @@ -118,6 +118,9 @@ endif IMAGEMAGICK := $(shell which convert) +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif .PHONY: $(BUILD) clean all diff --git a/examples/graphics/printing/hello-world/Makefile b/examples/graphics/printing/hello-world/Makefile index 8dce08d..542abb4 100755 --- a/examples/graphics/printing/hello-world/Makefile +++ b/examples/graphics/printing/hello-world/Makefile @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- diff --git a/examples/http/Makefile b/examples/http/Makefile index 8dce08d..542abb4 100644 --- a/examples/http/Makefile +++ b/examples/http/Makefile @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- diff --git a/examples/input/Makefile b/examples/input/Makefile new file mode 100644 index 0000000..bce05ec --- /dev/null +++ b/examples/input/Makefile @@ -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; diff --git a/examples/input/read-controls/Makefile b/examples/input/read-controls/Makefile index c21562a..b277846 100755 --- a/examples/input/read-controls/Makefile +++ b/examples/input/read-controls/Makefile @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- diff --git a/examples/input/touch-screen/Makefile b/examples/input/touch-screen/Makefile new file mode 100755 index 0000000..542abb4 --- /dev/null +++ b/examples/input/touch-screen/Makefile @@ -0,0 +1,174 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=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. +# 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): +# - .png +# - icon.png +# - /default_icon.png +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# 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 + +.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)),) +.PHONY: all +all : $(OUTPUT).3dsx $(OUTPUT).smdh +endif +$(OUTPUT).3dsx : $(OUTPUT).elf +$(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 +#--------------------------------------------------------------------------------------- diff --git a/examples/input/touch-screen/source/main.c b/examples/input/touch-screen/source/main.c new file mode 100644 index 0000000..7a06db0 --- /dev/null +++ b/examples/input/touch-screen/source/main.c @@ -0,0 +1,60 @@ +/* + Touch Screen example made by Aurelio Mannara for ctrulib + Please refer to https://github.com/smealum/ctrulib/blob/master/libctru/include/3ds/services/hid.h for more information + This code was modified for the last time on: 12/13/2014 2:30 UTC+1 + + This wouldn't be possible without the amazing work done by: + -Smealum + -fincs + -WinterMute + -yellows8 + -plutoo + -mtheall + -Many others who worked on 3DS and I'm surely forgetting about +*/ + +#include <3ds.h> +#include + +int main(int argc, char **argv) +{ + gfxInitDefault(); + + //Initialize console on top screen. Using NULL as the second argument tells the console library to use the internal console structure as current one + consoleInit(GFX_TOP, NULL); + + printf("\x1b[0;0HPress Start to exit."); + printf("\x1b[1;0HTouch Screen position:"); + + // Main loop + while (aptMainLoop()) + { + //Scan all the inputs. This should be done once for each frame + hidScanInput(); + + //hidKeysDown returns information about which buttons have been just pressed (and they weren't in the previous frame) + u32 kDown = hidKeysDown(); + + if (kDown & KEY_START) break; // break in order to return to hbmenu + + touchPosition touch; + + //Read the touch screen coordinates + hidTouchRead(&touch); + + //Print the touch screen coordinates + printf("\x1b[2;0H%03d; %03d", touch.px, touch.py); + + + // Flush and swap framebuffers + gfxFlushBuffers(); + gfxSwapBuffers(); + + //Wait for VBlank + gspWaitForVBlank(); + } + + // Exit services + gfxExit(); + return 0; +} diff --git a/examples/libapplet_launch/Makefile b/examples/libapplet_launch/Makefile index 8dce08d..542abb4 100644 --- a/examples/libapplet_launch/Makefile +++ b/examples/libapplet_launch/Makefile @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- diff --git a/examples/mvd/Makefile b/examples/mvd/Makefile index 8dce08d..542abb4 100644 --- a/examples/mvd/Makefile +++ b/examples/mvd/Makefile @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- diff --git a/examples/qtm/Makefile b/examples/qtm/Makefile index e6815d1..c366428 100644 --- a/examples/qtm/Makefile +++ b/examples/qtm/Makefile @@ -117,6 +117,10 @@ ifeq ($(strip $(NO_SMDH)),) export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- diff --git a/examples/sdmc/Makefile b/examples/sdmc/Makefile index 8dce08d..542abb4 100644 --- a/examples/sdmc/Makefile +++ b/examples/sdmc/Makefile @@ -113,6 +113,10 @@ else export APP_ICON := $(TOPDIR)/$(ICON) endif +ifeq ($(strip $(NO_SMDH)),) + export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- diff --git a/examples/threads/Makefile b/examples/threads/Makefile new file mode 100644 index 0000000..bce05ec --- /dev/null +++ b/examples/threads/Makefile @@ -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; diff --git a/examples/threads/event/Makefile b/examples/threads/event/Makefile new file mode 100644 index 0000000..2ed6a29 --- /dev/null +++ b/examples/threads/event/Makefile @@ -0,0 +1,163 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=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. +# 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): +# - .png +# - icon.png +# - /default_icon.png +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# 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 + +.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) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/examples/threads/event/source/main.c b/examples/threads/event/source/main.c new file mode 100644 index 0000000..1fcec86 --- /dev/null +++ b/examples/threads/event/source/main.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include + + +#include <3ds.h> + +Handle threadHandle, threadRequest; + +#define STACKSIZE (4 * 1024) + +volatile bool threadExit = false; + +volatile int threadcount=0; + +void threadMain(void *arg) { + + while(1) { + svcWaitSynchronization(threadRequest, U64_MAX); + svcClearEvent(threadRequest); + + if(threadExit) svcExitThread(); + + threadcount++; + } +} + +int main(int argc, char** argv) { + + + gfxInitDefault(); + + consoleInit(GFX_TOP, NULL); + + + svcCreateEvent(&threadRequest,0); + u32 *threadStack = memalign(32, STACKSIZE); + Result ret = svcCreateThread(&threadHandle, threadMain, 0, &threadStack[STACKSIZE/4], 0x3f, 0); + + printf("thread create returned %x\n", ret); + + // Main loop + while (aptMainLoop()) + { + gspWaitForVBlank(); + hidScanInput(); + + printf("\x1b[5;0H"); + printf("thread counter = %d\n",threadcount); + + u32 kDown = hidKeysDown(); + if (kDown & KEY_START) + break; // break in order to return to hbmenu + + if (kDown & KEY_A) + svcSignalEvent(threadRequest); + + // Flush and swap framebuffers + gfxFlushBuffers(); + gfxSwapBuffers(); + } + + // tell thread to exit + threadExit = true; + + // signal the thread + svcSignalEvent(threadRequest); + + // give it time to exit + svcSleepThread(10000000ULL); + + // close handles and free allocated stack + svcCloseHandle(threadRequest); + svcCloseHandle(threadHandle); + free(threadStack); + + + gfxExit(); + return 0; +} diff --git a/libctru/Makefile b/libctru/Makefile index 8a5c00c..bacf4e3 100644 --- a/libctru/Makefile +++ b/libctru/Makefile @@ -10,7 +10,7 @@ include $(DEVKITARM)/base_rules export LIBCTRU_MAJOR := 0 export LIBCTRU_MINOR := 4 -export LIBCTRU_PATCH := 0 +export LIBCTRU_PATCH := 1 VERSION := $(LIBCTRU_MAJOR).$(LIBCTRU_MINOR).$(LIBCTRU_PATCH) diff --git a/libctru/include/3ds/svc.h b/libctru/include/3ds/svc.h index 271408f..a95674b 100644 --- a/libctru/include/3ds/svc.h +++ b/libctru/include/3ds/svc.h @@ -86,6 +86,14 @@ s32 svcGetSystemInfo(s64* out, u32 type, s32 param); s32 svcGetProcessInfo(s64* out, Handle process, u32 type); s32 svcConnectToPort(volatile Handle* out, const char* portName); s32 svcSendSyncRequest(Handle session); +Result svcOpenProcess(Handle* process, u32 processId); s32 svcGetProcessId(u32 *out, Handle handle); s32 svcGetThreadId(u32 *out, Handle handle); s32 svcOutputDebugString(const char* str, int length); +Result svcCreatePort(Handle* portServer, Handle* portClient, const char* name, s32 maxSessions); +Result svcDebugActiveProcess(Handle* debug, u32 processId); +Result svcGetProcessList(s32* processCount, u32* processIds, s32 processIdMaxCount); +Result svcReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size); +Result svcMapProcessMemory(Handle process, u32 startAddr, u32 endAddr); +Result svcUnmapProcessMemory(Handle process, u32 startAddr, u32 endAddr); +Result svcQueryProcessMemory(MemInfo* info, PageInfo* out, Handle process, u32 addr); diff --git a/libctru/source/console.c b/libctru/source/console.c index 6346d25..e7ea8bd 100644 --- a/libctru/source/console.c +++ b/libctru/source/console.c @@ -528,6 +528,9 @@ PrintConsole* consoleInit(gfxScreen_t screen, PrintConsole* console) { gfxSetScreenFormat(screen,GSP_RGB565_OES); gfxSetDoubleBuffering(screen,false); + gfxSwapBuffers(); + gspWaitForVBlank(); + console->frameBuffer = (u16*)gfxGetFramebuffer(screen, GFX_LEFT, NULL, NULL); if(screen==GFX_TOP) { diff --git a/libctru/source/os.c b/libctru/source/os.c index d0287ad..090eb95 100644 --- a/libctru/source/os.c +++ b/libctru/source/os.c @@ -2,9 +2,17 @@ #include <3ds/os.h> #include <3ds/svc.h> +#include +#include +#define TICKS_PER_USEC 268.123480 #define TICKS_PER_MSEC 268123.480 +// Work around the VFP not supporting 64-bit integer <--> floating point conversion +static inline double u64_to_double(u64 value) { + return (((double)(u32)(value >> 32))*0x100000000ULL+(u32)value); +} + typedef struct { u64 date_time; u64 update_tick; @@ -19,8 +27,9 @@ static volatile datetime_t* __datetime1 = (datetime_t*) 0x1FF81040; -u32 osConvertVirtToPhys(u32 vaddr) -{ +//--------------------------------------------------------------------------------- +u32 osConvertVirtToPhys(u32 vaddr) { +//--------------------------------------------------------------------------------- if(vaddr >= 0x14000000 && vaddr < 0x1c000000) return vaddr + 0x0c000000; // LINEAR heap if(vaddr >= 0x1F000000 && vaddr < 0x1F600000) @@ -32,15 +41,17 @@ u32 osConvertVirtToPhys(u32 vaddr) return 0; } -u32 osConvertOldLINEARMemToNew(u32 vaddr) -{ +//--------------------------------------------------------------------------------- +u32 osConvertOldLINEARMemToNew(u32 vaddr) { +//--------------------------------------------------------------------------------- if(vaddr >= 0x30000000 && vaddr < 0x40000000)return vaddr; if(vaddr >= 0x14000000 && vaddr < 0x1c000000)return vaddr+=0x1c000000; return 0; } -// Returns number of milliseconds since 1st Jan 1900 00:00. -u64 osGetTime() { +//--------------------------------------------------------------------------------- +static datetime_t getSysTime() { +//--------------------------------------------------------------------------------- u32 s1, s2 = *__datetime_selector & 1; datetime_t dt; @@ -53,26 +64,64 @@ u64 osGetTime() { s2 = *__datetime_selector & 1; } while(s2 != s1); - u64 delta = svcGetSystemTick() - dt.update_tick; - - // Work around the VFP not supporting 64-bit integer <--> floating point conversion - double temp = (u32)(delta >> 32); - temp *= 0x100000000ULL; - temp += (u32)delta; - - u32 offset = temp / TICKS_PER_MSEC; - return dt.date_time + offset; + return dt; } +//--------------------------------------------------------------------------------- +int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz) { +//--------------------------------------------------------------------------------- + if (tp != NULL) { + + datetime_t dt = getSysTime(); + + u64 delta = svcGetSystemTick() - dt.update_tick; + + u32 offset = (u32)(u64_to_double(delta)/TICKS_PER_USEC); + + // adjust from 1900 to 1970 + u64 now = ((dt.date_time - 2208988800000ULL) * 1000) + offset; + + tp->tv_sec = u64_to_double(now)/1000000.0; + tp->tv_usec = now - ((tp->tv_sec) * 1000000); + + } + + if (tz != NULL) { + tz->tz_minuteswest = 0; + tz->tz_dsttime = 0; + } + + return 0; + +} + + +// Returns number of milliseconds since 1st Jan 1900 00:00. +//--------------------------------------------------------------------------------- +u64 osGetTime() { +//--------------------------------------------------------------------------------- + datetime_t dt = getSysTime(); + + u64 delta = svcGetSystemTick() - dt.update_tick; + + return dt.date_time + (u32)(u64_to_double(delta)/TICKS_PER_MSEC); +} + +//--------------------------------------------------------------------------------- u32 osGetFirmVersion() { +//--------------------------------------------------------------------------------- return (*(u32*)0x1FF80000) & ~0xFF; } +//--------------------------------------------------------------------------------- u32 osGetKernelVersion() { +//--------------------------------------------------------------------------------- return (*(u32*)0x1FF80060) & ~0xFF; } +//--------------------------------------------------------------------------------- const char* osStrError(u32 error) { +//--------------------------------------------------------------------------------- switch((error>>26) & 0x3F) { case 0: return "Success."; diff --git a/libctru/source/services/csnd.c b/libctru/source/services/csnd.c index 994443f..82767a9 100644 --- a/libctru/source/services/csnd.c +++ b/libctru/source/services/csnd.c @@ -405,6 +405,8 @@ Result csndPlaySound(int chn, u32 flags, u32 sampleRate, void* data0, void* data int encoding = (flags >> 12) & 3; int loopMode = (flags >> 10) & 3; + if (!loopMode) flags |= CSND_LOOPMODE_ONESHOT; + if (encoding != CSND_ENCODING_PSG) { if (data0) paddr0 = osConvertVirtToPhys((u32)data0); diff --git a/libctru/source/svc.s b/libctru/source/svc.s index 555eb13..18ee93e 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -247,6 +247,15 @@ svcSendSyncRequest: svc 0x32 bx lr +.global svcOpenProcess +.type svcOpenProcess, %function +svcOpenProcess: + push {r0} + svc 0x33 + pop {r2} + str r1, [r2] + bx lr + .global svcGetProcessId .type svcGetProcessId, %function svcGetProcessId: @@ -288,3 +297,67 @@ svcGetThreadId: ldr r3, [sp], #4 str r1, [r3] bx lr + +.global svcCreatePort +.type svcCreatePort, %function +svcCreatePort: + push {r0, r1} + svc 0x47 + ldr r3, [sp, #0] + str r1, [r3] + ldr r3, [sp, #4] + str r2, [r3] + add sp, sp, #8 + bx lr + +.global svcDebugActiveProcess +.type svcDebugActiveProcess, %function +svcDebugActiveProcess: + push {r0} + svc 0x60 + pop {r2} + str r1, [r2] + bx lr + +.global svcGetProcessList +.type svcGetProcessList, %function +svcGetProcessList: + push {r0, r1} + svc 0x65 + ldr r3, [sp, #0] + str r1, [r3] + ldr r3, [sp, #4] + str r2, [r3] + add sp, sp, #8 + bx lr + +.global svcReadProcessMemory +.type svcReadProcessMemory, %function +svcReadProcessMemory: + svc 0x6A + bx lr + +.global svcMapProcessMemory +.type svcMapProcessMemory, %function +svcMapProcessMemory: + svc 0x71 + bx lr + +.global svcUnmapProcessMemory +.type svcUnmapProcessMemory, %function +svcUnmapProcessMemory: + svc 0x72 + bx lr + +.global svcQueryProcessMemory +.type svcQueryProcessMemory, %function +svcQueryProcessMemory: + push {r0, r1, r4-r6} + svc 0x7D + ldr r6, [sp] + stm r6, {r1-r4} + ldr r6, [sp, #4] + str r5, [r6] + add sp, sp, #8 + pop {r4-r6} + bx lr diff --git a/libctru/source/system/initSystem.c b/libctru/source/system/initSystem.c index c14c455..4f1c597 100644 --- a/libctru/source/system/initSystem.c +++ b/libctru/source/system/initSystem.c @@ -1,4 +1,6 @@ #include +#include + #include #include <3ds/types.h> #include <3ds/svc.h> @@ -14,12 +16,15 @@ void __appInit(); void __ctru_exit(int rc); +int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz); void __attribute__((weak)) __libctru_init(void (*retAddr)(void)) { // Register newlib exit() syscall __syscalls.exit = __ctru_exit; + __syscalls.gettod_r = __libctru_gtod; + __system_retAddr = __service_ptr ? retAddr : NULL; __system_allocateHeaps();