From 20e542c2c888a6c6608183667933792504d4b0b5 Mon Sep 17 00:00:00 2001 From: fincs Date: Thu, 24 Dec 2015 12:39:26 +0100 Subject: [PATCH] Examples have been moved to https://github.com/devkitPro/3ds-examples --- .gitignore | 1 + examples/.gitignore | 3 - examples/Makefile | 26 -- examples/app_launch/Makefile | 196 -------------- examples/app_launch/README.md | 9 - examples/app_launch/source/main.c | 49 ---- examples/audio/mic/Makefile | 196 -------------- examples/audio/mic/README.md | 5 - examples/audio/mic/source/main.c | 102 -------- examples/camera/image/Makefile | 196 -------------- examples/camera/image/README.md | 7 - examples/camera/image/image.xml | 3 - examples/camera/image/src/main.c | 190 -------------- examples/camera/video/Makefile | 196 -------------- examples/camera/video/README.md | 7 - examples/camera/video/src/main.c | 206 --------------- examples/camera/video/video.xml | 3 - examples/get_system_language/Makefile | 196 -------------- examples/get_system_language/README.md | 4 - examples/get_system_language/source/main.c | 46 ---- examples/graphics/Makefile | 7 - examples/graphics/bitmap/24bit-color/Makefile | 193 -------------- .../graphics/bitmap/24bit-color/README.md | 16 -- .../graphics/bitmap/24bit-color/gfx/brew.png | Bin 141315 -> 0 bytes .../graphics/bitmap/24bit-color/source/main.c | 64 ----- examples/graphics/gpu/Makefile | 7 - examples/graphics/gpu/geoshader/Makefile | 177 ------------- examples/graphics/gpu/geoshader/README.md | 6 - .../graphics/gpu/geoshader/source/3dmath.c | 172 ------------ .../graphics/gpu/geoshader/source/3dmath.h | 56 ---- examples/graphics/gpu/geoshader/source/gpu.c | 94 ------- examples/graphics/gpu/geoshader/source/gpu.h | 26 -- .../gpu/geoshader/source/gshader.pica | 91 ------- examples/graphics/gpu/geoshader/source/main.c | 139 ---------- .../gpu/geoshader/source/vshader.pica | 24 -- examples/graphics/gpu/simple_tri/Makefile | 177 ------------- examples/graphics/gpu/simple_tri/README.md | 6 - .../graphics/gpu/simple_tri/source/3dmath.c | 172 ------------ .../graphics/gpu/simple_tri/source/3dmath.h | 56 ---- examples/graphics/gpu/simple_tri/source/gpu.c | 94 ------- examples/graphics/gpu/simple_tri/source/gpu.h | 26 -- .../graphics/gpu/simple_tri/source/main.c | 131 ---------- .../gpu/simple_tri/source/vshader.pica | 34 --- examples/graphics/gpu/textured_cube/Makefile | 177 ------------- examples/graphics/gpu/textured_cube/README.md | 6 - .../gpu/textured_cube/data/kitten.bin | Bin 16384 -> 0 bytes .../gpu/textured_cube/source/3dmath.c | 172 ------------ .../gpu/textured_cube/source/3dmath.h | 56 ---- .../graphics/gpu/textured_cube/source/gpu.c | 94 ------- .../graphics/gpu/textured_cube/source/gpu.h | 26 -- .../graphics/gpu/textured_cube/source/main.c | 244 ------------------ .../gpu/textured_cube/source/vshader.pica | 90 ------- examples/graphics/printing/Makefile | 7 - .../printing/both-screen-text/Makefile | 196 -------------- .../printing/both-screen-text/source/main.c | 57 ---- .../graphics/printing/colored-text/Makefile | 196 -------------- .../printing/colored-text/source/main.c | 69 ----- .../graphics/printing/hello-world/Makefile | 196 -------------- .../printing/hello-world/source/main.c | 46 ---- .../printing/multiple-windows-text/Makefile | 196 -------------- .../multiple-windows-text/source/main.c | 66 ----- examples/http/Makefile | 196 -------------- examples/http/README.md | 4 - examples/http/source/main.c | 113 -------- examples/input/Makefile | 7 - examples/input/read-controls/Makefile | 196 -------------- examples/input/read-controls/source/main.c | 105 -------- examples/input/touch-screen/Makefile | 196 -------------- examples/input/touch-screen/source/main.c | 60 ----- examples/libapplet_launch/Makefile | 196 -------------- examples/libapplet_launch/README.md | 7 - examples/libapplet_launch/source/main.c | 45 ---- examples/mvd/Makefile | 196 -------------- examples/mvd/README.md | 1 - examples/mvd/source/costable.h | 6 - examples/mvd/source/main.c | 143 ---------- examples/qtm/Makefile | 196 -------------- examples/qtm/README.md | 6 - examples/qtm/source/main.c | 85 ------ examples/romfs/Makefile | 196 -------------- examples/romfs/romfs/folder/file.txt | 6 - examples/romfs/romfs/フォルダ/ファイル.txt | 2 - examples/romfs/source/main.c | 58 ----- examples/sdmc/Makefile | 196 -------------- examples/sdmc/README.md | 5 - examples/sdmc/source/costable.c | 50 ---- examples/sdmc/source/costable.h | 6 - examples/sdmc/source/main.c | 98 ------- examples/sdmc/test.bin | 1 - examples/templates/Makefile | 7 - examples/templates/application/Makefile | 196 -------------- examples/templates/application/README.md | 3 - examples/templates/application/source/main.c | 37 --- examples/templates/library/Makefile | 122 --------- examples/templates/library/README.md | 3 - .../templates/library/include/templatelib.h | 6 - .../templates/library/source/templatelib.c | 6 - examples/threads/Makefile | 7 - examples/threads/event/Makefile | 196 -------------- examples/threads/event/source/main.c | 71 ----- examples/threads/thread-basic/Makefile | 196 -------------- examples/threads/thread-basic/source/main.c | 65 ----- examples/time/rtc/Makefile | 196 -------------- examples/time/rtc/source/main.c | 66 ----- exportdoc.sh | 1 + libctru/include/3ds.h | 40 +-- 106 files changed, 4 insertions(+), 8893 deletions(-) delete mode 100644 examples/.gitignore delete mode 100644 examples/Makefile delete mode 100644 examples/app_launch/Makefile delete mode 100644 examples/app_launch/README.md delete mode 100644 examples/app_launch/source/main.c delete mode 100644 examples/audio/mic/Makefile delete mode 100644 examples/audio/mic/README.md delete mode 100644 examples/audio/mic/source/main.c delete mode 100644 examples/camera/image/Makefile delete mode 100644 examples/camera/image/README.md delete mode 100644 examples/camera/image/image.xml delete mode 100644 examples/camera/image/src/main.c delete mode 100644 examples/camera/video/Makefile delete mode 100644 examples/camera/video/README.md delete mode 100644 examples/camera/video/src/main.c delete mode 100644 examples/camera/video/video.xml delete mode 100644 examples/get_system_language/Makefile delete mode 100644 examples/get_system_language/README.md delete mode 100644 examples/get_system_language/source/main.c delete mode 100644 examples/graphics/Makefile delete mode 100644 examples/graphics/bitmap/24bit-color/Makefile delete mode 100644 examples/graphics/bitmap/24bit-color/README.md delete mode 100644 examples/graphics/bitmap/24bit-color/gfx/brew.png delete mode 100644 examples/graphics/bitmap/24bit-color/source/main.c delete mode 100644 examples/graphics/gpu/Makefile delete mode 100644 examples/graphics/gpu/geoshader/Makefile delete mode 100644 examples/graphics/gpu/geoshader/README.md delete mode 100644 examples/graphics/gpu/geoshader/source/3dmath.c delete mode 100644 examples/graphics/gpu/geoshader/source/3dmath.h delete mode 100644 examples/graphics/gpu/geoshader/source/gpu.c delete mode 100644 examples/graphics/gpu/geoshader/source/gpu.h delete mode 100644 examples/graphics/gpu/geoshader/source/gshader.pica delete mode 100644 examples/graphics/gpu/geoshader/source/main.c delete mode 100644 examples/graphics/gpu/geoshader/source/vshader.pica delete mode 100644 examples/graphics/gpu/simple_tri/Makefile delete mode 100644 examples/graphics/gpu/simple_tri/README.md delete mode 100644 examples/graphics/gpu/simple_tri/source/3dmath.c delete mode 100644 examples/graphics/gpu/simple_tri/source/3dmath.h delete mode 100644 examples/graphics/gpu/simple_tri/source/gpu.c delete mode 100644 examples/graphics/gpu/simple_tri/source/gpu.h delete mode 100644 examples/graphics/gpu/simple_tri/source/main.c delete mode 100644 examples/graphics/gpu/simple_tri/source/vshader.pica delete mode 100644 examples/graphics/gpu/textured_cube/Makefile delete mode 100644 examples/graphics/gpu/textured_cube/README.md delete mode 100644 examples/graphics/gpu/textured_cube/data/kitten.bin delete mode 100644 examples/graphics/gpu/textured_cube/source/3dmath.c delete mode 100644 examples/graphics/gpu/textured_cube/source/3dmath.h delete mode 100644 examples/graphics/gpu/textured_cube/source/gpu.c delete mode 100644 examples/graphics/gpu/textured_cube/source/gpu.h delete mode 100644 examples/graphics/gpu/textured_cube/source/main.c delete mode 100644 examples/graphics/gpu/textured_cube/source/vshader.pica delete mode 100644 examples/graphics/printing/Makefile delete mode 100644 examples/graphics/printing/both-screen-text/Makefile delete mode 100644 examples/graphics/printing/both-screen-text/source/main.c delete mode 100644 examples/graphics/printing/colored-text/Makefile delete mode 100644 examples/graphics/printing/colored-text/source/main.c delete mode 100644 examples/graphics/printing/hello-world/Makefile delete mode 100644 examples/graphics/printing/hello-world/source/main.c delete mode 100644 examples/graphics/printing/multiple-windows-text/Makefile delete mode 100644 examples/graphics/printing/multiple-windows-text/source/main.c delete mode 100644 examples/http/Makefile delete mode 100644 examples/http/README.md delete mode 100644 examples/http/source/main.c delete mode 100644 examples/input/Makefile delete mode 100644 examples/input/read-controls/Makefile delete mode 100644 examples/input/read-controls/source/main.c delete mode 100644 examples/input/touch-screen/Makefile delete mode 100644 examples/input/touch-screen/source/main.c delete mode 100644 examples/libapplet_launch/Makefile delete mode 100644 examples/libapplet_launch/README.md delete mode 100644 examples/libapplet_launch/source/main.c delete mode 100644 examples/mvd/Makefile delete mode 100644 examples/mvd/README.md delete mode 100644 examples/mvd/source/costable.h delete mode 100644 examples/mvd/source/main.c delete mode 100644 examples/qtm/Makefile delete mode 100644 examples/qtm/README.md delete mode 100644 examples/qtm/source/main.c delete mode 100644 examples/romfs/Makefile delete mode 100644 examples/romfs/romfs/folder/file.txt delete mode 100644 examples/romfs/romfs/フォルダ/ファイル.txt delete mode 100644 examples/romfs/source/main.c delete mode 100644 examples/sdmc/Makefile delete mode 100644 examples/sdmc/README.md delete mode 100644 examples/sdmc/source/costable.c delete mode 100644 examples/sdmc/source/costable.h delete mode 100644 examples/sdmc/source/main.c delete mode 100644 examples/sdmc/test.bin delete mode 100644 examples/templates/Makefile delete mode 100644 examples/templates/application/Makefile delete mode 100644 examples/templates/application/README.md delete mode 100644 examples/templates/application/source/main.c delete mode 100644 examples/templates/library/Makefile delete mode 100644 examples/templates/library/README.md delete mode 100644 examples/templates/library/include/templatelib.h delete mode 100644 examples/templates/library/source/templatelib.c delete mode 100644 examples/threads/Makefile delete mode 100644 examples/threads/event/Makefile delete mode 100644 examples/threads/event/source/main.c delete mode 100644 examples/threads/thread-basic/Makefile delete mode 100644 examples/threads/thread-basic/source/main.c delete mode 100644 examples/time/rtc/Makefile delete mode 100644 examples/time/rtc/source/main.c diff --git a/.gitignore b/.gitignore index bdb1a70..9c3f938 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,6 @@ Thumbs.db build/ lib/ docs/ +examples/ internal_docs build.sh diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index a4149ca..0000000 --- a/examples/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -build/ -*.3dsx -*.elf diff --git a/examples/Makefile b/examples/Makefile deleted file mode 100644 index 444e135..0000000 --- a/examples/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -SUBDIRS:= $(shell ls | egrep -v '^(CVS)$$') - -DATESTRING := $(shell date +%Y)$(shell date +%m)$(shell date +%d) - -#--------------------------------------------------------------------------------- -all: examples -#--------------------------------------------------------------------------------- - @rm -fr bin - @mkdir -p bin - @find . -name "*.3dsx" ! -path "./bin/*" -exec cp -fv {} bin \; - -examples: - @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i || { exit 1;} fi; done; - -#--------------------------------------------------------------------------------- -clean: -#--------------------------------------------------------------------------------- - @rm -fr bin - @rm -f *.bz2 - @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i clean || { exit 1;} fi; done; - -#--------------------------------------------------------------------------------- -dist: clean -#--------------------------------------------------------------------------------- - @rm -fr bin - @tar --exclude=.svn --exclude=*CVS* -cvjf 3ds-examples-$(DATESTRING).tar.bz2 * diff --git a/examples/app_launch/Makefile b/examples/app_launch/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/app_launch/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/app_launch/README.md b/examples/app_launch/README.md deleted file mode 100644 index 2fa1986..0000000 --- a/examples/app_launch/README.md +++ /dev/null @@ -1,9 +0,0 @@ -app_launch -======= - -Example for launching other apps/applets with ctrulib. Press the A button to launch the app or applet specified in the source. - - -Note: The title ID of the EUR Nintendo 3DS Camera app is hardcoded and you need to change it if your 3DS is not an european one. See here for title IDs: http://3dbrew.org/wiki/Title_list#00040010_-_System_Applications -This example only works if launched as regular app by the home menu. It will not work with the homebrew menu. - diff --git a/examples/app_launch/source/main.c b/examples/app_launch/source/main.c deleted file mode 100644 index 6838e5c..0000000 --- a/examples/app_launch/source/main.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include <3ds.h> - - - -int main() -{ - gfxInitDefault(); // Init graphic stuff - - - // We need these 2 buffers for APT_DoAppJump() later. They can be smaller too - u8 buf0[0x300]; - u8 buf1[0x20]; - - - // Loop as long as the status is not exit - while(aptMainLoop()) - { - // Scan hid shared memory for input events - hidScanInput(); - - if(hidKeysDown() & KEY_A) // If the A button got pressed, start the app launch - { - // Clear both buffers - memset(buf0, 0, 0x300); - memset(buf1, 0, 0x20); - - // Open an APT session so we can talk to the APT service - aptOpenSession(); - // Prepare for the app launch - APT_PrepareToDoAppJump(0, 0x0004001000022400LL, 0); // *EUR* camera app title ID - // Tell APT to trigger the app launch and set the status of this app to exit - APT_DoAppJump(0x300 /* size of buf0 */, 0x20 /* size of buf1 */, buf0, buf1); - // Close the APT session because we don't need APT anymore - aptCloseSession(); - } - - // Flush + swap framebuffers and wait for VBlank. Not really needed in this example - gfxFlushBuffers(); - gfxSwapBuffers(); - gspWaitForVBlank(); - } - - - gfxExit(); - - return 0; -} diff --git a/examples/audio/mic/Makefile b/examples/audio/mic/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/audio/mic/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/audio/mic/README.md b/examples/audio/mic/README.md deleted file mode 100644 index f3e6d72..0000000 --- a/examples/audio/mic/README.md +++ /dev/null @@ -1,5 +0,0 @@ -mic -======= - -Example for using the microphone with ctrulib. Hold down the A button to record, the app will then play the recorded audio once the A button is released. Roughly 32 seconds of audio can be recorded with the default audiobuf size in this app. - diff --git a/examples/audio/mic/source/main.c b/examples/audio/mic/source/main.c deleted file mode 100644 index a180c4e..0000000 --- a/examples/audio/mic/source/main.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include -#include <3ds.h> - -int main() -{ - gfxInitDefault(); - consoleInit(GFX_BOTTOM, NULL); - - bool initialized = true; - - u32 micbuf_size = 0x30000; - u32 micbuf_pos = 0; - u8* micbuf = memalign(0x1000, micbuf_size); - - printf("Initializing CSND...\n"); - if(R_FAILED(csndInit())) - { - initialized = false; - printf("Could not initialize CSND.\n"); - } else printf("CSND initialized.\n"); - - printf("Initializing MIC...\n"); - if(R_FAILED(micInit(micbuf, micbuf_size))) - { - initialized = false; - printf("Could not initialize MIC.\n"); - } else printf("MIC initialized.\n"); - - u32 micbuf_datasize = micGetSampleDataSize(); - - u32 audiobuf_size = 0x100000; - u32 audiobuf_pos = 0; - u8* audiobuf = linearAlloc(audiobuf_size); - - if(initialized) printf("Hold A to record, release to play.\n"); - printf("Press START to exit.\n"); - - while(aptMainLoop()) - { - hidScanInput(); - gspWaitForVBlank(); - - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - if(initialized) - { - if(kDown & KEY_A) - { - audiobuf_pos = 0; - micbuf_pos = 0; - - printf("Stopping audio playback...\n"); - CSND_SetPlayState(0x8, 0); - if(R_FAILED(CSND_UpdateInfo(0))) printf("Failed to stop audio playback.\n"); - - printf("Starting sampling...\n"); - if(R_SUCCEEDED(MICU_StartSampling(MICU_ENCODING_PCM16_SIGNED, MICU_SAMPLE_RATE_16360, 0, micbuf_datasize, true))) printf("Now recording.\n"); - else printf("Failed to start sampling.\n"); - } - - if((hidKeysHeld() & KEY_A) && audiobuf_pos < audiobuf_size) - { - u32 micbuf_readpos = micbuf_pos; - micbuf_pos = micGetLastSampleOffset(); - while(audiobuf_pos < audiobuf_size && micbuf_readpos != micbuf_pos) - { - audiobuf[audiobuf_pos] = micbuf[micbuf_readpos]; - audiobuf_pos++; - micbuf_readpos = (micbuf_readpos + 1) % micbuf_datasize; - } - } - - if(hidKeysUp() & KEY_A) - { - printf("Stoping sampling...\n"); - if(R_FAILED(MICU_StopSampling())) printf("Failed to stop sampling.\n"); - - printf("Starting audio playback...\n"); - if(R_SUCCEEDED(GSPGPU_FlushDataCache(audiobuf, audiobuf_pos)) && R_SUCCEEDED(csndPlaySound(0x8, SOUND_ONE_SHOT | SOUND_FORMAT_16BIT, 16360, 1.0, 0.0, (u32*)audiobuf, NULL, audiobuf_pos))) printf("Now playing.\n"); - else printf("Failed to start playback.\n"); - } - } - - gfxFlushBuffers(); - gfxSwapBuffers(); - } - - linearFree(audiobuf); - - micExit(); - free(micbuf); - - csndExit(); - gfxExit(); - return 0; -} - diff --git a/examples/camera/image/Makefile b/examples/camera/image/Makefile deleted file mode 100644 index a56a373..0000000 --- a/examples/camera/image/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/camera/image/README.md b/examples/camera/image/README.md deleted file mode 100644 index 5c444a1..0000000 --- a/examples/camera/image/README.md +++ /dev/null @@ -1,7 +0,0 @@ -image -======= - -Example for using the camera to take 3D pictures with ctrulib. Press the R button to take a picture - it will be displayed on the top screen. - -Currently this example does not make use of the 3DS camera's calibration data to get a correct 3D effect. - diff --git a/examples/camera/image/image.xml b/examples/camera/image/image.xml deleted file mode 100644 index 30545b3..0000000 --- a/examples/camera/image/image.xml +++ /dev/null @@ -1,3 +0,0 @@ - - 0004001000021400 - diff --git a/examples/camera/image/src/main.c b/examples/camera/image/src/main.c deleted file mode 100644 index 3f2827d..0000000 --- a/examples/camera/image/src/main.c +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include -#include -#include -#include -#include <3ds.h> -#include -#include -#include -#include - -#define CONFIG_3D_SLIDERSTATE (*(volatile float*)0x1FF81080) -#define WAIT_TIMEOUT 300000000ULL - -#define WIDTH 400 -#define HEIGHT 240 -#define SCREEN_SIZE WIDTH * HEIGHT * 2 -#define BUF_SIZE SCREEN_SIZE * 2 - -static jmp_buf exitJmp; - -inline void clearScreen(void) { - u8 *frame = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); - memset(frame, 0, 320 * 240 * 3); -} - -void hang(char *message) { - clearScreen(); - printf("%s", message); - printf("Press start to exit"); - - while (aptMainLoop()) { - hidScanInput(); - - u32 kHeld = hidKeysHeld(); - if (kHeld & KEY_START) longjmp(exitJmp, 1); - } -} - -void cleanup() { - camExit(); - gfxExit(); - acExit(); -} - -void writePictureToFramebufferRGB565(void *fb, void *img, u16 x, u16 y, u16 width, u16 height) { - u8 *fb_8 = (u8*) fb; - u16 *img_16 = (u16*) img; - int i, j, draw_x, draw_y; - for(j = 0; j < height; j++) { - for(i = 0; i < width; i++) { - draw_y = y + height - j; - draw_x = x + i; - u32 v = (draw_y + draw_x * height) * 3; - u16 data = img_16[j * width + i]; - uint8_t b = ((data >> 11) & 0x1F) << 3; - uint8_t g = ((data >> 5) & 0x3F) << 2; - uint8_t r = (data & 0x1F) << 3; - fb_8[v] = r; - fb_8[v+1] = g; - fb_8[v+2] = b; - } - } -} - -// TODO: Figure out how to use CAMU_GetStereoCameraCalibrationData -void takePicture3D(u8 *buf) { - u32 bufSize; - printf("CAMU_GetMaxBytes: 0x%08X\n", (unsigned int) CAMU_GetMaxBytes(&bufSize, WIDTH, HEIGHT)); - printf("CAMU_SetTransferBytes: 0x%08X\n", (unsigned int) CAMU_SetTransferBytes(PORT_BOTH, bufSize, WIDTH, HEIGHT)); - - printf("CAMU_Activate: 0x%08X\n", (unsigned int) CAMU_Activate(SELECT_OUT1_OUT2)); - - Handle camReceiveEvent = 0; - Handle camReceiveEvent2 = 0; - - printf("CAMU_ClearBuffer: 0x%08X\n", (unsigned int) CAMU_ClearBuffer(PORT_BOTH)); - printf("CAMU_SynchronizeVsyncTiming: 0x%08X\n", (unsigned int) CAMU_SynchronizeVsyncTiming(SELECT_OUT1, SELECT_OUT2)); - - printf("CAMU_StartCapture: 0x%08X\n", (unsigned int) CAMU_StartCapture(PORT_BOTH)); - - printf("CAMU_SetReceiving: 0x%08X\n", (unsigned int) CAMU_SetReceiving(&camReceiveEvent, buf, PORT_CAM1, SCREEN_SIZE, (s16) bufSize)); - printf("CAMU_SetReceiving: 0x%08X\n", (unsigned int) CAMU_SetReceiving(&camReceiveEvent2, buf + SCREEN_SIZE, PORT_CAM2, SCREEN_SIZE, (s16) bufSize)); - printf("svcWaitSynchronization: 0x%08X\n", (unsigned int) svcWaitSynchronization(camReceiveEvent, WAIT_TIMEOUT)); - printf("svcWaitSynchronization: 0x%08X\n", (unsigned int) svcWaitSynchronization(camReceiveEvent2, WAIT_TIMEOUT)); - printf("CAMU_PlayShutterSound: 0x%08X\n", (unsigned int) CAMU_PlayShutterSound(SHUTTER_SOUND_TYPE_NORMAL)); - - printf("CAMU_StopCapture: 0x%08X\n", (unsigned int) CAMU_StopCapture(PORT_BOTH)); - - svcCloseHandle(camReceiveEvent); - svcCloseHandle(camReceiveEvent2); - - printf("CAMU_Activate: 0x%08X\n", (unsigned int) CAMU_Activate(SELECT_NONE)); -} - -int main() { - // Initializations - acInit(); - gfxInitDefault(); - consoleInit(GFX_BOTTOM, NULL); - - // Enable double buffering to remove screen tearing - gfxSetDoubleBuffering(GFX_TOP, true); - gfxSetDoubleBuffering(GFX_BOTTOM, false); - - // Save current stack frame for easy exit - if(setjmp(exitJmp)) { - cleanup(); - return 0; - } - - u32 kDown; - u32 kHeld; - - printf("Initializing camera\n"); - - printf("camInit: 0x%08X\n", (unsigned int) camInit()); - - printf("CAMU_SetSize: 0x%08X\n", (unsigned int) CAMU_SetSize(SELECT_OUT1_OUT2, SIZE_CTR_TOP_LCD, CONTEXT_A)); - printf("CAMU_SetOutputFormat: 0x%08X\n", (unsigned int) CAMU_SetOutputFormat(SELECT_OUT1_OUT2, OUTPUT_RGB_565, CONTEXT_A)); - - printf("CAMU_SetNoiseFilter: 0x%08X\n", (unsigned int) CAMU_SetNoiseFilter(SELECT_OUT1_OUT2, true)); - printf("CAMU_SetAutoExposure: 0x%08X\n", (unsigned int) CAMU_SetAutoExposure(SELECT_OUT1_OUT2, true)); - printf("CAMU_SetAutoWhiteBalance: 0x%08X\n", (unsigned int) CAMU_SetAutoWhiteBalance(SELECT_OUT1_OUT2, true)); - //printf("CAMU_SetEffect: 0x%08X\n", (unsigned int) CAMU_SetEffect(SELECT_OUT1_OUT2, EFFECT_MONO, CONTEXT_A)); - - printf("CAMU_SetTrimming: 0x%08X\n", (unsigned int) CAMU_SetTrimming(PORT_CAM1, false)); - printf("CAMU_SetTrimming: 0x%08X\n", (unsigned int) CAMU_SetTrimming(PORT_CAM2, false)); - //printf("CAMU_SetTrimmingParamsCenter: 0x%08X\n", (unsigned int) CAMU_SetTrimmingParamsCenter(PORT_CAM1, 512, 240, 512, 384)); - - u8 *buf = malloc(BUF_SIZE); - if(!buf) { - hang("Failed to allocate memory!"); - } - - gfxFlushBuffers(); - gspWaitForVBlank(); - gfxSwapBuffers(); - - bool held_R = false; - - printf("\nPress R to take a new picture\n"); - printf("Use slider to enable/disable 3D\n"); - printf("Press Start to exit to Homebrew Launcher\n"); - - // Main loop - while (aptMainLoop()) { - // Read which buttons are currently pressed or not - hidScanInput(); - kDown = hidKeysDown(); - kHeld = hidKeysHeld(); - - // If START button is pressed, break loop and quit - if (kDown & KEY_START) { - break; - } - - if ((kHeld & KEY_R) && !held_R) { - printf("Capturing new image\n"); - gfxFlushBuffers(); - gspWaitForVBlank(); - gfxSwapBuffers(); - held_R = true; - takePicture3D(buf); - } else if (!(kHeld & KEY_R)) { - held_R = false; - } - - if(CONFIG_3D_SLIDERSTATE > 0.0f) { - gfxSet3D(true); - writePictureToFramebufferRGB565(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), buf, 0, 0, WIDTH, HEIGHT); - writePictureToFramebufferRGB565(gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL), buf + SCREEN_SIZE, 0, 0, WIDTH, HEIGHT); - } else { - gfxSet3D(false); - writePictureToFramebufferRGB565(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), buf, 0, 0, WIDTH, HEIGHT); - } - - // Flush and swap framebuffers - gfxFlushBuffers(); - gspWaitForVBlank(); - gfxSwapBuffers(); - } - - // Exit - free(buf); - cleanup(); - - // Return to hbmenu - return 0; -} diff --git a/examples/camera/video/Makefile b/examples/camera/video/Makefile deleted file mode 100644 index a56a373..0000000 --- a/examples/camera/video/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/camera/video/README.md b/examples/camera/video/README.md deleted file mode 100644 index 7c1e3c1..0000000 --- a/examples/camera/video/README.md +++ /dev/null @@ -1,7 +0,0 @@ -video -======= - -Example for using the camera to capture 3D videos with ctrulib. - -Currently this example does not make use of the 3DS camera's calibration data to get a correct 3D effect. - diff --git a/examples/camera/video/src/main.c b/examples/camera/video/src/main.c deleted file mode 100644 index f083034..0000000 --- a/examples/camera/video/src/main.c +++ /dev/null @@ -1,206 +0,0 @@ -#include -#include -#include -#include -#include -#include <3ds.h> -#include -#include -#include -#include - -#define CONFIG_3D_SLIDERSTATE (*(volatile float*)0x1FF81080) -#define WAIT_TIMEOUT 1000000000ULL - -#define WIDTH 400 -#define HEIGHT 240 -#define SCREEN_SIZE WIDTH * HEIGHT * 2 -#define BUF_SIZE SCREEN_SIZE * 2 - -static jmp_buf exitJmp; - -inline void clearScreen(void) { - u8 *frame = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); - memset(frame, 0, 320 * 240 * 3); -} - -void hang(char *message) { - clearScreen(); - printf("%s", message); - printf("Press start to exit"); - - while (aptMainLoop()) { - hidScanInput(); - - u32 kHeld = hidKeysHeld(); - if (kHeld & KEY_START) longjmp(exitJmp, 1); - } -} - -void cleanup() { - camExit(); - gfxExit(); - acExit(); -} - -void writePictureToFramebufferRGB565(void *fb, void *img, u16 x, u16 y, u16 width, u16 height) { - u8 *fb_8 = (u8*) fb; - u16 *img_16 = (u16*) img; - int i, j, draw_x, draw_y; - for(j = 0; j < height; j++) { - for(i = 0; i < width; i++) { - draw_y = y + height - j; - draw_x = x + i; - u32 v = (draw_y + draw_x * height) * 3; - u16 data = img_16[j * width + i]; - uint8_t b = ((data >> 11) & 0x1F) << 3; - uint8_t g = ((data >> 5) & 0x3F) << 2; - uint8_t r = (data & 0x1F) << 3; - fb_8[v] = r; - fb_8[v+1] = g; - fb_8[v+2] = b; - } - } -} - -// TODO: Figure out how to use CAMU_GetStereoCameraCalibrationData -void takePicture3D(u8 *buf) { - u32 bufSize; - printf("CAMU_GetMaxBytes: 0x%08X\n", (unsigned int) CAMU_GetMaxBytes(&bufSize, WIDTH, HEIGHT)); - printf("CAMU_SetTransferBytes: 0x%08X\n", (unsigned int) CAMU_SetTransferBytes(PORT_BOTH, bufSize, WIDTH, HEIGHT)); - - printf("CAMU_Activate: 0x%08X\n", (unsigned int) CAMU_Activate(SELECT_OUT1_OUT2)); - - Handle camReceiveEvent = 0; - Handle camReceiveEvent2 = 0; - - printf("CAMU_ClearBuffer: 0x%08X\n", (unsigned int) CAMU_ClearBuffer(PORT_BOTH)); - printf("CAMU_SynchronizeVsyncTiming: 0x%08X\n", (unsigned int) CAMU_SynchronizeVsyncTiming(SELECT_OUT1, SELECT_OUT2)); - - printf("CAMU_StartCapture: 0x%08X\n", (unsigned int) CAMU_StartCapture(PORT_BOTH)); - - printf("CAMU_SetReceiving: 0x%08X\n", (unsigned int) CAMU_SetReceiving(&camReceiveEvent, buf, PORT_CAM1, SCREEN_SIZE, (s16) bufSize)); - printf("CAMU_SetReceiving: 0x%08X\n", (unsigned int) CAMU_SetReceiving(&camReceiveEvent2, buf + SCREEN_SIZE, PORT_CAM2, SCREEN_SIZE, (s16) bufSize)); - printf("svcWaitSynchronization: 0x%08X\n", (unsigned int) svcWaitSynchronization(camReceiveEvent, WAIT_TIMEOUT)); - printf("svcWaitSynchronization: 0x%08X\n", (unsigned int) svcWaitSynchronization(camReceiveEvent2, WAIT_TIMEOUT)); - printf("CAMU_PlayShutterSound: 0x%08X\n", (unsigned int) CAMU_PlayShutterSound(SHUTTER_SOUND_TYPE_NORMAL)); - - printf("CAMU_StopCapture: 0x%08X\n", (unsigned int) CAMU_StopCapture(PORT_BOTH)); - - svcCloseHandle(camReceiveEvent); - svcCloseHandle(camReceiveEvent2); - - printf("CAMU_Activate: 0x%08X\n", (unsigned int) CAMU_Activate(SELECT_NONE)); -} - -int main() { - // Initializations - acInit(); - gfxInitDefault(); - consoleInit(GFX_BOTTOM, NULL); - - // Enable double buffering to remove screen tearing - gfxSetDoubleBuffering(GFX_TOP, true); - gfxSetDoubleBuffering(GFX_BOTTOM, false); - - // Save current stack frame for easy exit - if(setjmp(exitJmp)) { - cleanup(); - return 0; - } - - u32 kDown; - - printf("Initializing camera\n"); - - printf("camInit: 0x%08X\n", (unsigned int) camInit()); - - printf("CAMU_SetSize: 0x%08X\n", (unsigned int) CAMU_SetSize(SELECT_OUT1_OUT2, SIZE_CTR_TOP_LCD, CONTEXT_A)); - printf("CAMU_SetOutputFormat: 0x%08X\n", (unsigned int) CAMU_SetOutputFormat(SELECT_OUT1_OUT2, OUTPUT_RGB_565, CONTEXT_A)); - - // TODO: For some reason frame grabbing times out above 10fps. Figure out why this is. - printf("CAMU_SetFrameRate: 0x%08X\n", (unsigned int) CAMU_SetFrameRate(SELECT_OUT1_OUT2, FRAME_RATE_10)); - - printf("CAMU_SetNoiseFilter: 0x%08X\n", (unsigned int) CAMU_SetNoiseFilter(SELECT_OUT1_OUT2, true)); - printf("CAMU_SetAutoExposure: 0x%08X\n", (unsigned int) CAMU_SetAutoExposure(SELECT_OUT1_OUT2, true)); - printf("CAMU_SetAutoWhiteBalance: 0x%08X\n", (unsigned int) CAMU_SetAutoWhiteBalance(SELECT_OUT1_OUT2, true)); - // TODO: Figure out how to use the effects properly. - //printf("CAMU_SetEffect: 0x%08X\n", (unsigned int) CAMU_SetEffect(SELECT_OUT1_OUT2, EFFECT_SEPIA, CONTEXT_A)); - - printf("CAMU_SetTrimming: 0x%08X\n", (unsigned int) CAMU_SetTrimming(PORT_CAM1, false)); - printf("CAMU_SetTrimming: 0x%08X\n", (unsigned int) CAMU_SetTrimming(PORT_CAM2, false)); - //printf("CAMU_SetTrimmingParamsCenter: 0x%08X\n", (unsigned int) CAMU_SetTrimmingParamsCenter(PORT_CAM1, 512, 240, 512, 384)); - - u8 *buf = malloc(BUF_SIZE); - if(!buf) { - hang("Failed to allocate memory!"); - } - - u32 bufSize; - printf("CAMU_GetMaxBytes: 0x%08X\n", (unsigned int) CAMU_GetMaxBytes(&bufSize, WIDTH, HEIGHT)); - printf("CAMU_SetTransferBytes: 0x%08X\n", (unsigned int) CAMU_SetTransferBytes(PORT_BOTH, bufSize, WIDTH, HEIGHT)); - - printf("CAMU_Activate: 0x%08X\n", (unsigned int) CAMU_Activate(SELECT_OUT1_OUT2)); - - Handle camReceiveEvent = 0; - Handle camReceiveEvent2 = 0; - - printf("CAMU_ClearBuffer: 0x%08X\n", (unsigned int) CAMU_ClearBuffer(PORT_BOTH)); - printf("CAMU_SynchronizeVsyncTiming: 0x%08X\n", (unsigned int) CAMU_SynchronizeVsyncTiming(SELECT_OUT1, SELECT_OUT2)); - - printf("CAMU_StartCapture: 0x%08X\n", (unsigned int) CAMU_StartCapture(PORT_BOTH)); - printf("CAMU_PlayShutterSound: 0x%08X\n", (unsigned int) CAMU_PlayShutterSound(SHUTTER_SOUND_TYPE_MOVIE)); - - gfxFlushBuffers(); - gspWaitForVBlank(); - gfxSwapBuffers(); - - printf("\nUse slider to enable/disable 3D\n"); - printf("Press Start to exit to Homebrew Launcher\n"); - - // Main loop - while (aptMainLoop()) { - // Read which buttons are currently pressed or not - hidScanInput(); - kDown = hidKeysDown(); - - // If START button is pressed, break loop and quit - if (kDown & KEY_START) { - break; - } - - printf("CAMU_SetReceiving: 0x%08X\n", (unsigned int) CAMU_SetReceiving(&camReceiveEvent, buf, PORT_CAM1, SCREEN_SIZE, (s16) bufSize)); - CAMU_SetReceiving(&camReceiveEvent2, buf + SCREEN_SIZE, PORT_CAM2, SCREEN_SIZE, (s16) bufSize); - - printf("svcWaitSynchronization: 0x%08X\n", (unsigned int) svcWaitSynchronization(camReceiveEvent, WAIT_TIMEOUT)); - svcWaitSynchronization(camReceiveEvent2, WAIT_TIMEOUT); - - if(CONFIG_3D_SLIDERSTATE > 0.0f) { - gfxSet3D(true); - writePictureToFramebufferRGB565(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), buf, 0, 0, WIDTH, HEIGHT); - writePictureToFramebufferRGB565(gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL), buf + SCREEN_SIZE, 0, 0, WIDTH, HEIGHT); - } else { - gfxSet3D(false); - writePictureToFramebufferRGB565(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), buf, 0, 0, WIDTH, HEIGHT); - } - - printf("svcCloseHandle: 0x%08X\n", (unsigned int) svcCloseHandle(camReceiveEvent)); - svcCloseHandle(camReceiveEvent2); - - // Flush and swap framebuffers - gfxFlushBuffers(); - gspWaitForVBlank(); - gfxSwapBuffers(); - } - - printf("CAMU_StopCapture: 0x%08X\n", (unsigned int) CAMU_StopCapture(PORT_BOTH)); - - printf("CAMU_Activate: 0x%08X\n", (unsigned int) CAMU_Activate(SELECT_NONE)); - - // Exit - free(buf); - cleanup(); - - // Return to hbmenu - return 0; -} diff --git a/examples/camera/video/video.xml b/examples/camera/video/video.xml deleted file mode 100644 index 30545b3..0000000 --- a/examples/camera/video/video.xml +++ /dev/null @@ -1,3 +0,0 @@ - - 0004001000021400 - diff --git a/examples/get_system_language/Makefile b/examples/get_system_language/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/get_system_language/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/get_system_language/README.md b/examples/get_system_language/README.md deleted file mode 100644 index a54dbd6..0000000 --- a/examples/get_system_language/README.md +++ /dev/null @@ -1,4 +0,0 @@ -get_system_language -======= - -This is an example on how to get the system language on the 3DS. diff --git a/examples/get_system_language/source/main.c b/examples/get_system_language/source/main.c deleted file mode 100644 index 2672f47..0000000 --- a/examples/get_system_language/source/main.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include <3ds.h> - - -int main(int argc, char** argv) -{ - // Initialize services - gfxInitDefault(); - cfguInit(); - - - u8 language = 0; - Result res; - - // Init console for text output - consoleInit(GFX_BOTTOM, NULL); - - // Read the language field from the config savegame. - res = CFGU_GetSystemLanguage(&language); - - // Print return value and language code - printf(" Result: 0x%x\n", (int)res); - printf("Language code: %d", (int)language); - - - // Main loop - while (aptMainLoop()) - { - hidScanInput(); - - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - gspWaitForVBlank(); - } - - // Exit services - cfguExit(); - gfxExit(); - return 0; -} diff --git a/examples/graphics/Makefile b/examples/graphics/Makefile deleted file mode 100644 index bce05ec..0000000 --- a/examples/graphics/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -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/graphics/bitmap/24bit-color/Makefile b/examples/graphics/bitmap/24bit-color/Makefile deleted file mode 100644 index d91ef1b..0000000 --- a/examples/graphics/bitmap/24bit-color/Makefile +++ /dev/null @@ -1,193 +0,0 @@ -#--------------------------------------------------------------------------------- -.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 := -INCLUDES := include -GRAPHICS := gfx - -#--------------------------------------------------------------------------------- -# 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)) \ - $(foreach dir,$(GRAPHICS),$(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)/*.*))) -PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) - -#--------------------------------------------------------------------------------- -# 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)) \ - $(PNGFILES:.png=.bgr.o) \ - $(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 - -IMAGEMAGICK := $(shell which convert) - -ifeq ($(strip $(NO_SMDH)),) - export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh -endif - -.PHONY: $(BUILD) clean all - -#--------------------------------------------------------------------------------- -ifeq ($(strip $(IMAGEMAGICK)),) - -all: - @echo "Image Magick not found!" - @echo - @echo "Please install Image Magick from http://www.imagemagick.org/ to build this example" - -else - -all: $(BUILD) - -endif - -#--------------------------------------------------------------------------------- -$(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) - - - -#--------------------------------------------------------------------------------- -%.bgr.o: %.bgr -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -#--------------------------------------------------------------------------------- -%.bgr: %.png -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @convert $< -rotate 90 $@ - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/graphics/bitmap/24bit-color/README.md b/examples/graphics/bitmap/24bit-color/README.md deleted file mode 100644 index 50fff6d..0000000 --- a/examples/graphics/bitmap/24bit-color/README.md +++ /dev/null @@ -1,16 +0,0 @@ -24bit Bitmap Example -======= - -This example shows on bottom screen an upscaled version of the nds examples Drunken Coders logo that can be found in devkitPro. - -If you want to try with your own image follow these steps: - -1. Download & install: http://www.imagemagick.org/ (If you get an option to add the application to the path make sure to check it!). -2. convert fileIn.png -channel B -separate fileIn.png -channel G -separate fileIn.png -channel R -separate -channel RGB -combine -rotate 90 fileOut.rgb -3. Rename fileOut.rgb in fileOut.bin -4. Copy fileOut.bin in the data folder of your project -5. Replace any reference of drunkenlogo_bin in main.cpp with fileOut_bin (or however you named it) -6. Re-Build the project - - -As you can see from the previos steps the image is clockwise rotated by 90 degrees and its B and R channels are swapped. The first operation is done because the 3DS screens are actually portrait screens rotated by 90 degrees (in a counter-clockwise direction), while the second one is done because the 3DS screens' framebuffers have a BGR888 color format, by default. \ No newline at end of file diff --git a/examples/graphics/bitmap/24bit-color/gfx/brew.png b/examples/graphics/bitmap/24bit-color/gfx/brew.png deleted file mode 100644 index 6ac625b6ea4fe55079023d9680359b8ca5ff4933..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141315 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ΠLI(R};W#OCQ6n>-LWT#7L7> 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

xQR9}vtSh^w*+c$ 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 diff --git a/examples/graphics/bitmap/24bit-color/source/main.c b/examples/graphics/bitmap/24bit-color/source/main.c deleted file mode 100644 index a6ac76e..0000000 --- a/examples/graphics/bitmap/24bit-color/source/main.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - Hello World example made by Aurelio Mannara for ctrulib - This code was modified for the last time on: 12/13/2014 01:00 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 -#include - -//This include a header containing definitions of our image -#include "brew_bgr.h" - -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("Why so sad Smealum? We can haz 3DS homebrew!"); - - printf("\x1b[20;15HPress Start to exit."); - - //We don't need double buffering in this example. In this way we can draw our image only once on screen. - gfxSetDoubleBuffering(GFX_BOTTOM, false); - - //Get the bottom screen's frame buffer - u8* fb = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); - - //Copy our image in the bottom screen's frame buffer - memcpy(fb, brew_bgr, brew_bgr_size); - - // 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 - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - - //Wait for VBlank - gspWaitForVBlank(); - } - - // Exit services - gfxExit(); - return 0; -} diff --git a/examples/graphics/gpu/Makefile b/examples/graphics/gpu/Makefile deleted file mode 100644 index bce05ec..0000000 --- a/examples/graphics/gpu/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -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/graphics/gpu/geoshader/Makefile b/examples/graphics/gpu/geoshader/Makefile deleted file mode 100644 index 3b72824..0000000 --- a/examples/graphics/gpu/geoshader/Makefile +++ /dev/null @@ -1,177 +0,0 @@ -#--------------------------------------------------------------------------------- -.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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pica))) -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)) $(PICAFILES:.pica=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rule for assembling GPU shaders -#--------------------------------------------------------------------------------- -%.shbin.o: %.pica - @echo $(notdir $<) - $(eval CURBIN := $(patsubst %.pica,%.shbin,$(notdir $<))) - $(eval CURH := $(patsubst %.pica,%.psh.h,$(notdir $<))) - @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 - @echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/graphics/gpu/geoshader/README.md b/examples/graphics/gpu/geoshader/README.md deleted file mode 100644 index 5e3b6dd..0000000 --- a/examples/graphics/gpu/geoshader/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# GPU example - -This is a simple GPU example using the `picasso` shader assembler which comes with devkitARM r45 and up. -Users of earlier versions of devkitARM need to install the tool, which can be found in the address below: - -https://github.com/fincs/picasso/releases diff --git a/examples/graphics/gpu/geoshader/source/3dmath.c b/examples/graphics/gpu/geoshader/source/3dmath.c deleted file mode 100644 index eb8d03f..0000000 --- a/examples/graphics/gpu/geoshader/source/3dmath.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "3dmath.h" - -void m4x4_identity(matrix_4x4* out) -{ - m4x4_zeros(out); - out->r[0].x = out->r[1].y = out->r[2].z = out->r[3].w = 1.0f; -} - -void m4x4_multiply(matrix_4x4* out, const matrix_4x4* a, const matrix_4x4* b) -{ - int i, j; - for (i = 0; i < 4; i ++) - for (j = 0; j < 4; j ++) - out->r[j].c[i] = a->r[j].x*b->r[0].c[i] + a->r[j].y*b->r[1].c[i] + a->r[j].z*b->r[2].c[i] + a->r[j].w*b->r[3].c[i]; -} - -void m4x4_translate(matrix_4x4* mtx, float x, float y, float z) -{ - matrix_4x4 tm, om; - - m4x4_identity(&tm); - tm.r[0].w = x; - tm.r[1].w = y; - tm.r[2].w = z; - - m4x4_multiply(&om, mtx, &tm); - m4x4_copy(mtx, &om); -} - -void m4x4_scale(matrix_4x4* mtx, float x, float y, float z) -{ - int i; - for (i = 0; i < 4; i ++) - { - mtx->r[i].x *= x; - mtx->r[i].y *= y; - mtx->r[i].z *= z; - } -} - -void m4x4_rotate_x(matrix_4x4* mtx, float angle, bool bRightSide) -{ - matrix_4x4 rm, om; - - float cosAngle = cosf(angle); - float sinAngle = sinf(angle); - - m4x4_zeros(&rm); - rm.r[0].x = 1.0f; - rm.r[1].y = cosAngle; - rm.r[1].z = sinAngle; - rm.r[2].y = -sinAngle; - rm.r[2].z = cosAngle; - rm.r[3].w = 1.0f; - - if (bRightSide) m4x4_multiply(&om, mtx, &rm); - else m4x4_multiply(&om, &rm, mtx); - m4x4_copy(mtx, &om); -} - -void m4x4_rotate_y(matrix_4x4* mtx, float angle, bool bRightSide) -{ - matrix_4x4 rm, om; - - float cosAngle = cosf(angle); - float sinAngle = sinf(angle); - - m4x4_zeros(&rm); - rm.r[0].x = cosAngle; - rm.r[0].z = sinAngle; - rm.r[1].y = 1.0f; - rm.r[2].x = -sinAngle; - rm.r[2].z = cosAngle; - rm.r[3].w = 1.0f; - - if (bRightSide) m4x4_multiply(&om, mtx, &rm); - else m4x4_multiply(&om, &rm, mtx); - m4x4_copy(mtx, &om); -} - -void m4x4_rotate_z(matrix_4x4* mtx, float angle, bool bRightSide) -{ - matrix_4x4 rm, om; - - float cosAngle = cosf(angle); - float sinAngle = sinf(angle); - - m4x4_zeros(&rm); - rm.r[0].x = cosAngle; - rm.r[0].y = sinAngle; - rm.r[1].x = -sinAngle; - rm.r[1].y = cosAngle; - rm.r[2].z = 1.0f; - rm.r[3].w = 1.0f; - - if (bRightSide) m4x4_multiply(&om, mtx, &rm); - else m4x4_multiply(&om, &rm, mtx); - m4x4_copy(mtx, &om); -} - -void m4x4_ortho_tilt(matrix_4x4* mtx, float left, float right, float bottom, float top, float near, float far) -{ - matrix_4x4 mp; - m4x4_zeros(&mp); - - // Build standard orthogonal projection matrix - mp.r[0].x = 2.0f / (right - left); - mp.r[0].w = (left + right) / (left - right); - mp.r[1].y = 2.0f / (top - bottom); - mp.r[1].w = (bottom + top) / (bottom - top); - mp.r[2].z = 2.0f / (near - far); - mp.r[2].w = (far + near) / (far - near); - mp.r[3].w = 1.0f; - - // Fix depth range to [-1, 0] - matrix_4x4 mp2, mp3; - m4x4_identity(&mp2); - mp2.r[2].z = 0.5; - mp2.r[2].w = -0.5; - m4x4_multiply(&mp3, &mp2, &mp); - - // Fix the 3DS screens' orientation by swapping the X and Y axis - m4x4_identity(&mp2); - mp2.r[0].x = 0.0; - mp2.r[0].y = 1.0; - mp2.r[1].x = -1.0; // flipped - mp2.r[1].y = 0.0; - m4x4_multiply(mtx, &mp2, &mp3); -} - -void m4x4_persp_tilt(matrix_4x4* mtx, float fovx, float invaspect, float near, float far) -{ - // Notes: - // We are passed "fovy" and the "aspect ratio". However, the 3DS screens are sideways, - // and so are these parameters -- in fact, they are actually the fovx and the inverse - // of the aspect ratio. Therefore the formula for the perspective projection matrix - // had to be modified to be expressed in these terms instead. - - // Notes: - // fovx = 2 atan(tan(fovy/2)*w/h) - // fovy = 2 atan(tan(fovx/2)*h/w) - // invaspect = h/w - - // a0,0 = h / (w*tan(fovy/2)) = - // = h / (w*tan(2 atan(tan(fovx/2)*h/w) / 2)) = - // = h / (w*tan( atan(tan(fovx/2)*h/w) )) = - // = h / (w * tan(fovx/2)*h/w) = - // = 1 / tan(fovx/2) - - // a1,1 = 1 / tan(fovy/2) = (...) = w / (h*tan(fovx/2)) - - float fovx_tan = tanf(fovx / 2); - matrix_4x4 mp; - m4x4_zeros(&mp); - - // Build standard perspective projection matrix - mp.r[0].x = 1.0f / fovx_tan; - mp.r[1].y = 1.0f / (fovx_tan*invaspect); - mp.r[2].z = (near + far) / (near - far); - mp.r[2].w = (2 * near * far) / (near - far); - mp.r[3].z = -1.0f; - - // Fix depth range to [-1, 0] - matrix_4x4 mp2; - m4x4_identity(&mp2); - mp2.r[2].z = 0.5; - mp2.r[2].w = -0.5; - m4x4_multiply(mtx, &mp2, &mp); - - // Rotate the matrix one quarter of a turn CCW in order to fix the 3DS screens' orientation - m4x4_rotate_z(mtx, M_PI / 2, true); -} diff --git a/examples/graphics/gpu/geoshader/source/3dmath.h b/examples/graphics/gpu/geoshader/source/3dmath.h deleted file mode 100644 index a9a8596..0000000 --- a/examples/graphics/gpu/geoshader/source/3dmath.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Bare-bones simplistic 3D math library - * This library is common to all libctru GPU examples - */ - -#pragma once -#include -#include -#include - -typedef union { struct { float w, z, y, x; }; float c[4]; } vector_4f; -typedef struct { vector_4f r[4]; } matrix_4x4; - -static inline float v4f_dp4(const vector_4f* a, const vector_4f* b) -{ - return a->x*b->x + a->y*b->y + a->z*b->z + a->w*b->w; -} - -static inline float v4f_mod4(const vector_4f* a) -{ - return sqrtf(v4f_dp4(a,a)); -} - -static inline void v4f_norm4(vector_4f* vec) -{ - float m = v4f_mod4(vec); - if (m == 0.0) return; - vec->x /= m; - vec->y /= m; - vec->z /= m; - vec->w /= m; -} - -static inline void m4x4_zeros(matrix_4x4* out) -{ - memset(out, 0, sizeof(*out)); -} - -static inline void m4x4_copy(matrix_4x4* out, const matrix_4x4* in) -{ - memcpy(out, in, sizeof(*out)); -} - -void m4x4_identity(matrix_4x4* out); -void m4x4_multiply(matrix_4x4* out, const matrix_4x4* a, const matrix_4x4* b); - -void m4x4_translate(matrix_4x4* mtx, float x, float y, float z); -void m4x4_scale(matrix_4x4* mtx, float x, float y, float z); - -void m4x4_rotate_x(matrix_4x4* mtx, float angle, bool bRightSide); -void m4x4_rotate_y(matrix_4x4* mtx, float angle, bool bRightSide); -void m4x4_rotate_z(matrix_4x4* mtx, float angle, bool bRightSide); - -// Special versions of the projection matrices that take the 3DS' screen orientation into account -void m4x4_ortho_tilt(matrix_4x4* mtx, float left, float right, float bottom, float top, float near, float far); -void m4x4_persp_tilt(matrix_4x4* mtx, float fovy, float aspect, float near, float far); diff --git a/examples/graphics/gpu/geoshader/source/gpu.c b/examples/graphics/gpu/geoshader/source/gpu.c deleted file mode 100644 index d16f1ff..0000000 --- a/examples/graphics/gpu/geoshader/source/gpu.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "gpu.h" - -#define DISPLAY_TRANSFER_FLAGS \ - (GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | \ - GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \ - GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)) - -static u32 *colorBuf, *depthBuf; -static u32 *cmdBuf; - -void gpuInit(void) -{ - colorBuf = vramAlloc(400*240*4); - depthBuf = vramAlloc(400*240*4); - cmdBuf = linearAlloc(0x40000*4); - - GPU_Init(NULL); - GPU_Reset(NULL, cmdBuf, 0x40000); -} - -void gpuExit(void) -{ - linearFree(cmdBuf); - vramFree(depthBuf); - vramFree(colorBuf); -} - -void gpuClearBuffers(u32 clearColor) -{ - GX_MemoryFill( - colorBuf, clearColor, &colorBuf[240*400], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH, - depthBuf, 0, &depthBuf[240*400], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH); - gspWaitForPSC0(); // Wait for the fill to complete -} - -void gpuFrameBegin(void) -{ - // Configure the viewport and the depth linear conversion function - GPU_SetViewport( - (u32*)osConvertVirtToPhys(depthBuf), - (u32*)osConvertVirtToPhys(colorBuf), - 0, 0, 240, 400); // The top screen is physically 240x400 pixels - GPU_DepthMap(-1.0f, 0.0f); // calculate the depth value from the Z coordinate in the following way: -1.0*z + 0.0 - - // Configure some boilerplate - GPU_SetFaceCulling(GPU_CULL_BACK_CCW); - GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); - 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); - - // This is unknown - GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); - GPUCMD_AddWrite(GPUREG_0118, 0); - - // Configure alpha blending and test - GPU_SetAlphaBlending(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); - GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00); - - int i; - for (i = 0; i < 6; i ++) - GPU_SetDummyTexEnv(i); -} - -void gpuFrameEnd(void) -{ - // Finish rendering - GPU_FinishDrawing(); - GPUCMD_Finalize(); - GPUCMD_FlushAndRun(); - gspWaitForP3D(); // Wait for the rendering to complete - - // Transfer the GPU output to the framebuffer - GX_DisplayTransfer( - colorBuf, GX_BUFFER_DIM(240, 400), - (u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), GX_BUFFER_DIM(240, 400), - DISPLAY_TRANSFER_FLAGS); - gspWaitForPPF(); // Wait for the transfer to complete - - // Reset the command buffer - GPUCMD_SetBufferOffset(0); -}; - -void GPU_SetDummyTexEnv(int id) -{ - GPU_SetTexEnv(id, - GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), - GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_REPLACE, - GPU_REPLACE, - 0xFFFFFFFF); -} diff --git a/examples/graphics/gpu/geoshader/source/gpu.h b/examples/graphics/gpu/geoshader/source/gpu.h deleted file mode 100644 index 845d139..0000000 --- a/examples/graphics/gpu/geoshader/source/gpu.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Bare-bones simplistic GPU wrapper - * This library is common to all libctru GPU examples - */ - -#pragma once -#include -#include <3ds.h> -#include "3dmath.h" - -void gpuInit(void); -void gpuExit(void); - -void gpuClearBuffers(u32 clearColor); - -void gpuFrameBegin(void); -void gpuFrameEnd(void); - -// Configures the specified fixed-function fragment shading substage to be a no-operation -void GPU_SetDummyTexEnv(int id); - -// Uploads an uniform matrix -static inline void GPU_SetFloatUniformMatrix(GPU_SHADER_TYPE type, int location, matrix_4x4* matrix) -{ - GPU_SetFloatUniform(type, location, (u32*)matrix, 4); -} diff --git a/examples/graphics/gpu/geoshader/source/gshader.pica b/examples/graphics/gpu/geoshader/source/gshader.pica deleted file mode 100644 index 3b65db3..0000000 --- a/examples/graphics/gpu/geoshader/source/gshader.pica +++ /dev/null @@ -1,91 +0,0 @@ -; Example PICA200 geometry shader - -; Uniforms -.fvec projection[4] - -; Constants -.constf myconst(0.0, 1.0, -1.0, 0.5) -.alias zeros myconst.xxxx ; Vector full of zeros -.alias ones myconst.yyyy ; Vector full of ones -.alias half myconst.wwww - -; Outputs - this time the type *is* used -.out outpos position -.out outclr color - -; Inputs: we will receive the following inputs: -; v0-v1: position/color of the first vertex -; v2-v3: position/color of the second vertex -; v4-v5: position/color of the third vertex - -.proc main - ; Calculate the midpoints of the vertices - mov r4, v0 - add r4, v2, r4 - mul r4, half, r4 - mov r5, v2 - add r5, v4, r5 - mul r5, half, r5 - mov r6, v4 - add r6, v0, r6 - mul r6, half, r6 - - ; Emit the first triangle - mov r0, v0 - mov r1, r4 - mov r2, r6 - call emit_triangle - - ; Emit the second triangle - mov r0, r4 - mov r1, v2 - mov r2, r5 - call emit_triangle - - ; Emit the third triangle - mov r0, r6 - mov r1, r5 - mov r2, v4 - call emit_triangle - - ; We're finished - end -.end - -.proc emit_triangle - ; Emit the first vertex - setemit 0 - mov r8, r0 - mov r9, v1 - call process_vertex - emit - - ; Emit the second vertex - setemit 1 - mov r8, r1 - mov r9, v3 - call process_vertex - emit - - ; Emit the third vertex and finish the primitive - setemit 2, prim - mov r8, r2 - mov r9, v5 - call process_vertex - emit -.end - -; Subroutine -; Inputs: -; r8: vertex position -; r9: vertex color -.proc process_vertex - ; outpos = projectionMatrix * r8 - dp4 outpos.x, projection[0], r8 - dp4 outpos.y, projection[1], r8 - dp4 outpos.z, projection[2], r8 - dp4 outpos.w, projection[3], r8 - - ; outclr = r9 - mov outclr, r9 -.end diff --git a/examples/graphics/gpu/geoshader/source/main.c b/examples/graphics/gpu/geoshader/source/main.c deleted file mode 100644 index 83501e2..0000000 --- a/examples/graphics/gpu/geoshader/source/main.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * ~~ Simple libctru GPU geometry shader example ~~ - * This example demonstrates the basics of using the PICA200 in a 3DS homebrew - * application in order to render a basic scene using a geoshader. - * The example geoshader receives the vertices of a triangle and emits three - * smaller triangles, thus forming a 'triforce' shape. - */ - -#include "gpu.h" -#include "vshader_shbin.h" -#include "gshader_shbin.h" - -#define CLEAR_COLOR 0x68B0D8FF - -typedef struct { float position[3]; float color[4]; } vertex; - -static const vertex vertex_list[] = -{ - { {200.0f, 200.0f, 0.5f}, {1.0f, 0.0f, 0.0f, 1.0f} }, - { {100.0f, 40.0f, 0.5f}, {0.0f, 1.0f, 0.0f, 1.0f} }, - { {300.0f, 40.0f, 0.5f}, {0.0f, 0.0f, 1.0f, 1.0f} }, -}; - -#define vertex_list_count (sizeof(vertex_list)/sizeof(vertex_list[0])) - -static DVLB_s *vshader_dvlb, *gshader_dvlb; -static shaderProgram_s program; -static int uLoc_projection; -static matrix_4x4 projection; - -static void* vbo_data; - -static void sceneInit(void) -{ - // Load the shaders and create a shader program - // The geoshader stride is set to 6 so that it processes a triangle at a time - vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size); - gshader_dvlb = DVLB_ParseFile((u32*)gshader_shbin, gshader_shbin_size); - shaderProgramInit(&program); - shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]); - shaderProgramSetGsh(&program, &gshader_dvlb->DVLE[0], 6); - - // Get the location of the projection matrix uniform - uLoc_projection = shaderInstanceGetUniformLocation(program.geometryShader, "projection"); - - // Compute the projection matrix - m4x4_ortho_tilt(&projection, 0.0, 400.0, 0.0, 240.0, 0.0, 1.0); - - // Create the VBO (vertex buffer object) - vbo_data = linearAlloc(sizeof(vertex_list)); - memcpy(vbo_data, vertex_list, sizeof(vertex_list)); -} - -static void sceneRender(void) -{ - // Bind the shader program - shaderProgramUse(&program); - - // Configure the first fragment shading substage to just pass through the vertex color - // See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight - GPU_SetTexEnv(0, - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), // RGB channels - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), // Alpha - GPU_TEVOPERANDS(0, 0, 0), // RGB - GPU_TEVOPERANDS(0, 0, 0), // Alpha - GPU_REPLACE, GPU_REPLACE, // RGB, Alpha - 0xFFFFFFFF); - - // Configure the "attribute buffers" (that is, the vertex input buffers) - GPU_SetAttributeBuffers( - 2, // Number of inputs per vertex - (u32*)osConvertVirtToPhys(vbo_data), // Location of the VBO - GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | - GPU_ATTRIBFMT(1, 4, GPU_FLOAT), // Format of the inputs (in this case the only input is a 3-element float vector) - 0xFFC, // Unused attribute mask, in our case bit 0 is cleared since it is used - 0x10, // Attribute permutations (here it is the identity) - 1, // Number of buffers - (u32[]) { 0x0 }, // Buffer offsets (placeholders) - (u64[]) { 0x10 }, // Attribute permutations for each buffer (identity again) - (u8[]) { 2 }); // Number of attributes for each buffer - - // Upload the projection matrix - GPU_SetFloatUniformMatrix(GPU_GEOMETRY_SHADER, uLoc_projection, &projection); - - // Draw the VBO - GPU_GEOMETRY_PRIM allows the geoshader to control primitive emission - GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, vertex_list_count); -} - -static void sceneExit(void) -{ - // Free the VBO - linearFree(vbo_data); - - // Free the shader program - shaderProgramFree(&program); - DVLB_Free(vshader_dvlb); - DVLB_Free(gshader_dvlb); -} - -int main() -{ - // Initialize graphics - gfxInitDefault(); - gpuInit(); - - // Initialize the scene - sceneInit(); - gpuClearBuffers(CLEAR_COLOR); - - // Main loop - while (aptMainLoop()) - { - gspWaitForVBlank(); // Synchronize with the start of VBlank - gfxSwapBuffersGpu(); // Swap the framebuffers so that the frame that we rendered last frame is now visible - hidScanInput(); // Read the user input - - // Respond to user input - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - // Render the scene - gpuFrameBegin(); - sceneRender(); - gpuFrameEnd(); - gpuClearBuffers(CLEAR_COLOR); - - // Flush the framebuffers out of the data cache (not necessary with pure GPU rendering) - //gfxFlushBuffers(); - } - - // Deinitialize the scene - sceneExit(); - - // Deinitialize graphics - gpuExit(); - gfxExit(); - return 0; -} diff --git a/examples/graphics/gpu/geoshader/source/vshader.pica b/examples/graphics/gpu/geoshader/source/vshader.pica deleted file mode 100644 index 8bcbc22..0000000 --- a/examples/graphics/gpu/geoshader/source/vshader.pica +++ /dev/null @@ -1,24 +0,0 @@ -; Example PICA200 vertex shader - -; Constants -.constf myconst(0.0, 1.0, -1.0, -0.5) -.alias zeros myconst.xxxx ; Vector full of zeros -.alias ones myconst.yyyy ; Vector full of ones - -; Outputs - since we are also using a geoshader the output type isn't really used -.out outpos position -.out outclr color - -; Inputs (defined as aliases for convenience) -.alias inpos v0 -.alias inclr v1 - -.proc main - ; Pass through both inputs to the geoshader - mov outpos.xyz, inpos - mov outpos.w, ones - mov outclr, inclr - - ; We're finished - end -.end diff --git a/examples/graphics/gpu/simple_tri/Makefile b/examples/graphics/gpu/simple_tri/Makefile deleted file mode 100644 index 3b72824..0000000 --- a/examples/graphics/gpu/simple_tri/Makefile +++ /dev/null @@ -1,177 +0,0 @@ -#--------------------------------------------------------------------------------- -.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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pica))) -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)) $(PICAFILES:.pica=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rule for assembling GPU shaders -#--------------------------------------------------------------------------------- -%.shbin.o: %.pica - @echo $(notdir $<) - $(eval CURBIN := $(patsubst %.pica,%.shbin,$(notdir $<))) - $(eval CURH := $(patsubst %.pica,%.psh.h,$(notdir $<))) - @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 - @echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/graphics/gpu/simple_tri/README.md b/examples/graphics/gpu/simple_tri/README.md deleted file mode 100644 index 5e3b6dd..0000000 --- a/examples/graphics/gpu/simple_tri/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# GPU example - -This is a simple GPU example using the `picasso` shader assembler which comes with devkitARM r45 and up. -Users of earlier versions of devkitARM need to install the tool, which can be found in the address below: - -https://github.com/fincs/picasso/releases diff --git a/examples/graphics/gpu/simple_tri/source/3dmath.c b/examples/graphics/gpu/simple_tri/source/3dmath.c deleted file mode 100644 index eb8d03f..0000000 --- a/examples/graphics/gpu/simple_tri/source/3dmath.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "3dmath.h" - -void m4x4_identity(matrix_4x4* out) -{ - m4x4_zeros(out); - out->r[0].x = out->r[1].y = out->r[2].z = out->r[3].w = 1.0f; -} - -void m4x4_multiply(matrix_4x4* out, const matrix_4x4* a, const matrix_4x4* b) -{ - int i, j; - for (i = 0; i < 4; i ++) - for (j = 0; j < 4; j ++) - out->r[j].c[i] = a->r[j].x*b->r[0].c[i] + a->r[j].y*b->r[1].c[i] + a->r[j].z*b->r[2].c[i] + a->r[j].w*b->r[3].c[i]; -} - -void m4x4_translate(matrix_4x4* mtx, float x, float y, float z) -{ - matrix_4x4 tm, om; - - m4x4_identity(&tm); - tm.r[0].w = x; - tm.r[1].w = y; - tm.r[2].w = z; - - m4x4_multiply(&om, mtx, &tm); - m4x4_copy(mtx, &om); -} - -void m4x4_scale(matrix_4x4* mtx, float x, float y, float z) -{ - int i; - for (i = 0; i < 4; i ++) - { - mtx->r[i].x *= x; - mtx->r[i].y *= y; - mtx->r[i].z *= z; - } -} - -void m4x4_rotate_x(matrix_4x4* mtx, float angle, bool bRightSide) -{ - matrix_4x4 rm, om; - - float cosAngle = cosf(angle); - float sinAngle = sinf(angle); - - m4x4_zeros(&rm); - rm.r[0].x = 1.0f; - rm.r[1].y = cosAngle; - rm.r[1].z = sinAngle; - rm.r[2].y = -sinAngle; - rm.r[2].z = cosAngle; - rm.r[3].w = 1.0f; - - if (bRightSide) m4x4_multiply(&om, mtx, &rm); - else m4x4_multiply(&om, &rm, mtx); - m4x4_copy(mtx, &om); -} - -void m4x4_rotate_y(matrix_4x4* mtx, float angle, bool bRightSide) -{ - matrix_4x4 rm, om; - - float cosAngle = cosf(angle); - float sinAngle = sinf(angle); - - m4x4_zeros(&rm); - rm.r[0].x = cosAngle; - rm.r[0].z = sinAngle; - rm.r[1].y = 1.0f; - rm.r[2].x = -sinAngle; - rm.r[2].z = cosAngle; - rm.r[3].w = 1.0f; - - if (bRightSide) m4x4_multiply(&om, mtx, &rm); - else m4x4_multiply(&om, &rm, mtx); - m4x4_copy(mtx, &om); -} - -void m4x4_rotate_z(matrix_4x4* mtx, float angle, bool bRightSide) -{ - matrix_4x4 rm, om; - - float cosAngle = cosf(angle); - float sinAngle = sinf(angle); - - m4x4_zeros(&rm); - rm.r[0].x = cosAngle; - rm.r[0].y = sinAngle; - rm.r[1].x = -sinAngle; - rm.r[1].y = cosAngle; - rm.r[2].z = 1.0f; - rm.r[3].w = 1.0f; - - if (bRightSide) m4x4_multiply(&om, mtx, &rm); - else m4x4_multiply(&om, &rm, mtx); - m4x4_copy(mtx, &om); -} - -void m4x4_ortho_tilt(matrix_4x4* mtx, float left, float right, float bottom, float top, float near, float far) -{ - matrix_4x4 mp; - m4x4_zeros(&mp); - - // Build standard orthogonal projection matrix - mp.r[0].x = 2.0f / (right - left); - mp.r[0].w = (left + right) / (left - right); - mp.r[1].y = 2.0f / (top - bottom); - mp.r[1].w = (bottom + top) / (bottom - top); - mp.r[2].z = 2.0f / (near - far); - mp.r[2].w = (far + near) / (far - near); - mp.r[3].w = 1.0f; - - // Fix depth range to [-1, 0] - matrix_4x4 mp2, mp3; - m4x4_identity(&mp2); - mp2.r[2].z = 0.5; - mp2.r[2].w = -0.5; - m4x4_multiply(&mp3, &mp2, &mp); - - // Fix the 3DS screens' orientation by swapping the X and Y axis - m4x4_identity(&mp2); - mp2.r[0].x = 0.0; - mp2.r[0].y = 1.0; - mp2.r[1].x = -1.0; // flipped - mp2.r[1].y = 0.0; - m4x4_multiply(mtx, &mp2, &mp3); -} - -void m4x4_persp_tilt(matrix_4x4* mtx, float fovx, float invaspect, float near, float far) -{ - // Notes: - // We are passed "fovy" and the "aspect ratio". However, the 3DS screens are sideways, - // and so are these parameters -- in fact, they are actually the fovx and the inverse - // of the aspect ratio. Therefore the formula for the perspective projection matrix - // had to be modified to be expressed in these terms instead. - - // Notes: - // fovx = 2 atan(tan(fovy/2)*w/h) - // fovy = 2 atan(tan(fovx/2)*h/w) - // invaspect = h/w - - // a0,0 = h / (w*tan(fovy/2)) = - // = h / (w*tan(2 atan(tan(fovx/2)*h/w) / 2)) = - // = h / (w*tan( atan(tan(fovx/2)*h/w) )) = - // = h / (w * tan(fovx/2)*h/w) = - // = 1 / tan(fovx/2) - - // a1,1 = 1 / tan(fovy/2) = (...) = w / (h*tan(fovx/2)) - - float fovx_tan = tanf(fovx / 2); - matrix_4x4 mp; - m4x4_zeros(&mp); - - // Build standard perspective projection matrix - mp.r[0].x = 1.0f / fovx_tan; - mp.r[1].y = 1.0f / (fovx_tan*invaspect); - mp.r[2].z = (near + far) / (near - far); - mp.r[2].w = (2 * near * far) / (near - far); - mp.r[3].z = -1.0f; - - // Fix depth range to [-1, 0] - matrix_4x4 mp2; - m4x4_identity(&mp2); - mp2.r[2].z = 0.5; - mp2.r[2].w = -0.5; - m4x4_multiply(mtx, &mp2, &mp); - - // Rotate the matrix one quarter of a turn CCW in order to fix the 3DS screens' orientation - m4x4_rotate_z(mtx, M_PI / 2, true); -} diff --git a/examples/graphics/gpu/simple_tri/source/3dmath.h b/examples/graphics/gpu/simple_tri/source/3dmath.h deleted file mode 100644 index a9a8596..0000000 --- a/examples/graphics/gpu/simple_tri/source/3dmath.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Bare-bones simplistic 3D math library - * This library is common to all libctru GPU examples - */ - -#pragma once -#include -#include -#include - -typedef union { struct { float w, z, y, x; }; float c[4]; } vector_4f; -typedef struct { vector_4f r[4]; } matrix_4x4; - -static inline float v4f_dp4(const vector_4f* a, const vector_4f* b) -{ - return a->x*b->x + a->y*b->y + a->z*b->z + a->w*b->w; -} - -static inline float v4f_mod4(const vector_4f* a) -{ - return sqrtf(v4f_dp4(a,a)); -} - -static inline void v4f_norm4(vector_4f* vec) -{ - float m = v4f_mod4(vec); - if (m == 0.0) return; - vec->x /= m; - vec->y /= m; - vec->z /= m; - vec->w /= m; -} - -static inline void m4x4_zeros(matrix_4x4* out) -{ - memset(out, 0, sizeof(*out)); -} - -static inline void m4x4_copy(matrix_4x4* out, const matrix_4x4* in) -{ - memcpy(out, in, sizeof(*out)); -} - -void m4x4_identity(matrix_4x4* out); -void m4x4_multiply(matrix_4x4* out, const matrix_4x4* a, const matrix_4x4* b); - -void m4x4_translate(matrix_4x4* mtx, float x, float y, float z); -void m4x4_scale(matrix_4x4* mtx, float x, float y, float z); - -void m4x4_rotate_x(matrix_4x4* mtx, float angle, bool bRightSide); -void m4x4_rotate_y(matrix_4x4* mtx, float angle, bool bRightSide); -void m4x4_rotate_z(matrix_4x4* mtx, float angle, bool bRightSide); - -// Special versions of the projection matrices that take the 3DS' screen orientation into account -void m4x4_ortho_tilt(matrix_4x4* mtx, float left, float right, float bottom, float top, float near, float far); -void m4x4_persp_tilt(matrix_4x4* mtx, float fovy, float aspect, float near, float far); diff --git a/examples/graphics/gpu/simple_tri/source/gpu.c b/examples/graphics/gpu/simple_tri/source/gpu.c deleted file mode 100644 index d16f1ff..0000000 --- a/examples/graphics/gpu/simple_tri/source/gpu.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "gpu.h" - -#define DISPLAY_TRANSFER_FLAGS \ - (GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | \ - GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \ - GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)) - -static u32 *colorBuf, *depthBuf; -static u32 *cmdBuf; - -void gpuInit(void) -{ - colorBuf = vramAlloc(400*240*4); - depthBuf = vramAlloc(400*240*4); - cmdBuf = linearAlloc(0x40000*4); - - GPU_Init(NULL); - GPU_Reset(NULL, cmdBuf, 0x40000); -} - -void gpuExit(void) -{ - linearFree(cmdBuf); - vramFree(depthBuf); - vramFree(colorBuf); -} - -void gpuClearBuffers(u32 clearColor) -{ - GX_MemoryFill( - colorBuf, clearColor, &colorBuf[240*400], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH, - depthBuf, 0, &depthBuf[240*400], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH); - gspWaitForPSC0(); // Wait for the fill to complete -} - -void gpuFrameBegin(void) -{ - // Configure the viewport and the depth linear conversion function - GPU_SetViewport( - (u32*)osConvertVirtToPhys(depthBuf), - (u32*)osConvertVirtToPhys(colorBuf), - 0, 0, 240, 400); // The top screen is physically 240x400 pixels - GPU_DepthMap(-1.0f, 0.0f); // calculate the depth value from the Z coordinate in the following way: -1.0*z + 0.0 - - // Configure some boilerplate - GPU_SetFaceCulling(GPU_CULL_BACK_CCW); - GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); - 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); - - // This is unknown - GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); - GPUCMD_AddWrite(GPUREG_0118, 0); - - // Configure alpha blending and test - GPU_SetAlphaBlending(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); - GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00); - - int i; - for (i = 0; i < 6; i ++) - GPU_SetDummyTexEnv(i); -} - -void gpuFrameEnd(void) -{ - // Finish rendering - GPU_FinishDrawing(); - GPUCMD_Finalize(); - GPUCMD_FlushAndRun(); - gspWaitForP3D(); // Wait for the rendering to complete - - // Transfer the GPU output to the framebuffer - GX_DisplayTransfer( - colorBuf, GX_BUFFER_DIM(240, 400), - (u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), GX_BUFFER_DIM(240, 400), - DISPLAY_TRANSFER_FLAGS); - gspWaitForPPF(); // Wait for the transfer to complete - - // Reset the command buffer - GPUCMD_SetBufferOffset(0); -}; - -void GPU_SetDummyTexEnv(int id) -{ - GPU_SetTexEnv(id, - GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), - GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_REPLACE, - GPU_REPLACE, - 0xFFFFFFFF); -} diff --git a/examples/graphics/gpu/simple_tri/source/gpu.h b/examples/graphics/gpu/simple_tri/source/gpu.h deleted file mode 100644 index 845d139..0000000 --- a/examples/graphics/gpu/simple_tri/source/gpu.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Bare-bones simplistic GPU wrapper - * This library is common to all libctru GPU examples - */ - -#pragma once -#include -#include <3ds.h> -#include "3dmath.h" - -void gpuInit(void); -void gpuExit(void); - -void gpuClearBuffers(u32 clearColor); - -void gpuFrameBegin(void); -void gpuFrameEnd(void); - -// Configures the specified fixed-function fragment shading substage to be a no-operation -void GPU_SetDummyTexEnv(int id); - -// Uploads an uniform matrix -static inline void GPU_SetFloatUniformMatrix(GPU_SHADER_TYPE type, int location, matrix_4x4* matrix) -{ - GPU_SetFloatUniform(type, location, (u32*)matrix, 4); -} diff --git a/examples/graphics/gpu/simple_tri/source/main.c b/examples/graphics/gpu/simple_tri/source/main.c deleted file mode 100644 index 656fb70..0000000 --- a/examples/graphics/gpu/simple_tri/source/main.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * ~~ Simple libctru GPU triangle example ~~ - * This example demonstrates the basics of using the PICA200 in a 3DS homebrew - * application in order to render a basic scene consisting of a white solid triangle. - */ - -#include "gpu.h" -#include "vshader_shbin.h" - -#define CLEAR_COLOR 0x68B0D8FF - -typedef struct { float x, y, z; } vertex; - -static const vertex vertex_list[] = -{ - { 200.0f, 200.0f, 0.5f }, - { 100.0f, 40.0f, 0.5f }, - { 300.0f, 40.0f, 0.5f }, -}; - -#define vertex_list_count (sizeof(vertex_list)/sizeof(vertex_list[0])) - -static DVLB_s* vshader_dvlb; -static shaderProgram_s program; -static int uLoc_projection; -static matrix_4x4 projection; - -static void* vbo_data; - -static void sceneInit(void) -{ - // Load the vertex shader and create a shader program - vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size); - shaderProgramInit(&program); - shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]); - - // Get the location of the projection matrix uniform - uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection"); - - // Compute the projection matrix - m4x4_ortho_tilt(&projection, 0.0, 400.0, 0.0, 240.0, 0.0, 1.0); - - // Create the VBO (vertex buffer object) - vbo_data = linearAlloc(sizeof(vertex_list)); - memcpy(vbo_data, vertex_list, sizeof(vertex_list)); -} - -static void sceneRender(void) -{ - // Bind the shader program - shaderProgramUse(&program); - - // Configure the first fragment shading substage to just pass through the vertex color - // See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight - GPU_SetTexEnv(0, - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), // RGB channels - GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), // Alpha - GPU_TEVOPERANDS(0, 0, 0), // RGB - GPU_TEVOPERANDS(0, 0, 0), // Alpha - GPU_REPLACE, GPU_REPLACE, // RGB, Alpha - 0xFFFFFFFF); - - // Configure the "attribute buffers" (that is, the vertex input buffers) - GPU_SetAttributeBuffers( - 1, // Number of inputs per vertex - (u32*)osConvertVirtToPhys((u32)vbo_data), // Location of the VBO - GPU_ATTRIBFMT(0, 3, GPU_FLOAT), // Format of the inputs (in this case the only input is a 3-element float vector) - 0xFFE, // Unused attribute mask, in our case bit 0 is cleared since it is used - 0x0, // Attribute permutations (here it is the identity) - 1, // Number of buffers - (u32[]) { 0x0 }, // Buffer offsets (placeholders) - (u64[]) { 0x0 }, // Attribute permutations for each buffer (identity again) - (u8[]) { 1 }); // Number of attributes for each buffer - - // Upload the projection matrix - GPU_SetFloatUniformMatrix(GPU_VERTEX_SHADER, uLoc_projection, &projection); - - // Draw the VBO - GPU_DrawArray(GPU_TRIANGLES, 0, vertex_list_count); -} - -static void sceneExit(void) -{ - // Free the VBO - linearFree(vbo_data); - - // Free the shader program - shaderProgramFree(&program); - DVLB_Free(vshader_dvlb); -} - -int main() -{ - // Initialize graphics - gfxInitDefault(); - gpuInit(); - - // Initialize the scene - sceneInit(); - gpuClearBuffers(CLEAR_COLOR); - - // Main loop - while (aptMainLoop()) - { - gspWaitForVBlank(); // Synchronize with the start of VBlank - gfxSwapBuffersGpu(); // Swap the framebuffers so that the frame that we rendered last frame is now visible - hidScanInput(); // Read the user input - - // Respond to user input - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - // Render the scene - gpuFrameBegin(); - sceneRender(); - gpuFrameEnd(); - gpuClearBuffers(CLEAR_COLOR); - - // Flush the framebuffers out of the data cache (not necessary with pure GPU rendering) - //gfxFlushBuffers(); - } - - // Deinitialize the scene - sceneExit(); - - // Deinitialize graphics - gpuExit(); - gfxExit(); - return 0; -} diff --git a/examples/graphics/gpu/simple_tri/source/vshader.pica b/examples/graphics/gpu/simple_tri/source/vshader.pica deleted file mode 100644 index cdd9759..0000000 --- a/examples/graphics/gpu/simple_tri/source/vshader.pica +++ /dev/null @@ -1,34 +0,0 @@ -; Example PICA200 vertex shader - -; Uniforms -.fvec projection[4] - -; Constants -.constf myconst(0.0, 1.0, -1.0, -0.5) -.alias zeros myconst.xxxx ; Vector full of zeros -.alias ones myconst.yyyy ; Vector full of ones - -; Outputs -.out outpos position -.out outclr color - -; Inputs (defined as aliases for convenience) -.alias inpos v0 - -.proc main - ; Force the w component of inpos to be 1.0 - mov r0.xyz, inpos - mov r0.w, ones - - ; outpos = projectionMatrix * inpos - dp4 outpos.x, projection[0], r0 - dp4 outpos.y, projection[1], r0 - dp4 outpos.z, projection[2], r0 - dp4 outpos.w, projection[3], r0 - - ; outclr = solid white color - mov outclr, ones - - ; We're finished - end -.end diff --git a/examples/graphics/gpu/textured_cube/Makefile b/examples/graphics/gpu/textured_cube/Makefile deleted file mode 100644 index 3b72824..0000000 --- a/examples/graphics/gpu/textured_cube/Makefile +++ /dev/null @@ -1,177 +0,0 @@ -#--------------------------------------------------------------------------------- -.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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pica))) -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)) $(PICAFILES:.pica=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rule for assembling GPU shaders -#--------------------------------------------------------------------------------- -%.shbin.o: %.pica - @echo $(notdir $<) - $(eval CURBIN := $(patsubst %.pica,%.shbin,$(notdir $<))) - $(eval CURH := $(patsubst %.pica,%.psh.h,$(notdir $<))) - @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 - @echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/graphics/gpu/textured_cube/README.md b/examples/graphics/gpu/textured_cube/README.md deleted file mode 100644 index 5e3b6dd..0000000 --- a/examples/graphics/gpu/textured_cube/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# GPU example - -This is a simple GPU example using the `picasso` shader assembler which comes with devkitARM r45 and up. -Users of earlier versions of devkitARM need to install the tool, which can be found in the address below: - -https://github.com/fincs/picasso/releases diff --git a/examples/graphics/gpu/textured_cube/data/kitten.bin b/examples/graphics/gpu/textured_cube/data/kitten.bin deleted file mode 100644 index a87ac4a8f17788e646796732120bda82629e0c97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 CZh=bx diff --git a/examples/graphics/gpu/textured_cube/source/3dmath.c b/examples/graphics/gpu/textured_cube/source/3dmath.c deleted file mode 100644 index eb8d03f..0000000 --- a/examples/graphics/gpu/textured_cube/source/3dmath.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "3dmath.h" - -void m4x4_identity(matrix_4x4* out) -{ - m4x4_zeros(out); - out->r[0].x = out->r[1].y = out->r[2].z = out->r[3].w = 1.0f; -} - -void m4x4_multiply(matrix_4x4* out, const matrix_4x4* a, const matrix_4x4* b) -{ - int i, j; - for (i = 0; i < 4; i ++) - for (j = 0; j < 4; j ++) - out->r[j].c[i] = a->r[j].x*b->r[0].c[i] + a->r[j].y*b->r[1].c[i] + a->r[j].z*b->r[2].c[i] + a->r[j].w*b->r[3].c[i]; -} - -void m4x4_translate(matrix_4x4* mtx, float x, float y, float z) -{ - matrix_4x4 tm, om; - - m4x4_identity(&tm); - tm.r[0].w = x; - tm.r[1].w = y; - tm.r[2].w = z; - - m4x4_multiply(&om, mtx, &tm); - m4x4_copy(mtx, &om); -} - -void m4x4_scale(matrix_4x4* mtx, float x, float y, float z) -{ - int i; - for (i = 0; i < 4; i ++) - { - mtx->r[i].x *= x; - mtx->r[i].y *= y; - mtx->r[i].z *= z; - } -} - -void m4x4_rotate_x(matrix_4x4* mtx, float angle, bool bRightSide) -{ - matrix_4x4 rm, om; - - float cosAngle = cosf(angle); - float sinAngle = sinf(angle); - - m4x4_zeros(&rm); - rm.r[0].x = 1.0f; - rm.r[1].y = cosAngle; - rm.r[1].z = sinAngle; - rm.r[2].y = -sinAngle; - rm.r[2].z = cosAngle; - rm.r[3].w = 1.0f; - - if (bRightSide) m4x4_multiply(&om, mtx, &rm); - else m4x4_multiply(&om, &rm, mtx); - m4x4_copy(mtx, &om); -} - -void m4x4_rotate_y(matrix_4x4* mtx, float angle, bool bRightSide) -{ - matrix_4x4 rm, om; - - float cosAngle = cosf(angle); - float sinAngle = sinf(angle); - - m4x4_zeros(&rm); - rm.r[0].x = cosAngle; - rm.r[0].z = sinAngle; - rm.r[1].y = 1.0f; - rm.r[2].x = -sinAngle; - rm.r[2].z = cosAngle; - rm.r[3].w = 1.0f; - - if (bRightSide) m4x4_multiply(&om, mtx, &rm); - else m4x4_multiply(&om, &rm, mtx); - m4x4_copy(mtx, &om); -} - -void m4x4_rotate_z(matrix_4x4* mtx, float angle, bool bRightSide) -{ - matrix_4x4 rm, om; - - float cosAngle = cosf(angle); - float sinAngle = sinf(angle); - - m4x4_zeros(&rm); - rm.r[0].x = cosAngle; - rm.r[0].y = sinAngle; - rm.r[1].x = -sinAngle; - rm.r[1].y = cosAngle; - rm.r[2].z = 1.0f; - rm.r[3].w = 1.0f; - - if (bRightSide) m4x4_multiply(&om, mtx, &rm); - else m4x4_multiply(&om, &rm, mtx); - m4x4_copy(mtx, &om); -} - -void m4x4_ortho_tilt(matrix_4x4* mtx, float left, float right, float bottom, float top, float near, float far) -{ - matrix_4x4 mp; - m4x4_zeros(&mp); - - // Build standard orthogonal projection matrix - mp.r[0].x = 2.0f / (right - left); - mp.r[0].w = (left + right) / (left - right); - mp.r[1].y = 2.0f / (top - bottom); - mp.r[1].w = (bottom + top) / (bottom - top); - mp.r[2].z = 2.0f / (near - far); - mp.r[2].w = (far + near) / (far - near); - mp.r[3].w = 1.0f; - - // Fix depth range to [-1, 0] - matrix_4x4 mp2, mp3; - m4x4_identity(&mp2); - mp2.r[2].z = 0.5; - mp2.r[2].w = -0.5; - m4x4_multiply(&mp3, &mp2, &mp); - - // Fix the 3DS screens' orientation by swapping the X and Y axis - m4x4_identity(&mp2); - mp2.r[0].x = 0.0; - mp2.r[0].y = 1.0; - mp2.r[1].x = -1.0; // flipped - mp2.r[1].y = 0.0; - m4x4_multiply(mtx, &mp2, &mp3); -} - -void m4x4_persp_tilt(matrix_4x4* mtx, float fovx, float invaspect, float near, float far) -{ - // Notes: - // We are passed "fovy" and the "aspect ratio". However, the 3DS screens are sideways, - // and so are these parameters -- in fact, they are actually the fovx and the inverse - // of the aspect ratio. Therefore the formula for the perspective projection matrix - // had to be modified to be expressed in these terms instead. - - // Notes: - // fovx = 2 atan(tan(fovy/2)*w/h) - // fovy = 2 atan(tan(fovx/2)*h/w) - // invaspect = h/w - - // a0,0 = h / (w*tan(fovy/2)) = - // = h / (w*tan(2 atan(tan(fovx/2)*h/w) / 2)) = - // = h / (w*tan( atan(tan(fovx/2)*h/w) )) = - // = h / (w * tan(fovx/2)*h/w) = - // = 1 / tan(fovx/2) - - // a1,1 = 1 / tan(fovy/2) = (...) = w / (h*tan(fovx/2)) - - float fovx_tan = tanf(fovx / 2); - matrix_4x4 mp; - m4x4_zeros(&mp); - - // Build standard perspective projection matrix - mp.r[0].x = 1.0f / fovx_tan; - mp.r[1].y = 1.0f / (fovx_tan*invaspect); - mp.r[2].z = (near + far) / (near - far); - mp.r[2].w = (2 * near * far) / (near - far); - mp.r[3].z = -1.0f; - - // Fix depth range to [-1, 0] - matrix_4x4 mp2; - m4x4_identity(&mp2); - mp2.r[2].z = 0.5; - mp2.r[2].w = -0.5; - m4x4_multiply(mtx, &mp2, &mp); - - // Rotate the matrix one quarter of a turn CCW in order to fix the 3DS screens' orientation - m4x4_rotate_z(mtx, M_PI / 2, true); -} diff --git a/examples/graphics/gpu/textured_cube/source/3dmath.h b/examples/graphics/gpu/textured_cube/source/3dmath.h deleted file mode 100644 index a9a8596..0000000 --- a/examples/graphics/gpu/textured_cube/source/3dmath.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Bare-bones simplistic 3D math library - * This library is common to all libctru GPU examples - */ - -#pragma once -#include -#include -#include - -typedef union { struct { float w, z, y, x; }; float c[4]; } vector_4f; -typedef struct { vector_4f r[4]; } matrix_4x4; - -static inline float v4f_dp4(const vector_4f* a, const vector_4f* b) -{ - return a->x*b->x + a->y*b->y + a->z*b->z + a->w*b->w; -} - -static inline float v4f_mod4(const vector_4f* a) -{ - return sqrtf(v4f_dp4(a,a)); -} - -static inline void v4f_norm4(vector_4f* vec) -{ - float m = v4f_mod4(vec); - if (m == 0.0) return; - vec->x /= m; - vec->y /= m; - vec->z /= m; - vec->w /= m; -} - -static inline void m4x4_zeros(matrix_4x4* out) -{ - memset(out, 0, sizeof(*out)); -} - -static inline void m4x4_copy(matrix_4x4* out, const matrix_4x4* in) -{ - memcpy(out, in, sizeof(*out)); -} - -void m4x4_identity(matrix_4x4* out); -void m4x4_multiply(matrix_4x4* out, const matrix_4x4* a, const matrix_4x4* b); - -void m4x4_translate(matrix_4x4* mtx, float x, float y, float z); -void m4x4_scale(matrix_4x4* mtx, float x, float y, float z); - -void m4x4_rotate_x(matrix_4x4* mtx, float angle, bool bRightSide); -void m4x4_rotate_y(matrix_4x4* mtx, float angle, bool bRightSide); -void m4x4_rotate_z(matrix_4x4* mtx, float angle, bool bRightSide); - -// Special versions of the projection matrices that take the 3DS' screen orientation into account -void m4x4_ortho_tilt(matrix_4x4* mtx, float left, float right, float bottom, float top, float near, float far); -void m4x4_persp_tilt(matrix_4x4* mtx, float fovy, float aspect, float near, float far); diff --git a/examples/graphics/gpu/textured_cube/source/gpu.c b/examples/graphics/gpu/textured_cube/source/gpu.c deleted file mode 100644 index d16f1ff..0000000 --- a/examples/graphics/gpu/textured_cube/source/gpu.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "gpu.h" - -#define DISPLAY_TRANSFER_FLAGS \ - (GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | \ - GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \ - GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)) - -static u32 *colorBuf, *depthBuf; -static u32 *cmdBuf; - -void gpuInit(void) -{ - colorBuf = vramAlloc(400*240*4); - depthBuf = vramAlloc(400*240*4); - cmdBuf = linearAlloc(0x40000*4); - - GPU_Init(NULL); - GPU_Reset(NULL, cmdBuf, 0x40000); -} - -void gpuExit(void) -{ - linearFree(cmdBuf); - vramFree(depthBuf); - vramFree(colorBuf); -} - -void gpuClearBuffers(u32 clearColor) -{ - GX_MemoryFill( - colorBuf, clearColor, &colorBuf[240*400], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH, - depthBuf, 0, &depthBuf[240*400], GX_FILL_TRIGGER | GX_FILL_32BIT_DEPTH); - gspWaitForPSC0(); // Wait for the fill to complete -} - -void gpuFrameBegin(void) -{ - // Configure the viewport and the depth linear conversion function - GPU_SetViewport( - (u32*)osConvertVirtToPhys(depthBuf), - (u32*)osConvertVirtToPhys(colorBuf), - 0, 0, 240, 400); // The top screen is physically 240x400 pixels - GPU_DepthMap(-1.0f, 0.0f); // calculate the depth value from the Z coordinate in the following way: -1.0*z + 0.0 - - // Configure some boilerplate - GPU_SetFaceCulling(GPU_CULL_BACK_CCW); - GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); - 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); - - // This is unknown - GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); - GPUCMD_AddWrite(GPUREG_0118, 0); - - // Configure alpha blending and test - GPU_SetAlphaBlending(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); - GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00); - - int i; - for (i = 0; i < 6; i ++) - GPU_SetDummyTexEnv(i); -} - -void gpuFrameEnd(void) -{ - // Finish rendering - GPU_FinishDrawing(); - GPUCMD_Finalize(); - GPUCMD_FlushAndRun(); - gspWaitForP3D(); // Wait for the rendering to complete - - // Transfer the GPU output to the framebuffer - GX_DisplayTransfer( - colorBuf, GX_BUFFER_DIM(240, 400), - (u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), GX_BUFFER_DIM(240, 400), - DISPLAY_TRANSFER_FLAGS); - gspWaitForPPF(); // Wait for the transfer to complete - - // Reset the command buffer - GPUCMD_SetBufferOffset(0); -}; - -void GPU_SetDummyTexEnv(int id) -{ - GPU_SetTexEnv(id, - GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), - GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_TEVOPERANDS(0, 0, 0), - GPU_REPLACE, - GPU_REPLACE, - 0xFFFFFFFF); -} diff --git a/examples/graphics/gpu/textured_cube/source/gpu.h b/examples/graphics/gpu/textured_cube/source/gpu.h deleted file mode 100644 index 845d139..0000000 --- a/examples/graphics/gpu/textured_cube/source/gpu.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Bare-bones simplistic GPU wrapper - * This library is common to all libctru GPU examples - */ - -#pragma once -#include -#include <3ds.h> -#include "3dmath.h" - -void gpuInit(void); -void gpuExit(void); - -void gpuClearBuffers(u32 clearColor); - -void gpuFrameBegin(void); -void gpuFrameEnd(void); - -// Configures the specified fixed-function fragment shading substage to be a no-operation -void GPU_SetDummyTexEnv(int id); - -// Uploads an uniform matrix -static inline void GPU_SetFloatUniformMatrix(GPU_SHADER_TYPE type, int location, matrix_4x4* matrix) -{ - GPU_SetFloatUniform(type, location, (u32*)matrix, 4); -} diff --git a/examples/graphics/gpu/textured_cube/source/main.c b/examples/graphics/gpu/textured_cube/source/main.c deleted file mode 100644 index 1e9687c..0000000 --- a/examples/graphics/gpu/textured_cube/source/main.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * ~~ Simple libctru GPU textured cube example ~~ - * This example demonstrates the basics of using the PICA200 in a 3DS homebrew - * application in order to render a basic scene consisting of a rotating - * textured cube which is also shaded using a simple shading algorithm. - * The shading algorithm is explained in the vertex shader source code. - */ - -#include "gpu.h" -#include "vshader_shbin.h" -#include "kitten_bin.h" - -#define CLEAR_COLOR 0x68B0D8FF - -typedef struct { float position[3]; float texcoord[2]; float normal[3]; } vertex; - -static const vertex vertex_list[] = -{ - // First face (PZ) - // First triangle - { {-0.5f, -0.5f, +0.5f}, {0.0f, 0.0f}, {0.0f, 0.0f, +1.0f} }, - { {+0.5f, -0.5f, +0.5f}, {1.0f, 0.0f}, {0.0f, 0.0f, +1.0f} }, - { {+0.5f, +0.5f, +0.5f}, {1.0f, 1.0f}, {0.0f, 0.0f, +1.0f} }, - // Second triangle - { {+0.5f, +0.5f, +0.5f}, {1.0f, 1.0f}, {0.0f, 0.0f, +1.0f} }, - { {-0.5f, +0.5f, +0.5f}, {0.0f, 1.0f}, {0.0f, 0.0f, +1.0f} }, - { {-0.5f, -0.5f, +0.5f}, {0.0f, 0.0f}, {0.0f, 0.0f, +1.0f} }, - - // Second face (MZ) - // First triangle - { {-0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, {0.0f, 0.0f, -1.0f} }, - { {-0.5f, +0.5f, -0.5f}, {1.0f, 0.0f}, {0.0f, 0.0f, -1.0f} }, - { {+0.5f, +0.5f, -0.5f}, {1.0f, 1.0f}, {0.0f, 0.0f, -1.0f} }, - // Second triangle - { {+0.5f, +0.5f, -0.5f}, {1.0f, 1.0f}, {0.0f, 0.0f, -1.0f} }, - { {+0.5f, -0.5f, -0.5f}, {0.0f, 1.0f}, {0.0f, 0.0f, -1.0f} }, - { {-0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, {0.0f, 0.0f, -1.0f} }, - - // Third face (PX) - // First triangle - { {+0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, {+1.0f, 0.0f, 0.0f} }, - { {+0.5f, +0.5f, -0.5f}, {1.0f, 0.0f}, {+1.0f, 0.0f, 0.0f} }, - { {+0.5f, +0.5f, +0.5f}, {1.0f, 1.0f}, {+1.0f, 0.0f, 0.0f} }, - // Second triangle - { {+0.5f, +0.5f, +0.5f}, {1.0f, 1.0f}, {+1.0f, 0.0f, 0.0f} }, - { {+0.5f, -0.5f, +0.5f}, {0.0f, 1.0f}, {+1.0f, 0.0f, 0.0f} }, - { {+0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, {+1.0f, 0.0f, 0.0f} }, - - // Fourth face (MX) - // First triangle - { {-0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f} }, - { {-0.5f, -0.5f, +0.5f}, {1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f} }, - { {-0.5f, +0.5f, +0.5f}, {1.0f, 1.0f}, {-1.0f, 0.0f, 0.0f} }, - // Second triangle - { {-0.5f, +0.5f, +0.5f}, {1.0f, 1.0f}, {-1.0f, 0.0f, 0.0f} }, - { {-0.5f, +0.5f, -0.5f}, {0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f} }, - { {-0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f} }, - - // Fifth face (PY) - // First triangle - { {-0.5f, +0.5f, -0.5f}, {0.0f, 0.0f}, {0.0f, +1.0f, 0.0f} }, - { {-0.5f, +0.5f, +0.5f}, {1.0f, 0.0f}, {0.0f, +1.0f, 0.0f} }, - { {+0.5f, +0.5f, +0.5f}, {1.0f, 1.0f}, {0.0f, +1.0f, 0.0f} }, - // Second triangle - { {+0.5f, +0.5f, +0.5f}, {1.0f, 1.0f}, {0.0f, +1.0f, 0.0f} }, - { {+0.5f, +0.5f, -0.5f}, {0.0f, 1.0f}, {0.0f, +1.0f, 0.0f} }, - { {-0.5f, +0.5f, -0.5f}, {0.0f, 0.0f}, {0.0f, +1.0f, 0.0f} }, - - // Sixth face (MY) - // First triangle - { {-0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, {0.0f, -1.0f, 0.0f} }, - { {+0.5f, -0.5f, -0.5f}, {1.0f, 0.0f}, {0.0f, -1.0f, 0.0f} }, - { {+0.5f, -0.5f, +0.5f}, {1.0f, 1.0f}, {0.0f, -1.0f, 0.0f} }, - // Second triangle - { {+0.5f, -0.5f, +0.5f}, {1.0f, 1.0f}, {0.0f, -1.0f, 0.0f} }, - { {-0.5f, -0.5f, +0.5f}, {0.0f, 1.0f}, {0.0f, -1.0f, 0.0f} }, - { {-0.5f, -0.5f, -0.5f}, {0.0f, 0.0f}, {0.0f, -1.0f, 0.0f} }, -}; - -#define vertex_list_count (sizeof(vertex_list)/sizeof(vertex_list[0])) - -static DVLB_s* vshader_dvlb; -static shaderProgram_s program; -static int uLoc_projection, uLoc_modelView; -static int uLoc_lightVec, uLoc_lightHalfVec, uLoc_lightClr, uLoc_material; -static matrix_4x4 projection; -static matrix_4x4 material = -{ - { - { { 0.0f, 0.2f, 0.2f, 0.2f } }, // Ambient - { { 0.0f, 0.4f, 0.4f, 0.4f } }, // Diffuse - { { 0.0f, 0.8f, 0.8f, 0.8f } }, // Specular - { { 1.0f, 0.0f, 0.0f, 0.0f } }, // Emission - } -}; - -static void* vbo_data; -static void* tex_data; -static float angleX = 0.0, angleY = 0.0; - -static void sceneInit(void) -{ - // Load the vertex shader and create a shader program - vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size); - shaderProgramInit(&program); - shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]); - - // Get the location of the uniforms - uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection"); - uLoc_modelView = shaderInstanceGetUniformLocation(program.vertexShader, "modelView"); - uLoc_lightVec = shaderInstanceGetUniformLocation(program.vertexShader, "lightVec"); - uLoc_lightHalfVec = shaderInstanceGetUniformLocation(program.vertexShader, "lightHalfVec"); - uLoc_lightClr = shaderInstanceGetUniformLocation(program.vertexShader, "lightClr"); - uLoc_material = shaderInstanceGetUniformLocation(program.vertexShader, "material"); - - // Compute the projection matrix - m4x4_persp_tilt(&projection, 80.0f*M_PI/180.0f, 400.0f/240.0f, 0.01f, 1000.0f); - - // Create the VBO (vertex buffer object) - vbo_data = linearAlloc(sizeof(vertex_list)); - memcpy(vbo_data, vertex_list, sizeof(vertex_list)); - - // Load the texture - tex_data = linearAlloc(kitten_bin_size); - memcpy(tex_data, kitten_bin, kitten_bin_size); -} - -static void sceneRender(void) -{ - // Bind the shader program - shaderProgramUse(&program); - - // Configure the first fragment shading substage to blend the texture color with - // the vertex color (calculated by the vertex shader using a lighting algorithm) - // See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight - GPU_SetTexEnv(0, - GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), // RGB channels - GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), // Alpha - GPU_TEVOPERANDS(0, 0, 0), // RGB - GPU_TEVOPERANDS(0, 0, 0), // Alpha - GPU_MODULATE, GPU_MODULATE, // RGB, Alpha - 0xFFFFFFFF); - - // Configure the first texture unit - GPU_SetTextureEnable(GPU_TEXUNIT0); - GPU_SetTexture( - GPU_TEXUNIT0, - (u32*)osConvertVirtToPhys(tex_data), - 64, // Width - 64, // Height - GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_WRAP_S(GPU_REPEAT) | GPU_TEXTURE_WRAP_T(GPU_REPEAT), // Flags - GPU_RGBA8 // Pixel format - ); - - // Configure the "attribute buffers" (that is, the vertex input buffers) - GPU_SetAttributeBuffers( - 3, // Number of inputs per vertex - (u32*)osConvertVirtToPhys(vbo_data), // Location of the VBO - GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | // Format of the inputs - GPU_ATTRIBFMT(1, 2, GPU_FLOAT) | - GPU_ATTRIBFMT(2, 3, GPU_FLOAT), - 0xFFC, // Unused attribute mask, in our case bits 0~2 are cleared since they are used - 0x210, // Attribute permutations (here it is the identity, passing each attribute in order) - 1, // Number of buffers - (u32[]) { 0x0 }, // Buffer offsets (placeholders) - (u64[]) { 0x210 }, // Attribute permutations for each buffer (identity again) - (u8[]) { 3 }); // Number of attributes for each buffer - - // Calculate the modelView matrix - matrix_4x4 modelView; - m4x4_identity(&modelView); - m4x4_translate(&modelView, 0.0, 0.0, -2.0 + 0.5*sinf(angleX)); - m4x4_rotate_x(&modelView, angleX, true); - m4x4_rotate_y(&modelView, angleY, true); - - // Rotate the cube each frame - angleX += M_PI / 180; - angleY += M_PI / 360; - - // Upload the uniforms - GPU_SetFloatUniformMatrix(GPU_VERTEX_SHADER, uLoc_projection, &projection); - GPU_SetFloatUniformMatrix(GPU_VERTEX_SHADER, uLoc_modelView, &modelView); - GPU_SetFloatUniformMatrix(GPU_VERTEX_SHADER, uLoc_material, &material); - GPU_SetFloatUniform(GPU_VERTEX_SHADER, uLoc_lightVec, (u32*)(float[]){0.0f, -1.0f, 0.0f, 0.0f}, 1); - GPU_SetFloatUniform(GPU_VERTEX_SHADER, uLoc_lightHalfVec, (u32*)(float[]){0.0f, -1.0f, 0.0f, 0.0f}, 1); - 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, 0, vertex_list_count); -} - -static void sceneExit(void) -{ - // Free the texture - linearFree(tex_data); - - // Free the VBO - linearFree(vbo_data); - - // Free the shader program - shaderProgramFree(&program); - DVLB_Free(vshader_dvlb); -} - -int main() -{ - // Initialize graphics - gfxInitDefault(); - gpuInit(); - - // Initialize the scene - sceneInit(); - gpuClearBuffers(CLEAR_COLOR); - - // Main loop - while (aptMainLoop()) - { - gspWaitForVBlank(); // Synchronize with the start of VBlank - gfxSwapBuffersGpu(); // Swap the framebuffers so that the frame that we rendered last frame is now visible - hidScanInput(); // Read the user input - - // Respond to user input - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - // Render the scene - gpuFrameBegin(); - sceneRender(); - gpuFrameEnd(); - gpuClearBuffers(CLEAR_COLOR); - - // Flush the framebuffers out of the data cache (not necessary with pure GPU rendering) - //gfxFlushBuffers(); - } - - // Deinitialize the scene - sceneExit(); - - // Deinitialize graphics - gpuExit(); - gfxExit(); - return 0; -} diff --git a/examples/graphics/gpu/textured_cube/source/vshader.pica b/examples/graphics/gpu/textured_cube/source/vshader.pica deleted file mode 100644 index 0f0ac5d..0000000 --- a/examples/graphics/gpu/textured_cube/source/vshader.pica +++ /dev/null @@ -1,90 +0,0 @@ -; Example PICA200 vertex shader - -; Uniforms -.fvec projection[4], modelView[4] -.fvec lightVec, lightHalfVec, lightClr, material[4] -.alias mat_amb material[0] -.alias mat_dif material[1] -.alias mat_spe material[2] -.alias mat_emi material[3] - -; Constants -.constf myconst(0.0, 1.0, -1.0, -0.5) -.alias zeros myconst.xxxx ; Vector full of zeros -.alias ones myconst.yyyy ; Vector full of ones - -; Outputs -.out outpos position -.out outtc0 texcoord0 -.out outclr color - -; Inputs (defined as aliases for convenience) -.alias inpos v0 -.alias intex v1 -.alias innrm v2 - -.proc main - ; Force the w component of inpos to be 1.0 - mov r0.xyz, inpos - mov r0.w, ones - - ; r1 = modelView * inpos - dp4 r1.x, modelView[0], r0 - dp4 r1.y, modelView[1], r0 - dp4 r1.z, modelView[2], r0 - dp4 r1.w, modelView[3], r0 - - ; outpos = projection * r1 - dp4 outpos.x, projection[0], r1 - dp4 outpos.y, projection[1], r1 - dp4 outpos.z, projection[2], r1 - dp4 outpos.w, projection[3], r1 - - ; outtex = intex - mov outtc0, intex - - ; Transform the normal vector with the modelView matrix - ; r1 = normalize(modelView * innrm) - mov r0.xyz, innrm - mov r0.w, zeros - dp4 r1.x, modelView[0], r0 - dp4 r1.y, modelView[1], r0 - dp4 r1.z, modelView[2], r0 - mov r1.w, zeros - dp3 r2, r1, r1 ; r2 = x^2+y^2+z^2 for each component - rsq r2, r2 ; r2 = 1/sqrt(r2) '' - mul r1, r2, r1 ; r1 = r1*r2 - - ; Calculate the diffuse level (r0.x) and the shininess level (r0.y) - ; r0.x = max(0, -(lightVec * r1)) - ; r0.y = max(0, (-lightHalfVec[i]) * r1) ^ 2 - dp3 r0.x, lightVec, r1 - add r0.x, zeros, -r0 - dp3 r0.y, -lightHalfVec, r1 - max r0, zeros, r0 - mul r0.y, r0, r0 - - ; Accumulate the vertex color in r1, initializing it to the emission color - mov r1, mat_emi - - ; r1 += specularColor * lightClr * shininessLevel - mul r2, lightClr, r0.yyyy - mul r2, mat_spe, r2 - add r1, r2, r1 - - ; r1 += diffuseColor * lightClr * diffuseLevel - mul r2, lightClr, r0.xxxx - mul r2, mat_dif, r2 - add r1, r2, r1 - - ; r1 += ambientColor * lightClr - mov r2, lightClr - mul r2, mat_amb, r2 - add r1, r2, r1 - - ; outclr = clamp r1 to [0,1] - min outclr, ones, r1 - - ; We're finished - end -.end diff --git a/examples/graphics/printing/Makefile b/examples/graphics/printing/Makefile deleted file mode 100644 index bce05ec..0000000 --- a/examples/graphics/printing/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -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/graphics/printing/both-screen-text/Makefile b/examples/graphics/printing/both-screen-text/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/graphics/printing/both-screen-text/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/graphics/printing/both-screen-text/source/main.c b/examples/graphics/printing/both-screen-text/source/main.c deleted file mode 100644 index d2ddd95..0000000 --- a/examples/graphics/printing/both-screen-text/source/main.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - Both Screen Text example made by Aurelio Mannara for ctrulib - This code was modified for the last time on: 12/12/2014 23:20 UTC+1 - -*/ - -#include <3ds.h> -#include - -int main(int argc, char **argv) -{ - // Initialize services - gfxInitDefault(); - - //In this example we need one PrintConsole for each screen - PrintConsole topScreen, bottomScreen; - - //Initialize console for both screen using the two different PrintConsole we have defined - consoleInit(GFX_TOP, &topScreen); - consoleInit(GFX_BOTTOM, &bottomScreen); - - //Before doing any text printing we should select the PrintConsole in which we are willing to write, otherwise the library will print on the last selected/initialized one - //Let's start by printing something on the top screen - consoleSelect(&topScreen); - printf("This is the top screen. We have lot of space here!\n"); - - //Now write something else on the bottom screen - consoleSelect(&bottomScreen); - printf("This is the bottom screen. We don't have much space...\nStill better than DS screens :D"); - - consoleSelect(&topScreen); - printf("\x1b[29;15HPress Start to exit."); - - // 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 - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - - //Wait for VBlank - gspWaitForVBlank(); - } - - // Exit services - gfxExit(); - - return 0; -} diff --git a/examples/graphics/printing/colored-text/Makefile b/examples/graphics/printing/colored-text/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/graphics/printing/colored-text/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/graphics/printing/colored-text/source/main.c b/examples/graphics/printing/colored-text/source/main.c deleted file mode 100644 index 26afc15..0000000 --- a/examples/graphics/printing/colored-text/source/main.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - Colored Text example made by Aurelio Mannara for ctrulib - This code was modified for the last time on: 12/12/2014 23:00 UTC+1 - -*/ - -#include <3ds.h> -#include - -int main(int argc, char **argv) -{ - // Initialize services - 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); - - //Move the cursor to row 15 and column 19 and then prints "Hello World!" - //To move the cursor you have tu print "\x1b[r;cH", where r and c are respectively - //the row and column where you want your cursor to move - //The top screen has 30 rows and 50 columns - //The bottom screen has 30 rows and 40 columns - printf("\x1b[15;19HHello World!"); - - //Move the cursor to the top left corner of the screen - printf("\x1b[0;0H"); - - //Print a REALLY crappy poeam with colored text - //\x1b[cm set a SGR (Select Graphic Rendition) parameter, where c is the parameter that you want to set - //Please refer to http://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes to see all the possible SGR parameters - //As of now ctrulib support only these parameters: - //Reset (0), Half bright colors (2), Reverse (7), Text color (30-37) and Background color (40-47) - printf("Roses are \x1b[31mred\x1b[0m\n"); - printf("Violets are \x1b[34mblue\x1b[0m\n"); - printf("Piracy is bad\n"); - printf("While homebrews are good\n\n"); - - //Black text on white background - //In this example we set two parameter in a single escape sequence by separating them by a semicolon - //\x1b[47;30m means that it will set a white background (47) and it will print white characters (30) - //In this we also could have used the - printf("\x1b[47;30mBlack text on white background\x1b[0m"); - - - printf("\x1b[29;15HPress Start to exit."); - // 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 - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - - //Wait for VBlank - gspWaitForVBlank(); - } - - // Exit services - gfxExit(); - - return 0; -} diff --git a/examples/graphics/printing/hello-world/Makefile b/examples/graphics/printing/hello-world/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/graphics/printing/hello-world/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/graphics/printing/hello-world/source/main.c b/examples/graphics/printing/hello-world/source/main.c deleted file mode 100644 index 04b4c29..0000000 --- a/examples/graphics/printing/hello-world/source/main.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - Hello World example made by Aurelio Mannara for ctrulib - This code was modified for the last time on: 12/12/2014 21:00 UTC+1 -*/ - -#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); - - //Move the cursor to row 15 and column 19 and then prints "Hello World!" - //To move the cursor you have to print "\x1b[r;cH", where r and c are respectively - //the row and column where you want your cursor to move - //The top screen has 30 rows and 50 columns - //The bottom screen has 30 rows and 40 columns - printf("\x1b[15;19HHello World!"); - - printf("\x1b[29;15HPress Start to exit."); - - // 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 - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - - //Wait for VBlank - gspWaitForVBlank(); - } - - gfxExit(); - return 0; -} diff --git a/examples/graphics/printing/multiple-windows-text/Makefile b/examples/graphics/printing/multiple-windows-text/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/graphics/printing/multiple-windows-text/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/graphics/printing/multiple-windows-text/source/main.c b/examples/graphics/printing/multiple-windows-text/source/main.c deleted file mode 100644 index bf238f9..0000000 --- a/examples/graphics/printing/multiple-windows-text/source/main.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - Multiple Windows Text example made by Aurelio Mannara for ctrulib - This code was modified for the last time on: 12/12/2014 23:50 UTC+1 - -*/ - -#include <3ds.h> -#include - -int main(int argc, char **argv) -{ - // Initialize services - gfxInitDefault(); - - //In this example we need three PrintConsole, one for each window and one for the whole top screen - PrintConsole leftWindow, rightWindow, topScreen; - - //Initialize console for each window - consoleInit(GFX_TOP, &leftWindow); - consoleInit(GFX_TOP, &rightWindow); - consoleInit(GFX_TOP, &topScreen); - - //Now we specify the window position and dimension for each console window using consoleSetWindow(PrintConsole* console, int x, int y, int width, int height); - //x, y, width and height are in terms of cells, not pixel, where each cell is composed by 8x8 pixels. - consoleSetWindow(&leftWindow, 1, 1, 23, 28); - consoleSetWindow(&rightWindow, 26, 1, 23, 28); - - //Before doing any text printing we should select the PrintConsole in which we are willing to write, otherwise the library will print on the last selected/initialized one - //Let's start by printing something on the top screen - consoleSelect(&leftWindow); - printf("This text is in the left window!\n"); - printf("3DS rocks!!!\n"); - - //Now write something else on the bottom screen - consoleSelect(&rightWindow); - printf("This text is in the right window!\n"); - printf("This thing works pretty well!\n"); - - - consoleSelect(&topScreen); - printf("\x1b[29;15HPress Start to exit."); - - // 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 - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - - //Wait for VBlank - gspWaitForVBlank(); - } - - // Exit services - gfxExit(); - - return 0; -} diff --git a/examples/http/Makefile b/examples/http/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/http/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/http/README.md b/examples/http/README.md deleted file mode 100644 index 8472ee2..0000000 --- a/examples/http/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# http - -This is an example for using HTTPC. This downloads a raw image for displaying on the top-screen. The URL used here is a LAN-only one, hence this URL must be changed before building+running this example. - diff --git a/examples/http/source/main.c b/examples/http/source/main.c deleted file mode 100644 index 5c2c43e..0000000 --- a/examples/http/source/main.c +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include -#include -#include - -#include <3ds.h> - -Result http_download(httpcContext *context)//This error handling needs updated with proper text printing once ctrulib itself supports that. -{ - Result ret=0; - u8* framebuf_top; - u32 statuscode=0; - u32 size=0, contentsize=0; - u8 *buf; - - ret = httpcBeginRequest(context); - if(ret!=0)return ret; - - ret = httpcGetResponseStatusCode(context, &statuscode, 0); - if(ret!=0)return ret; - - if(statuscode!=200)return -2; - - ret=httpcGetDownloadSizeState(context, NULL, &contentsize); - if(ret!=0)return ret; - - printf("size: %"PRId32"\n",contentsize); - gfxFlushBuffers(); - - buf = (u8*)malloc(contentsize); - if(buf==NULL)return -1; - memset(buf, 0, contentsize); - - - ret = httpcDownloadData(context, buf, contentsize, NULL); - if(ret!=0) - { - free(buf); - return ret; - } - - size = contentsize; - if(size>(240*400*3*2))size = 240*400*3*2; - - framebuf_top = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); - memcpy(framebuf_top, buf, size); - - gfxFlushBuffers(); - gfxSwapBuffers(); - - framebuf_top = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); - memcpy(framebuf_top, buf, size); - - gfxFlushBuffers(); - gfxSwapBuffers(); - gspWaitForVBlank(); - - free(buf); - - return 0; -} - -int main() -{ - Result ret=0; - httpcContext context; - - gfxInitDefault(); - httpcInit(); - - consoleInit(GFX_BOTTOM,NULL); - - //Change this to your own URL. - char *url = "http://devkitpro.org/misc/httpexample_rawimg.rgb"; - - printf("Downloading %s\n",url); - gfxFlushBuffers(); - - ret = httpcOpenContext(&context, url, 1); - printf("return from httpcOpenContext: %"PRId32"\n",ret); - gfxFlushBuffers(); - - if(ret==0) - { - ret=http_download(&context); - printf("return from http_download: %"PRId32"\n",ret); - gfxFlushBuffers(); - httpcCloseContext(&context); - } - - // Main loop - while (aptMainLoop()) - { - gspWaitForVBlank(); - hidScanInput(); - - // Your code goes here - - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - } - - // Exit services - httpcExit(); - gfxExit(); - return 0; -} - diff --git a/examples/input/Makefile b/examples/input/Makefile deleted file mode 100644 index bce05ec..0000000 --- a/examples/input/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -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 deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/input/read-controls/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/input/read-controls/source/main.c b/examples/input/read-controls/source/main.c deleted file mode 100644 index bb9c2b3..0000000 --- a/examples/input/read-controls/source/main.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - Circle Pad 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:20 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) -{ - //Matrix containing the name of each key. Useful for printing when a key is pressed - char keysNames[32][32] = { - "KEY_A", "KEY_B", "KEY_SELECT", "KEY_START", - "KEY_DRIGHT", "KEY_DLEFT", "KEY_DUP", "KEY_DDOWN", - "KEY_R", "KEY_L", "KEY_X", "KEY_Y", - "", "", "KEY_ZL", "KEY_ZR", - "", "", "", "", - "KEY_TOUCH", "", "", "", - "KEY_CSTICK_RIGHT", "KEY_CSTICK_LEFT", "KEY_CSTICK_UP", "KEY_CSTICK_DOWN", - "KEY_CPAD_RIGHT", "KEY_CPAD_LEFT", "KEY_CPAD_UP", "KEY_CPAD_DOWN" - }; - - // Initialize services - 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); - - u32 kDownOld = 0, kHeldOld = 0, kUpOld = 0; //In these variables there will be information about keys detected in the previous frame - - printf("\x1b[0;0HPress Start to exit."); - printf("\x1b[1;0HCirclePad 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(); - //hidKeysHeld returns information about which buttons have are held down in this frame - u32 kHeld = hidKeysHeld(); - //hidKeysUp returns information about which buttons have been just released - u32 kUp = hidKeysUp(); - - if (kDown & KEY_START) break; // break in order to return to hbmenu - - //Do the keys printing only if keys have changed - if (kDown != kDownOld || kHeld != kHeldOld || kUp != kUpOld) - { - //Clear console - consoleClear(); - - //These two lines must be rewritten because we cleared the whole console - printf("\x1b[0;0HPress Start to exit."); - printf("\x1b[1;0HCirclePad position:"); - - printf("\x1b[3;0H"); //Move the cursor to the fourth row because on the third one we'll write the circle pad position - - //Check if some of the keys are down, held or up - int i; - for (i = 0; i < 32; i++) - { - if (kDown & BIT(i)) printf("%s down\n", keysNames[i]); - if (kHeld & BIT(i)) printf("%s held\n", keysNames[i]); - if (kUp & BIT(i)) printf("%s up\n", keysNames[i]); - } - } - - //Set keys old values for the next frame - kDownOld = kDown; - kHeldOld = kHeld; - kUpOld = kUp; - - circlePosition pos; - - //Read the CirclePad position - hidCircleRead(&pos); - - //Print the CirclePad position - printf("\x1b[2;0H%04d; %04d", pos.dx, pos.dy); - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - - //Wait for VBlank - gspWaitForVBlank(); - } - - // Exit services - gfxExit(); - return 0; -} diff --git a/examples/input/touch-screen/Makefile b/examples/input/touch-screen/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/input/touch-screen/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/input/touch-screen/source/main.c b/examples/input/touch-screen/source/main.c deleted file mode 100644 index 7a06db0..0000000 --- a/examples/input/touch-screen/source/main.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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 deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/libapplet_launch/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/libapplet_launch/README.md b/examples/libapplet_launch/README.md deleted file mode 100644 index 3b1478b..0000000 --- a/examples/libapplet_launch/README.md +++ /dev/null @@ -1,7 +0,0 @@ -libapplet_launch -======= - -Example for launching library applets. This launches the extrapad library applet(Circle Pad Pro calibration applet) when the B button is pressed. - -This is not usable from the homebrew launcher. - diff --git a/examples/libapplet_launch/source/main.c b/examples/libapplet_launch/source/main.c deleted file mode 100644 index 590262d..0000000 --- a/examples/libapplet_launch/source/main.c +++ /dev/null @@ -1,45 +0,0 @@ -#include <3ds.h> -#include - -static bool allowed = false; - -// If you define this function, you can monitor/debug APT events -void _aptDebug(int a, int b) -{ - if (allowed) - printf("_aptDebug(%d,%x)\n", a, b); -} - -int main() -{ - gfxInitDefault(); - consoleInit(GFX_TOP, NULL); - allowed = true; - - printf("Press B to launch applet\n"); - - // Main loop - while (aptMainLoop()) - { - gspWaitForVBlank(); - gfxSwapBuffers(); - hidScanInput(); - - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - gfxFlushBuffers(); - - // Launch the extrapad library applet when button B is pressed. - if (kDown & KEY_B) - { - Result rc = APT_LaunchLibraryApplet(APPID_EXTRAPAD, 0, NULL, 0); - if (rc) printf("APT_LaunchLibraryApplet: %08lX\n", rc); - } - } - - // Exit services - gfxExit(); - return 0; -} diff --git a/examples/mvd/Makefile b/examples/mvd/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/mvd/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/mvd/README.md b/examples/mvd/README.md deleted file mode 100644 index f6eb32d..0000000 --- a/examples/mvd/README.md +++ /dev/null @@ -1 +0,0 @@ -This example is for using New3DS MVD, for hardware color-format conversion + video processing(the latter is not supported by ctrulib/this example yet). diff --git a/examples/mvd/source/costable.h b/examples/mvd/source/costable.h deleted file mode 100644 index 1c9b8ec..0000000 --- a/examples/mvd/source/costable.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef COSTABLE_H -#define COSTABLE_H - -s32 costable[] = {4096, 4095, 4094, 4093, 4091, 4088, 4084, 4080, 4076, 4071, 4065, 4058, 4051, 4044, 4035, 4026, 4017, 4007, 3996, 3985, 3973, 3960, 3947, 3934, 3919, 3904, 3889, 3873, 3856, 3839, 3821, 3803, 3784, 3765, 3744, 3724, 3703, 3681, 3659, 3636, 3612, 3588, 3564, 3539, 3513, 3487, 3461, 3434, 3406, 3378, 3349, 3320, 3290, 3260, 3229, 3198, 3167, 3135, 3102, 3069, 3035, 3002, 2967, 2932, 2897, 2861, 2825, 2788, 2751, 2714, 2676, 2638, 2599, 2560, 2521, 2481, 2441, 2401, 2360, 2318, 2277, 2235, 2193, 2150, 2107, 2064, 2020, 1976, 1932, 1888, 1843, 1798, 1753, 1707, 1662, 1616, 1569, 1523, 1476, 1429, 1382, 1334, 1287, 1239, 1191, 1143, 1095, 1046, 997, 949, 900, 851, 801, 752, 703, 653, 603, 554, 504, 454, 404, 354, 304, 254, 204, 153, 103, 53, 3, -46, -97, -147, -197, -247, -297, -347, -398, -448, -497, -547, -597, -647, -696, -746, -795, -844, -893, -942, -991, -1040, -1088, -1137, -1185, -1233, -1281, -1328, -1376, -1423, -1470, -1517, -1563, -1610, -1656, -1701, -1747, -1792, -1837, -1882, -1927, -1971, -2015, -2058, -2102, -2144, -2187, -2229, -2271, -2313, -2354, -2395, -2436, -2476, -2516, -2555, -2594, -2633, -2671, -2709, -2747, -2784, -2820, -2857, -2892, -2928, -2963, -2997, -3031, -3065, -3098, -3130, -3163, -3194, -3225, -3256, -3286, -3316, -3345, -3374, -3402, -3430, -3457, -3484, -3510, -3536, -3561, -3585, -3609, -3633, -3656, -3678, -3700, -3721, -3742, -3762, -3782, -3801, -3819, -3837, -3854, -3871, -3887, -3902, -3917, -3932, -3946, -3959, -3971, -3983, -3995, -4005, -4016, -4025, -4034, -4042, -4050, -4057, -4064, -4070, -4075, -4080, -4084, -4087, -4090, -4092, -4094, -4095, -4095, -4095, -4094, -4093, -4091, -4088, -4085, -4081, -4076, -4071, -4066, -4059, -4052, -4045, -4036, -4028, -4018, -4008, -3997, -3986, -3974, -3962, -3949, -3935, -3921, -3906, -3891, -3875, -3858, -3841, -3824, -3805, -3787, -3767, -3747, -3727, -3705, -3684, -3662, -3639, -3615, -3592, -3567, -3542, -3517, -3491, -3464, -3437, -3409, -3381, -3353, -3324, -3294, -3264, -3233, -3202, -3171, -3139, -3106, -3073, -3040, -3006, -2972, -2937, -2902, -2866, -2830, -2793, -2756, -2719, -2681, -2643, -2604, -2565, -2526, -2486, -2446, -2406, -2365, -2324, -2282, -2240, -2198, -2156, -2113, -2069, -2026, -1982, -1938, -1894, -1849, -1804, -1759, -1713, -1668, -1622, -1575, -1529, -1482, -1435, -1388, -1341, -1293, -1245, -1197, -1149, -1101, -1052, -1004, -955, -906, -857, -808, -758, -709, -660, -610, -560, -510, -460, -411, -360, -310, -260, -210, -160, -110, -60, -9, 40, 90, 140, 191, 241, 291, 341, 391, 441, 491, 541, 591, 640, 690, 739, 789, 838, 887, 936, 985, 1033, 1082, 1130, 1179, 1227, 1274, 1322, 1370, 1417, 1464, 1511, 1557, 1604, 1650, 1695, 1741, 1786, 1831, 1876, 1921, 1965, 2009, 2053, 2096, 2139, 2182, 2224, 2266, 2308, 2349, 2390, 2431, 2471, 2511, 2550, 2589, 2628, 2666, 2704, 2742, 2779, 2816, 2852, 2888, 2923, 2958, 2993, 3027, 3060, 3093, 3126, 3158, 3190, 3221, 3252, 3282, 3312, 3342, 3370, 3399, 3426, 3454, 3480, 3507, 3532, 3557, 3582, 3606, 3630, 3653, 3675, 3697, 3718, 3739, 3759, 3779, 3798, 3817, 3835, 3852, 3869, 3885, 3900, 3915, 3930, 3944, 3957, 3970, 3982, 3993, 4004, 4014, 4024, 4033, 4041, 4049, 4056, 4063, 4069, 4074, 4079, 4083, 4087, 4090, 4092, 4094, 4095}; - -#endif diff --git a/examples/mvd/source/main.c b/examples/mvd/source/main.c deleted file mode 100644 index 4e407de..0000000 --- a/examples/mvd/source/main.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include - -#include <3ds.h> - -#include "costable.h" - -u8* inaddr; -u8* outaddr; - -char logstring[256]; - -s32 pcCos(u16 v) -{ - return costable[v&0x1FF]; -} - -void printstring(char *str)//Placeholder until ctrulib itself has proper text drawing. -{ - strncat(logstring, str, sizeof(logstring)-1); -} - -void draw_startup() -{ - Result ret; - - FILE *f = NULL; - - u8* bufAdr = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); - u8* gfxtopadr = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); - - MVDSTD_Config config; - - char str[256]; - - int i, j; - u32 cnt=0; - for(i=0;i<320;i++) - { - for(j=0;j<240;j++) - { - u32 v=(j+i*240)*3; - bufAdr[v]=(pcCos(i+cnt)+4096)/32; - bufAdr[v+1]=(pcCos(j-256+cnt)+4096)/64; - bufAdr[v+2]=(pcCos(i+128-cnt)+4096)/32; - } - } - - f = fopen("sdmc:/mvd_indata.bin", "r"); - if(f) - { - fread(inaddr, 1, 0x46500, f); - fclose(f); - } - else - { - memcpy(inaddr, bufAdr, 320*240*3); - } - - memset(gfxtopadr, 0, 0x46500); - GSPGPU_FlushDataCache(inaddr, 0x46500); - - printstring("mvd example\n"); - - ret = mvdstdInit(MVDMODE_COLORFORMATCONV, MVD_INPUT_YUYV422, MVD_OUTPUT_RGB565, 0); - memset(str, 0, 256); - snprintf(str, sizeof(str)-1, "mvdstdInit(): 0x%08x\n", (unsigned int)ret); - printstring(str); - - if(ret>=0) - { - mvdstdGenerateDefaultConfig(&config, 320, 240, 320, 240, (u32*)inaddr, (u32*)outaddr, (u32*)&outaddr[0x12c00]); - - ret = mvdstdProcessFrame(&config, NULL, 0, 0); - memset(str, 0, 256); - snprintf(str, sizeof(str)-1, "mvdstdProcessFrame(): 0x%08x\n", (unsigned int)ret); - printstring(str); - } - - svcSleepThread(1000000000);//Not sure how to determine when frame processing finishes. - - GSPGPU_InvalidateDataCache(outaddr, 0x100000); - - f = fopen("sdmc:/mvd_outdata.bin", "w"); - if(f) - { - fwrite(outaddr, 1, 0x100000, f); - fclose(f); - } - - f = fopen("sdmc:/mvd_log", "w"); - if(f) - { - fwrite(logstring, 1, strlen(logstring), f); - fclose(f); - } - - memcpy(gfxtopadr, outaddr, 0x46500); - - mvdstdExit(); - - gfxFlushBuffers(); - gfxSwapBuffers(); - gspWaitForVBlank(); -} - -int main() -{ - gfxInitDefault(); - //gfxSet3D(true); // uncomment if using stereoscopic 3D - - memset(logstring, 0, 256); - - inaddr = linearAlloc(0x100000); - outaddr = linearAlloc(0x100000); - - if(inaddr && outaddr) - { - memset(inaddr, 0, 0x100000); - memset(outaddr, 0, 0x100000); - draw_startup(); - } - - // Main loop - while (aptMainLoop()) - { - gspWaitForVBlank(); - hidScanInput(); - - // Your code goes here - - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - } - - if(inaddr)linearFree(inaddr); - if(outaddr)linearFree(outaddr); - - gfxExit(); - return 0; -} - diff --git a/examples/qtm/Makefile b/examples/qtm/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/qtm/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/qtm/README.md b/examples/qtm/README.md deleted file mode 100644 index 2ad4cc6..0000000 --- a/examples/qtm/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# qtm - -This is an example for using New3DS QTM for head-tracking. - -This is currently not usable from the homebrew launcher. - diff --git a/examples/qtm/source/main.c b/examples/qtm/source/main.c deleted file mode 100644 index bf56804..0000000 --- a/examples/qtm/source/main.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include <3ds.h> - -int main() -{ - u32 pos; - u32 x, y; - Result ret; - bool qtm_usable; - QTM_HeadTrackingInfo qtminfo; - u32 colors[4] = {0x0000FF, 0x00FF00, 0xFF0000, 0xFFFFFF}; - - gfxInitDefault(); - //gfxSet3D(true); // uncomment if using stereoscopic 3D - - qtmInit(); - - consoleInit(GFX_BOTTOM, NULL); - - printf("qtm example\n"); - - qtm_usable = qtmCheckInitialized(); - if(!qtm_usable)printf("QTM is not usable, therefore this example won't do anything with QTM.\n"); - - // Main loop - while (aptMainLoop()) - { - gspWaitForVBlank(); - hidScanInput(); - - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - if(qtm_usable) - { - u8* fb = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); - memset(fb, 0, 400*240*3); - - ret = QTM_GetHeadTrackingInfo(0, &qtminfo); - if(ret==0) - { - consoleClear(); - - for(pos=0; pos<5; pos++) - { - printf("flags[%x]=0x%x", (unsigned int)pos, qtminfo.flags[pos]); - if(pos<4)printf(", "); - } - - printf("\nfloatdata_x08: %f\n", qtminfo.floatdata_x08); - - printf("coords0: "); - for(pos=0; pos<4; pos++) - { - printf("[%x].x=%f, y=%f", (unsigned int)pos, qtminfo.coords0[pos].x, qtminfo.coords0[pos].y); - if(pos<3)printf(", "); - } - - printf("\n"); - - if(qtmCheckHeadFullyDetected(&qtminfo)) - { - for(pos=0; pos<4; pos++) - { - ret = qtmConvertCoordToScreen(&qtminfo.coords0[pos], NULL, NULL, &x, &y); - - if(ret==0)memcpy(&fb[(x*240 + y) * 3], &colors[pos], 3); - } - } - } - } - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - } - - // Exit services - qtmExit(); - gfxExit(); - return 0; -} - diff --git a/examples/romfs/Makefile b/examples/romfs/Makefile deleted file mode 100644 index 8f0d372..0000000 --- a/examples/romfs/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/romfs/romfs/folder/file.txt b/examples/romfs/romfs/folder/file.txt deleted file mode 100644 index 2454092..0000000 --- a/examples/romfs/romfs/folder/file.txt +++ /dev/null @@ -1,6 +0,0 @@ -Hello, this is the libctru romfs example. -This text is being read off a file in romfs. - - >>3DS Homebrew is Cool<< - -Signed off, fincs diff --git a/examples/romfs/romfs/フォルダ/ファイル.txt b/examples/romfs/romfs/フォルダ/ファイル.txt deleted file mode 100644 index 2cd922e..0000000 --- a/examples/romfs/romfs/フォルダ/ファイル.txt +++ /dev/null @@ -1,2 +0,0 @@ -The path to this file contains UTF-16 -characters that fall outside ASCII. diff --git a/examples/romfs/source/main.c b/examples/romfs/source/main.c deleted file mode 100644 index eb89630..0000000 --- a/examples/romfs/source/main.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include -#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; -} diff --git a/examples/sdmc/Makefile b/examples/sdmc/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/sdmc/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/sdmc/README.md b/examples/sdmc/README.md deleted file mode 100644 index 4658c41..0000000 --- a/examples/sdmc/README.md +++ /dev/null @@ -1,5 +0,0 @@ -sdmc -======= - -very simple example of how to access SD files with libctru; - diff --git a/examples/sdmc/source/costable.c b/examples/sdmc/source/costable.c deleted file mode 100644 index 7788b2d..0000000 --- a/examples/sdmc/source/costable.c +++ /dev/null @@ -1,50 +0,0 @@ -#include <3ds/types.h> - -s32 costable[] = { 4096, 4095, 4094, 4093, 4091, 4088, 4084, 4080, 4076, 4071, 4065, - 4058, 4051, 4044, 4035, 4026, 4017, 4007, 3996, 3985, 3973, 3960, - 3947, 3934, 3919, 3904, 3889, 3873, 3856, 3839, 3821, 3803, 3784, - 3765, 3744, 3724, 3703, 3681, 3659, 3636, 3612, 3588, 3564, 3539, - 3513, 3487, 3461, 3434, 3406, 3378, 3349, 3320, 3290, 3260, 3229, - 3198, 3167, 3135, 3102, 3069, 3035, 3002, 2967, 2932, 2897, 2861, - 2825, 2788, 2751, 2714, 2676, 2638, 2599, 2560, 2521, 2481, 2441, - 2401, 2360, 2318, 2277, 2235, 2193, 2150, 2107, 2064, 2020, 1976, - 1932, 1888, 1843, 1798, 1753, 1707, 1662, 1616, 1569, 1523, 1476, - 1429, 1382, 1334, 1287, 1239, 1191, 1143, 1095, 1046, 997, 949, - 900, 851, 801, 752, 703, 653, 603, 554, 504, 454, 404, 354, 304, - 254, 204, 153, 103, 53, 3, -46, -97, -147, -197, -247, -297, -347, - -398, -448, -497, -547, -597, -647, -696, -746, -795, -844, -893, - -942, -991, -1040, -1088, -1137, -1185, -1233, -1281, -1328, -1376, - -1423, -1470, -1517, -1563, -1610, -1656, -1701, -1747, -1792, -1837, - -1882, -1927, -1971, -2015, -2058, -2102, -2144, -2187, -2229, -2271, - -2313, -2354, -2395, -2436, -2476, -2516, -2555, -2594, -2633, -2671, - -2709, -2747, -2784, -2820, -2857, -2892, -2928, -2963, -2997, -3031, - -3065, -3098, -3130, -3163, -3194, -3225, -3256, -3286, -3316, -3345, - -3374, -3402, -3430, -3457, -3484, -3510, -3536, -3561, -3585, -3609, - -3633, -3656, -3678, -3700, -3721, -3742, -3762, -3782, -3801, -3819, - -3837, -3854, -3871, -3887, -3902, -3917, -3932, -3946, -3959, -3971, - -3983, -3995, -4005, -4016, -4025, -4034, -4042, -4050, -4057, -4064, - -4070, -4075, -4080, -4084, -4087, -4090, -4092, -4094, -4095, -4095, - -4095, -4094, -4093, -4091, -4088, -4085, -4081, -4076, -4071, -4066, - -4059, -4052, -4045, -4036, -4028, -4018, -4008, -3997, -3986, -3974, - -3962, -3949, -3935, -3921, -3906, -3891, -3875, -3858, -3841, -3824, - -3805, -3787, -3767, -3747, -3727, -3705, -3684, -3662, -3639, -3615, - -3592, -3567, -3542, -3517, -3491, -3464, -3437, -3409, -3381, -3353, - -3324, -3294, -3264, -3233, -3202, -3171, -3139, -3106, -3073, -3040, - -3006, -2972, -2937, -2902, -2866, -2830, -2793, -2756, -2719, -2681, - -2643, -2604, -2565, -2526, -2486, -2446, -2406, -2365, -2324, -2282, - -2240, -2198, -2156, -2113, -2069, -2026, -1982, -1938, -1894, -1849, - -1804, -1759, -1713, -1668, -1622, -1575, -1529, -1482, -1435, -1388, - -1341, -1293, -1245, -1197, -1149, -1101, -1052, -1004, -955, -906, - -857, -808, -758, -709, -660, -610, -560, -510, -460, -411, -360, - -310, -260, -210, -160, -110, -60, -9, 40, 90, 140, 191, 241, 291, - 341, 391, 441, 491, 541, 591, 640, 690, 739, 789, 838, 887, 936, - 985, 1033, 1082, 1130, 1179, 1227, 1274, 1322, 1370, 1417, 1464, - 1511, 1557, 1604, 1650, 1695, 1741, 1786, 1831, 1876, 1921, 1965, - 2009, 2053, 2096, 2139, 2182, 2224, 2266, 2308, 2349, 2390, 2431, - 2471, 2511, 2550, 2589, 2628, 2666, 2704, 2742, 2779, 2816, 2852, - 2888, 2923, 2958, 2993, 3027, 3060, 3093, 3126, 3158, 3190, 3221, - 3252, 3282, 3312, 3342, 3370, 3399, 3426, 3454, 3480, 3507, 3532, - 3557, 3582, 3606, 3630, 3653, 3675, 3697, 3718, 3739, 3759, 3779, - 3798, 3817, 3835, 3852, 3869, 3885, 3900, 3915, 3930, 3944, 3957, - 3970, 3982, 3993, 4004, 4014, 4024, 4033, 4041, 4049, 4056, 4063, - 4069, 4074, 4079, 4083, 4087, 4090, 4092, 4094, 4095}; diff --git a/examples/sdmc/source/costable.h b/examples/sdmc/source/costable.h deleted file mode 100644 index f53eb36..0000000 --- a/examples/sdmc/source/costable.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef COSTABLE_H -#define COSTABLE_H - -extern s32 costable[]; - -#endif diff --git a/examples/sdmc/source/main.c b/examples/sdmc/source/main.c deleted file mode 100644 index 9e9dde6..0000000 --- a/examples/sdmc/source/main.c +++ /dev/null @@ -1,98 +0,0 @@ -/////////////////////////////////////// -// SDMC example // -/////////////////////////////////////// - -//this example shows you how to load a binary image file from the SD card and display it on the lower screen -//for this to work you should copy test.bin to same folder as your .3dsx -//this file was generated with GIMP by saving a 240x320 image to raw RGB -#include -#include -#include - -#include <3ds.h> -#include "costable.h" - -//this will contain the data read from SDMC -u8* buffer; - -//3DS has VFPs so we could just use cos -//but we're old school so LUT4life -s32 pcCos(u16 v) -{ - return costable[v&0x1FF]; -} - -void renderEffect() -{ - static int cnt; - u8* bufAdr=gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); - - int i, j; - for(i=1;i<400;i++) - { - for(j=1;j<240;j++) - { - u32 v=(j+i*240)*3; - bufAdr[v]=(pcCos(i+cnt)+4096)/32; - bufAdr[v+1]=(pcCos(j-256+cnt)+4096)/64; - bufAdr[v+2]=(pcCos(i+128-cnt)+4096)/32; - } - } - - cnt++; -} - -int main(int argc, char** argv) -{ - - gfxInitDefault(); //makes displaying to screen easier - - FILE *file = fopen("test.bin","rb"); - if (file == NULL) goto exit; - - // seek to end of file - fseek(file,0,SEEK_END); - - // file pointer tells us the size - off_t size = ftell(file); - - // seek back to start - fseek(file,0,SEEK_SET); - - //allocate a buffer - buffer=malloc(size); - if(!buffer)goto exit; - - //read contents ! - off_t bytesRead = fread(buffer,1,size,file); - - //close the file because we like being nice and tidy - fclose(file); - - if(size!=bytesRead)goto exit; - - while(aptMainLoop()) - { - //exit when user hits B - hidScanInput(); - if(keysHeld()&KEY_B)break; - - //render rainbow - renderEffect(); - - //copy buffer to lower screen (don't have to do it every frame) - memcpy(gfxGetFramebuffer(GFX_BOTTOM, GFX_BOTTOM, NULL, NULL), buffer, size); - - //wait & swap - gfxSwapBuffersGpu(); - gspWaitForEvent(GSPGPU_EVENT_VBlank0, false); - } - - //cleanup and return - //returning from main() returns to hbmenu when run under ninjhax - exit: - - //closing all services even more so - gfxExit(); - return 0; -} diff --git a/examples/sdmc/test.bin b/examples/sdmc/test.bin deleted file mode 100644 index 7081df1..0000000 --- a/examples/sdmc/test.bin +++ /dev/null @@ -1 +0,0 @@ -ǽ˾öɹʿ̿ǽ}}}}}}yyytttuuuwwwzzzqqqmmmmmmqqq{{{tttllljjjjjjmmmtttvvvnnnkkkkkkooovvvƼwwwpppmmmoooqqqzzzƼ{{{tttvvvzzzźƼǹĶƸƷƷŶŶĵĵĴĵĴĵŵŶŶƷƶƸƵŸƶƹǸȻ˻˿ŹƻȼĻſ¿ƼƼžºȽǻɽ·ʽ¿ĹĿ˽þǿſĹƽĿƹǹɼýǸ÷ȽɹοʼɻɼȺʼƵν;´ϿʽĵƺŶIJŶö;ƷƴȹƷȺķƸɸƸɹɺƸ̹ĶƸ˺Ʒ˹̿ƸǷ̽Ŷƴ¶²ĽѾ̻̽˿ɷùõ²ĸɽƿļĻŽ»ǼǺµʻ¾;òõŵŸƵƸƵŸŵĸŵĵôϾʻƹ´˻Ÿ̾Ǻɻõͽǹ¶˽Ƹ˼Ÿ̼ƶõξʺŷ³Ǿ˻ĶƸʸ÷îøѽ~~~ƻѼ~~~zzz|||ҽzzz~~~­ƱͺϼïŵƵƷŶŶŵĵĴĵĴĵĵĵĵij³пμȷIJҾ˻ɴĴŲ³ijȹÿľľǽ¶µþɼĴ̻ʺɹ˹ʻ̼õſǸ¹ͼóķȺʽͿŹŶŷ̽̾ķƷ̼ǸŷǺ˾µǺ˾µɾ;ýɼƾʿÿżǿÿ¼¼þ \ No newline at end of file diff --git a/examples/templates/Makefile b/examples/templates/Makefile deleted file mode 100644 index bce05ec..0000000 --- a/examples/templates/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -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/templates/application/Makefile b/examples/templates/application/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/templates/application/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/templates/application/README.md b/examples/templates/application/README.md deleted file mode 100644 index 8a43ac1..0000000 --- a/examples/templates/application/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# template - -This is a template for starting new 3DS libctru projects. diff --git a/examples/templates/application/source/main.c b/examples/templates/application/source/main.c deleted file mode 100644 index 633c7ff..0000000 --- a/examples/templates/application/source/main.c +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#include <3ds.h> - -int main() -{ - gfxInitDefault(); - //gfxSet3D(true); // uncomment if using stereoscopic 3D - - // Main loop - while (aptMainLoop()) - { - gspWaitForVBlank(); - hidScanInput(); - - // Your code goes here - - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - // Example rendering code that displays a white pixel - // Please note that the 3DS screens are sideways (thus 240x400 and 240x320) - u8* fb = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); - memset(fb, 0, 240*400*3); - fb[3*(10+10*240)] = 0xFF; - fb[3*(10+10*240)+1] = 0xFF; - fb[3*(10+10*240)+2] = 0xFF; - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - } - - gfxExit(); - return 0; -} diff --git a/examples/templates/library/Makefile b/examples/templates/library/Makefile deleted file mode 100644 index d982f90..0000000 --- a/examples/templates/library/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- - -ifeq ($(strip $(DEVKITARM)),) -$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") -endif - -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 -#--------------------------------------------------------------------------------- -TARGET := $(shell basename $(CURDIR)) -BUILD := build -SOURCES := source -DATA := data -INCLUDES := include - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(ARCH) - -CFLAGS += $(INCLUDE) -DARM11 -D_3DS -CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions - -ASFLAGS := -g $(ARCH) - -#--------------------------------------------------------------------------------- -# 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)/lib/lib$(TARGET).a - -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) - -.PHONY: $(BUILD) clean all - -#--------------------------------------------------------------------------------- -all: $(BUILD) - -lib: - @[ -d $@ ] || mkdir -p $@ - -$(BUILD): lib - @[ -d $@ ] || mkdir -p $@ - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - -#--------------------------------------------------------------------------------- -clean: - @echo clean ... - @rm -fr $(BUILD) lib - -#--------------------------------------------------------------------------------- -else - -DEPENDS := $(OFILES:.o=.d) - -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- -$(OUTPUT) : $(OFILES) - -#--------------------------------------------------------------------------------- -%.bin.o : %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/templates/library/README.md b/examples/templates/library/README.md deleted file mode 100644 index 8089b6e..0000000 --- a/examples/templates/library/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# template - -This is a template for starting new 3DS library projects. diff --git a/examples/templates/library/include/templatelib.h b/examples/templates/library/include/templatelib.h deleted file mode 100644 index 1d02448..0000000 --- a/examples/templates/library/include/templatelib.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _templatelib_h_ -#define _templatelib_h_ - -int myLibFunction(); - -#endif // _templatelib_h_ diff --git a/examples/templates/library/source/templatelib.c b/examples/templates/library/source/templatelib.c deleted file mode 100644 index 570d9e5..0000000 --- a/examples/templates/library/source/templatelib.c +++ /dev/null @@ -1,6 +0,0 @@ -int myLibFunction() { - - - return 42; - -} diff --git a/examples/threads/Makefile b/examples/threads/Makefile deleted file mode 100644 index bce05ec..0000000 --- a/examples/threads/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -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 deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/threads/event/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/threads/event/source/main.c b/examples/threads/event/source/main.c deleted file mode 100644 index 7d75cee..0000000 --- a/examples/threads/event/source/main.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include - - -#include <3ds.h> - -Thread threadHandle; -Handle threadRequest; - -#define STACKSIZE (4 * 1024) - -volatile bool runThread = true; - -volatile int threadcount=0; - -void threadMain(void *arg) { - - while(runThread) { - svcWaitSynchronization(threadRequest, U64_MAX); - svcClearEvent(threadRequest); - - threadcount++; - } -} - -int main(int argc, char** argv) -{ - gfxInitDefault(); - consoleInit(GFX_TOP, NULL); - - svcCreateEvent(&threadRequest,0); - threadHandle = threadCreate(threadMain, 0, STACKSIZE, 0x3f, -2, true); - - printf("thread handle: %p\n", threadHandle); - - // 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 - runThread = false; - - // signal the thread and wait for it to exit - svcSignalEvent(threadRequest); - threadJoin(threadHandle, U64_MAX); - - // close event handle - svcCloseHandle(threadRequest); - - gfxExit(); - return 0; -} diff --git a/examples/threads/thread-basic/Makefile b/examples/threads/thread-basic/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/threads/thread-basic/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/threads/thread-basic/source/main.c b/examples/threads/thread-basic/source/main.c deleted file mode 100644 index af4011e..0000000 --- a/examples/threads/thread-basic/source/main.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include <3ds.h> - -#define NUMTHREADS 3 -#define STACKSIZE (4 * 1024) - -volatile bool runThreads = true; - -void threadMain(void *arg) -{ - u64 sleepDuration = 1000000ULL * (u32)arg; - int i = 0; - while (runThreads) - { - printf("thread%d says %d\n", (int)arg, i++); - svcSleepThread(sleepDuration); - } -} - -int main(int argc, char** argv) -{ - gfxInitDefault(); - consoleInit(GFX_TOP, NULL); - - Thread threads[NUMTHREADS]; - int i; - s32 prio = 0; - svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); - printf("Main thread prio: 0x%lx\n", prio); - - for (i = 0; i < NUMTHREADS; i ++) - { - // The priority of these child threads must be higher (aka the value is lower) than that - // of the main thread, otherwise there is thread starvation due to stdio being locked. - threads[i] = threadCreate(threadMain, (void*)((i+1)*250), STACKSIZE, prio-1, -2, false); - printf("created thread %d: %p\n", i, threads[i]); - } - - // Main loop - while (aptMainLoop()) - { - gspWaitForVBlank(); - hidScanInput(); - - u32 kDown = hidKeysDown(); - if (kDown & KEY_START) - break; // break in order to return to hbmenu - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - } - - // tell threads to exit & wait for them to exit - runThreads = false; - for (i = 0; i < NUMTHREADS; i ++) - { - threadJoin(threads[i], U64_MAX); - threadFree(threads[i]); - } - - gfxExit(); - return 0; -} diff --git a/examples/time/rtc/Makefile b/examples/time/rtc/Makefile deleted file mode 100644 index 4f5cda2..0000000 --- a/examples/time/rtc/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -#--------------------------------------------------------------------------------- -.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. -# 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): -# - .png -# - icon.png -# - /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 -mtp=soft - -CFLAGS := -g -Wall -O2 -mword-relocations \ - -fomit-frame-pointer -ffunction-sections \ - $(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))) -PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) -SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) -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)) \ - $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \ - $(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) - -#--------------------------------------------------------------------------------- -# rules for assembling GPU shaders -#--------------------------------------------------------------------------------- -define shader-as - $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@))) - picasso -o $(CURBIN) $1 - 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 - echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h -endef - -%.shbin.o : %.v.pica %.g.pica - @echo $(notdir $^) - @$(call shader-as,$^) - -%.shbin.o : %.v.pica - @echo $(notdir $<) - @$(call shader-as,$<) - -%.shbin.o : %.shlist - @echo $(notdir $<) - @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/examples/time/rtc/source/main.c b/examples/time/rtc/source/main.c deleted file mode 100644 index 6139185..0000000 --- a/examples/time/rtc/source/main.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - RTC example made by Aurelio Mannara for ctrulib - This code was modified for the last time on: 12/13/2014 2:45 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 -#include - -int main(int argc, char **argv) -{ - // Initialize services - 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[29;15HPress Start to exit."); - - // 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 - - //Print current time - time_t unixTime = time(NULL); - struct tm* timeStruct = gmtime((const time_t *)&unixTime); - - int hours = timeStruct->tm_hour; - int minutes = timeStruct->tm_min; - int seconds = timeStruct->tm_sec; - int day = timeStruct->tm_mday; - int month = timeStruct->tm_mon; - int year = timeStruct->tm_year +1900; - - printf("\x1b[0;0H%02i:%02i:%02i", hours, minutes, seconds); - printf("\x1b[1;0H%02i/%02i/%04i", day, month, year); - - // Flush and swap framebuffers - gfxFlushBuffers(); - gfxSwapBuffers(); - - //Wait for VBlank - gspWaitForVBlank(); - } - - // Exit services - gfxExit(); - - return 0; -} diff --git a/exportdoc.sh b/exportdoc.sh index b70a992..9e9e480 100644 --- a/exportdoc.sh +++ b/exportdoc.sh @@ -2,6 +2,7 @@ if [ "$TRAVIS_REPO_SLUG" = "smealum/ctrulib" ] && [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ -n "$TRAVIS_TAG" ]; then git clone --branch=gh-pages --single-branch --depth 1 https://${GH_TOKEN}@github.com/$TRAVIS_REPO_SLUG docs git rm -rf docs/* +git clone --branch=master --single-branch --depth 1 https://github.com/devkitPro/3ds-examples examples cd libctru doxygen Doxyfile mv ./docs/html/* ../docs diff --git a/libctru/include/3ds.h b/libctru/include/3ds.h index 030853c..1a7b2f9 100644 --- a/libctru/include/3ds.h +++ b/libctru/include/3ds.h @@ -79,47 +79,11 @@ extern "C" { * @example graphics/printing/both-screen-text/source/main.c * @example graphics/printing/colored-text/source/main.c * @example graphics/printing/multiple-windows-text/source/main.c - + * @example graphics/gpu/fragment_light/source/main.c * @example graphics/gpu/geoshader/source/main.c - graphics/gpu/geoshader/source/gpu.h - @include graphics/gpu/geoshader/source/gpu.h - graphics/gpu/geoshader/source/gpu.c - @include graphics/gpu/geoshader/source/gpu.c - graphics/gpu/geoshader/source/3dmath.h - @include graphics/gpu/geoshader/source/3dmath.h - graphics/gpu/geoshader/source/3dmath.c - @include graphics/gpu/geoshader/source/3dmath.c - graphics/gpu/geoshader/source/vshader.pica - @include graphics/gpu/geoshader/source/vshader.pica - graphics/gpu/geoshader/source/gshader.pica - @include graphics/gpu/geoshader/source/gshader.pica - - + * @example graphics/gpu/immediate/source/main.c * @example graphics/gpu/simple_tri/source/main.c - graphics/gpu/simple_tri/source/gpu.h - @include graphics/gpu/simple_tri/source/gpu.h - graphics/gpu/simple_tri/source/gpu.c - @include graphics/gpu/simple_tri/source/gpu.c - graphics/gpu/simple_tri/source/3dmath.h - @include graphics/gpu/simple_tri/source/3dmath.h - graphics/gpu/simple_tri/source/3dmath.c - @include graphics/gpu/simple_tri/source/3dmath.c - graphics/gpu/simple_tri/source/vshader.pica - @include graphics/gpu/simple_tri/source/vshader.pica - - * @example graphics/gpu/textured_cube/source/main.c - graphics/gpu/textured_cube/source/gpu.h - @include graphics/gpu/textured_cube/source/gpu.h - graphics/gpu/textured_cube/source/gpu.c - @include graphics/gpu/textured_cube/source/gpu.c - graphics/gpu/textured_cube/source/3dmath.h - @include graphics/gpu/textured_cube/source/3dmath.h - graphics/gpu/textured_cube/source/3dmath.c - @include graphics/gpu/textured_cube/source/3dmath.c - graphics/gpu/textured_cube/source/vshader.pica - @include graphics/gpu/textured_cube/source/vshader.pica - * @example http/source/main.c * @example input/read-controls/source/main.c * @example input/touch-screen/source/main.c