├── EULASetter.xml
├── Makefile
├── README.md
├── img
└── screenshot.png
└── source
└── main.c
/EULASetter.xml:
--------------------------------------------------------------------------------
1 |
2 | 0004001000020000
3 | 0004001000021000
4 | 0004001000022000
5 | 0004001000026000
6 | 0004001000027000
7 | 0004001000028000
8 |
9 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #---------------------------------------------------------------------------------
2 | .SUFFIXES:
3 | #---------------------------------------------------------------------------------
4 |
5 | ifeq ($(strip $(DEVKITARM)),)
6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM")
7 | endif
8 |
9 | TOPDIR ?= $(CURDIR)
10 | include $(DEVKITARM)/3ds_rules
11 |
12 | #---------------------------------------------------------------------------------
13 | # TARGET is the name of the output
14 | # BUILD is the directory where object files & intermediate files will be placed
15 | # SOURCES is a list of directories containing source code
16 | # DATA is a list of directories containing data files
17 | # INCLUDES is a list of directories containing header files
18 | #
19 | # NO_SMDH: if set to anything, no SMDH file is generated.
20 | # ROMFS is the directory which contains the RomFS, relative to the Makefile (Optional)
21 | # APP_TITLE is the name of the app stored in the SMDH file (Optional)
22 | # APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional)
23 | # APP_AUTHOR is the author of the app stored in the SMDH file (Optional)
24 | # ICON is the filename of the icon (.png), relative to the project folder.
25 | # If not set, it attempts to use one of the following (in this order):
26 | # - .png
27 | # - icon.png
28 | # - /default_icon.png
29 | #---------------------------------------------------------------------------------
30 | TARGET := $(notdir $(CURDIR))
31 | BUILD := build
32 | SOURCES := source
33 | DATA := data
34 | INCLUDES := include
35 |
36 | APP_TITLE := EULA Setter
37 | APP_DESCRIPTION := Set your EULA version!
38 | APP_AUTHOR := SciresM
39 |
40 | #---------------------------------------------------------------------------------
41 | # options for code generation
42 | #---------------------------------------------------------------------------------
43 | ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
44 |
45 | CFLAGS := -g -Wall -O2 -mword-relocations \
46 | -fomit-frame-pointer -ffunction-sections \
47 | $(ARCH)
48 |
49 | CFLAGS += $(INCLUDE) -DARM11 -D_3DS
50 |
51 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
52 |
53 | ASFLAGS := -g $(ARCH)
54 | LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
55 |
56 | LIBS := -lctru -lm
57 |
58 | #---------------------------------------------------------------------------------
59 | # list of directories containing libraries, this must be the top level containing
60 | # include and lib
61 | #---------------------------------------------------------------------------------
62 | LIBDIRS := $(CTRULIB)
63 |
64 |
65 | #---------------------------------------------------------------------------------
66 | # no real need to edit anything past this point unless you need to add additional
67 | # rules for different file extensions
68 | #---------------------------------------------------------------------------------
69 | ifneq ($(BUILD),$(notdir $(CURDIR)))
70 | #---------------------------------------------------------------------------------
71 |
72 | export OUTPUT := $(CURDIR)/$(TARGET)
73 | export TOPDIR := $(CURDIR)
74 |
75 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
76 | $(foreach dir,$(DATA),$(CURDIR)/$(dir))
77 |
78 | export DEPSDIR := $(CURDIR)/$(BUILD)
79 |
80 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
81 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
82 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
83 | PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica)))
84 | SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist)))
85 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
86 |
87 | #---------------------------------------------------------------------------------
88 | # use CXX for linking C++ projects, CC for standard C
89 | #---------------------------------------------------------------------------------
90 | ifeq ($(strip $(CPPFILES)),)
91 | #---------------------------------------------------------------------------------
92 | export LD := $(CC)
93 | #---------------------------------------------------------------------------------
94 | else
95 | #---------------------------------------------------------------------------------
96 | export LD := $(CXX)
97 | #---------------------------------------------------------------------------------
98 | endif
99 | #---------------------------------------------------------------------------------
100 |
101 | export OFILES := $(addsuffix .o,$(BINFILES)) \
102 | $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \
103 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
104 |
105 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
106 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
107 | -I$(CURDIR)/$(BUILD)
108 |
109 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
110 |
111 | ifeq ($(strip $(ICON)),)
112 | icons := $(wildcard *.png)
113 | ifneq (,$(findstring $(TARGET).png,$(icons)))
114 | export APP_ICON := $(TOPDIR)/$(TARGET).png
115 | else
116 | ifneq (,$(findstring icon.png,$(icons)))
117 | export APP_ICON := $(TOPDIR)/icon.png
118 | endif
119 | endif
120 | else
121 | export APP_ICON := $(TOPDIR)/$(ICON)
122 | endif
123 |
124 | ifeq ($(strip $(NO_SMDH)),)
125 | export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh
126 | endif
127 |
128 | ifneq ($(ROMFS),)
129 | export _3DSXFLAGS += --romfs=$(CURDIR)/$(ROMFS)
130 | endif
131 |
132 | .PHONY: $(BUILD) clean all
133 |
134 | #---------------------------------------------------------------------------------
135 | all: $(BUILD)
136 |
137 | $(BUILD):
138 | @[ -d $@ ] || mkdir -p $@
139 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
140 |
141 | #---------------------------------------------------------------------------------
142 | clean:
143 | @echo clean ...
144 | @rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf
145 |
146 |
147 | #---------------------------------------------------------------------------------
148 | else
149 |
150 | DEPENDS := $(OFILES:.o=.d)
151 |
152 | #---------------------------------------------------------------------------------
153 | # main targets
154 | #---------------------------------------------------------------------------------
155 | ifeq ($(strip $(NO_SMDH)),)
156 | $(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh
157 | else
158 | $(OUTPUT).3dsx : $(OUTPUT).elf
159 | endif
160 |
161 | $(OUTPUT).elf : $(OFILES)
162 |
163 | #---------------------------------------------------------------------------------
164 | # you need a rule like this for each extension you use as binary data
165 | #---------------------------------------------------------------------------------
166 | %.bin.o : %.bin
167 | #---------------------------------------------------------------------------------
168 | @echo $(notdir $<)
169 | @$(bin2o)
170 |
171 | #---------------------------------------------------------------------------------
172 | # rules for assembling GPU shaders
173 | #---------------------------------------------------------------------------------
174 | define shader-as
175 | $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@)))
176 | picasso -o $(CURBIN) $1
177 | bin2s $(CURBIN) | $(AS) -o $@
178 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h
179 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h
180 | echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h
181 | endef
182 |
183 | %.shbin.o : %.v.pica %.g.pica
184 | @echo $(notdir $^)
185 | @$(call shader-as,$^)
186 |
187 | %.shbin.o : %.v.pica
188 | @echo $(notdir $<)
189 | @$(call shader-as,$<)
190 |
191 | %.shbin.o : %.shlist
192 | @echo $(notdir $<)
193 | @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file)))
194 |
195 | -include $(DEPENDS)
196 |
197 | #---------------------------------------------------------------------------------------
198 | endif
199 | #---------------------------------------------------------------------------------------
200 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is an example homebrew using cfg:i service commands to adjust the agreed EULA version value in the config NAND savegame.
2 |
3 | 
--------------------------------------------------------------------------------
/img/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SciresM/EULASetter/ba3b52b97f4473fe55c642f34644fc0cc8b7830a/img/screenshot.png
--------------------------------------------------------------------------------
/source/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include <3ds.h>
5 |
6 | #define HIGH 1
7 | #define LOW 0
8 |
9 | static uint8_t eulaData[4];
10 | static PrintConsole *console;
11 | static int x, y;
12 |
13 | static int modIndex;
14 |
15 | // Function prototypes
16 | static void initStatics(void);
17 | static uint16_t getEulaVersion(void);
18 | static void setEulaVersion(uint16_t version);
19 | static void refreshEulaVal(void);
20 |
21 | int main(int argc, char **argv)
22 | {
23 | // Initialize services
24 | aptInit();
25 | gfxInitDefault();
26 | hidInit();
27 | cfguInit();
28 |
29 | initStatics();
30 |
31 | refreshEulaVal();
32 | uint16_t origVal = getEulaVersion();
33 |
34 | //Flushes the buffer
35 | gfxFlushBuffers();
36 | gfxSwapBuffers();
37 |
38 | while(aptMainLoop()) //Always have the main code loop in here
39 | {
40 | hidScanInput(); //Checks which keys are pressed
41 |
42 | u32 button = hidKeysDown(); // Checks which keys are up and which ones are down
43 | if (button & KEY_LEFT)
44 | {
45 | modIndex = HIGH;
46 | refreshEulaVal();
47 | }
48 | if (button & KEY_RIGHT)
49 | {
50 | modIndex = LOW;
51 | refreshEulaVal();
52 | }
53 | if (button & KEY_UP)
54 | {
55 | eulaData[modIndex] += 1;
56 | refreshEulaVal();
57 | }
58 | if (button & KEY_DOWN)
59 | {
60 | eulaData[modIndex] -= 1;
61 | refreshEulaVal();
62 | }
63 | if (button & KEY_X)
64 | {
65 | setEulaVersion(0xFFFF);
66 | refreshEulaVal();
67 | }
68 | if (button & KEY_Y)
69 | {
70 | setEulaVersion(0x0000);
71 | refreshEulaVal();
72 | }
73 | if (button & KEY_START)
74 | {
75 | CFG_UpdateConfigNANDSavegame();
76 | break;
77 | }
78 | if (button & KEY_SELECT)
79 | {
80 | setEulaVersion(origVal);
81 | CFG_UpdateConfigNANDSavegame();
82 | break;
83 | }
84 | }
85 |
86 | // Exit services
87 | aptExit();
88 | gfxExit();
89 | hidExit();
90 | cfguExit();
91 | return 0;
92 | }
93 |
94 | static void initStatics(void)
95 | {
96 | // Initialize static pointers/values
97 | console = consoleInit(GFX_TOP, NULL);
98 | printf("\nEULA Setter:\n");
99 | printf("Press UP to increase selected byte\n");
100 | printf("Press DOWN to decrease selected byte\n");
101 | printf("Press LEFT to modify high byte\n");
102 | printf("Press RIGHT to modify low byte\n");
103 | printf("Press X for 0xFFFF\n");
104 | printf("Press Y for 0x0000\n");
105 | printf("Press START to save and exit\n");
106 | printf("Press SELECT to exit without saving\n\n");
107 | printf("Current accepted EULA version: ");
108 |
109 | x = console->cursorX;
110 | y = console->cursorY;
111 |
112 | modIndex = LOW;
113 |
114 | CFGU_GetConfigInfoBlk2(4, 0xD0000, eulaData);
115 | }
116 |
117 | static uint16_t getEulaVersion(void)
118 | {
119 | return (uint16_t)((eulaData[HIGH] << 8) | (eulaData[LOW]));
120 | }
121 |
122 | static void setEulaVersion(uint16_t version)
123 | {
124 | *((uint16_t *)eulaData) = version;
125 | CFG_SetConfigInfoBlk8(4, 0xD0000, eulaData);
126 | }
127 |
128 | static void refreshEulaVal(void)
129 | {
130 | console->cursorX = x;
131 | console->cursorY = y;
132 | setEulaVersion(getEulaVersion());
133 | if (modIndex == LOW)
134 | {
135 | printf(" %02X .[%02X]\n\n", eulaData[HIGH], eulaData[LOW]);
136 | }
137 | else
138 | {
139 | printf("[%02X]. %02X \n\n", eulaData[HIGH], eulaData[LOW]);
140 | }
141 | }
--------------------------------------------------------------------------------