├── .gitignore ├── JKSM.rsf ├── Makefile ├── README.md ├── banner ├── data └── font.ttf ├── filter.txt ├── icon ├── icon.png ├── include ├── 3dsx.h ├── archive.h ├── backup.h ├── backupmenu.h ├── date.h ├── db.h ├── dev.h ├── extmenu.h ├── extra.h ├── file.h ├── global.h ├── gstr.h ├── hbfilter.h ├── img.h ├── menu.h ├── nand.h ├── restore.h ├── savemenu.h ├── sd_cia.h ├── sdpath.h ├── shared.h ├── slot.h ├── smdh.h ├── sys.h ├── titledata.h ├── titles.h ├── ui.h └── util.h └── source ├── 3dsx.cpp ├── archive.cpp ├── backup.cpp ├── backupmenu.cpp ├── date.cpp ├── db.cpp ├── dev.cpp ├── extmenu.cpp ├── extra.cpp ├── file.cpp ├── global.cpp ├── gstr.cpp ├── hbfilter.cpp ├── main.cpp ├── menu.cpp ├── nand.cpp ├── progBar.c ├── restore.cpp ├── savemenu.cpp ├── sd_cia.cpp ├── sdpath.cpp ├── shared.cpp ├── slot.cpp ├── smdh.cpp ├── sys.cpp ├── textBoxTex.c ├── titledata.cpp ├── titles.cpp ├── topBar.c ├── ui.cpp └── util.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | test/ 3 | release/ 4 | .codelite/ 5 | *.o 6 | *.elf 7 | *.wav 8 | *.cbp 9 | *.layout 10 | *.smdh 11 | *.exe 12 | *.log 13 | *.7z 14 | *.project 15 | *.cia 16 | *.3dsx -------------------------------------------------------------------------------- /JKSM.rsf: -------------------------------------------------------------------------------- 1 | BasicInfo: 2 | Title : "JKSM" 3 | ProductCode : "CTR-HB-JKSV" 4 | Logo : Nintendo 5 | 6 | RomFs: 7 | #RootPath : romfs 8 | 9 | TitleInfo: 10 | Category : Application 11 | UniqueId : 0x2c232 12 | 13 | Option: 14 | UseOnSD : true # true if App is to be installed to SD 15 | FreeProductCode : true # Removes limitations on ProductCode 16 | MediaFootPadding : false # If true CCI files are created with padding 17 | EnableCrypt : false # Enables encryption for NCCH and CIA 18 | EnableCompress : true # Compresses where applicable (currently only exefs:/.code) 19 | 20 | AccessControlInfo: 21 | CoreVersion : 2 22 | 23 | # Exheader Format Version 24 | DescVersion : 2 25 | 26 | # Minimum Required Kernel Version (below is for 4.5.0) 27 | ReleaseKernelMajor : "02" 28 | ReleaseKernelMinor : "33" 29 | 30 | # ExtData 31 | UseExtSaveData : false # enables ExtData 32 | #ExtSaveDataId : 0x300 # only set this when the ID is different to the UniqueId 33 | 34 | # FS:USER Archive Access Permissions 35 | # Uncomment as required 36 | FileSystemAccess: 37 | #- CategorySystemApplication 38 | #- CategoryHardwareCheck 39 | - CategoryFileSystemTool 40 | #- Debug 41 | #- TwlCardBackup 42 | #- TwlNandData 43 | - Boss 44 | - DirectSdmc 45 | #- Core 46 | #- CtrNandRo 47 | - CtrNandRw 48 | #- CtrNandRoWrite 49 | #- CategorySystemSettings 50 | #- CardBoard 51 | #- ExportImportIvs 52 | #- DirectSdmcWrite 53 | #- SwitchCleanup 54 | - SaveDataMove 55 | #- Shop 56 | #- Shell 57 | #- CategoryHomeMenu 58 | IoAccessControl: 59 | #- FsMountNand 60 | #- FsMountNandRoWrite 61 | #- FsMountTwln 62 | #- FsMountWnand 63 | #- FsMountCardSpi 64 | #- UseSdif3 65 | #- CreateSeed 66 | #- UseCardSpi 67 | 68 | # Process Settings 69 | MemoryType : Application # Application/System/Base 70 | SystemMode : 64MB # 64MB(Default)/96MB/80MB/72MB/32MB 71 | IdealProcessor : 0 72 | AffinityMask : 1 73 | Priority : 16 74 | MaxCpu : 0x9E # Default 75 | HandleTableSize : 0x200 76 | DisableDebug : false 77 | EnableForceDebug : false 78 | CanWriteSharedPage : true 79 | CanUsePrivilegedPriority : false 80 | CanUseNonAlphabetAndNumber : true 81 | PermitMainFunctionArgument : true 82 | CanShareDeviceMemory : true 83 | RunnableOnSleep : false 84 | SpecialMemoryArrange : true 85 | 86 | # New3DS Exclusive Process Settings 87 | SystemModeExt : Legacy # Legacy(Default)/124MB/178MB Legacy:Use Old3DS SystemMode 88 | CpuSpeed : 804MHz # 256MHz(Default)/804MHz 89 | EnableL2Cache : true # false(default)/true 90 | CanAccessCore2 : false 91 | 92 | # Virtual Address Mappings 93 | IORegisterMapping: 94 | - 1ff00000-1ff7ffff # DSP memory 95 | MemoryMapping: 96 | - 1f000000-1f5fffff:r # VRAM 97 | 98 | # Accessible SVCs, : 99 | SystemCallAccess: 100 | ArbitrateAddress: 34 101 | Backdoor: 123 102 | Break: 60 103 | CancelTimer: 28 104 | ClearEvent: 25 105 | ClearTimer: 29 106 | CloseHandle: 35 107 | ConnectToPort: 45 108 | ControlMemory: 1 109 | ControlProcessMemory: 112 110 | CreateAddressArbiter: 33 111 | CreateEvent: 23 112 | CreateMemoryBlock: 30 113 | CreateMutex: 19 114 | CreateSemaphore: 21 115 | CreateThread: 8 116 | CreateTimer: 26 117 | DuplicateHandle: 39 118 | ExitProcess: 3 119 | ExitThread: 9 120 | GetCurrentProcessorNumber: 17 121 | GetHandleInfo: 41 122 | GetProcessId: 53 123 | GetProcessIdOfThread: 54 124 | GetProcessIdealProcessor: 6 125 | GetProcessInfo: 43 126 | GetResourceLimit: 56 127 | GetResourceLimitCurrentValues: 58 128 | GetResourceLimitLimitValues: 57 129 | GetSystemInfo: 42 130 | GetSystemTick: 40 131 | GetThreadContext: 59 132 | GetThreadId: 55 133 | GetThreadIdealProcessor: 15 134 | GetThreadInfo: 44 135 | GetThreadPriority: 11 136 | MapMemoryBlock: 31 137 | OutputDebugString: 61 138 | QueryMemory: 2 139 | ReleaseMutex: 20 140 | ReleaseSemaphore: 22 141 | SendSyncRequest1: 46 142 | SendSyncRequest2: 47 143 | SendSyncRequest3: 48 144 | SendSyncRequest4: 49 145 | SendSyncRequest: 50 146 | SetThreadPriority: 12 147 | SetTimer: 27 148 | SignalEvent: 24 149 | SleepThread: 10 150 | UnmapMemoryBlock: 32 151 | WaitSynchronization1: 36 152 | WaitSynchronizationN: 37 153 | 154 | # Service List 155 | # Maximum 34 services (32 if firmware is prior to 9.6.0) 156 | ServiceAccessControl: 157 | - APT:U 158 | - ac:u 159 | - am:net 160 | - boss:U 161 | - cam:u 162 | - cecd:u 163 | - cfg:nor 164 | - cfg:u 165 | - csnd:SND 166 | - dsp::DSP 167 | - frd:u 168 | - fs:USER 169 | - gsp::Gpu 170 | - hid:USER 171 | - http:C 172 | - ir:rst 173 | - ir:u 174 | - ir:USER 175 | - mic:u 176 | - ndm:u 177 | - news:u 178 | - nwm::UDS 179 | - ptm:u 180 | - pxi:dev 181 | - soc:U 182 | - ssl:C 183 | - y2r:u 184 | 185 | 186 | SystemControlInfo: 187 | SaveDataSize: 0KB # Change if the app uses savedata 188 | RemasterVersion: 2 189 | StackSize: 0x40000 190 | 191 | # Modules that run services listed above should be included below 192 | # Maximum 48 dependencies 193 | # : 194 | Dependency: 195 | ac: 0x0004013000002402 196 | #act: 0x0004013000003802 197 | am: 0x0004013000001502 198 | boss: 0x0004013000003402 199 | camera: 0x0004013000001602 200 | cecd: 0x0004013000002602 201 | cfg: 0x0004013000001702 202 | codec: 0x0004013000001802 203 | csnd: 0x0004013000002702 204 | dlp: 0x0004013000002802 205 | dsp: 0x0004013000001a02 206 | friends: 0x0004013000003202 207 | gpio: 0x0004013000001b02 208 | gsp: 0x0004013000001c02 209 | hid: 0x0004013000001d02 210 | http: 0x0004013000002902 211 | i2c: 0x0004013000001e02 212 | ir: 0x0004013000003302 213 | mcu: 0x0004013000001f02 214 | mic: 0x0004013000002002 215 | ndm: 0x0004013000002b02 216 | news: 0x0004013000003502 217 | #nfc: 0x0004013000004002 218 | nim: 0x0004013000002c02 219 | nwm: 0x0004013000002d02 220 | pdn: 0x0004013000002102 221 | ps: 0x0004013000003102 222 | ptm: 0x0004013000002202 223 | #qtm: 0x0004013020004202 224 | ro: 0x0004013000003702 225 | socket: 0x0004013000002e02 226 | spi: 0x0004013000002302 227 | ssl: 0x0004013000002f02 228 | -------------------------------------------------------------------------------- /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 | # APP_TITLE is the name of the app stored in the SMDH file (Optional) 21 | # APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional) 22 | # APP_AUTHOR is the author of the app stored in the SMDH file (Optional) 23 | # ICON is the filename of the icon (.png), relative to the project folder. 24 | # If not set, it attempts to use one of the following (in this order): 25 | # - .png 26 | # - icon.png 27 | # - /default_icon.png 28 | #--------------------------------------------------------------------------------- 29 | TARGET := JKSM 30 | BUILD := build 31 | SOURCES := source 32 | DATA := data 33 | INCLUDES := include 34 | ROMFS := romfs 35 | 36 | APP_TITLE := JK's Save Manager 37 | APP_DESCRIPTION := Save Manager 38 | APP_AUTHOR := JK 39 | 40 | #--------------------------------------------------------------------------------- 41 | # options for code generation 42 | #--------------------------------------------------------------------------------- 43 | ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard 44 | 45 | CFLAGS := -g -Wall -O2 -mword-relocations \ 46 | -fomit-frame-pointer -ffast-math \ 47 | $(ARCH) 48 | 49 | CFLAGS += $(INCLUDE) -DARM11 -D_3DS 50 | 51 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=c++11 52 | 53 | ASFLAGS := -g $(ARCH) 54 | LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 55 | 56 | LIBS := -lsf2d -lpng -lsftd -lfreetype -lcitro3d -lctru -lm -lz 57 | 58 | #--------------------------------------------------------------------------------- 59 | # list of directories containing libraries, this must be the top level containing 60 | # include and lib 61 | #--------------------------------------------------------------------------------- 62 | LIBDIRS := $(CTRULIB) $(PORTLIBS) 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,$(IMGS),$(CURDIR)/$(dir)) \ 77 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 78 | 79 | export DEPSDIR := $(CURDIR)/$(BUILD) 80 | 81 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 82 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 83 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 84 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 85 | 86 | #--------------------------------------------------------------------------------- 87 | # use CXX for linking C++ projects, CC for standard C 88 | #--------------------------------------------------------------------------------- 89 | ifeq ($(strip $(CPPFILES)),) 90 | #--------------------------------------------------------------------------------- 91 | export LD := $(CC) 92 | #--------------------------------------------------------------------------------- 93 | else 94 | #--------------------------------------------------------------------------------- 95 | export LD := $(CXX) 96 | #--------------------------------------------------------------------------------- 97 | endif 98 | #--------------------------------------------------------------------------------- 99 | 100 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 101 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(IMGFILES:.c=.o) $(SFILES:.s=.o) 102 | 103 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 104 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 105 | -I$(CURDIR)/$(BUILD) 106 | 107 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 108 | 109 | ifeq ($(strip $(ICON)),) 110 | icons := $(wildcard *.png) 111 | ifneq (,$(findstring $(TARGET).png,$(icons))) 112 | export APP_ICON := $(TOPDIR)/$(TARGET).png 113 | else 114 | ifneq (,$(findstring icon.png,$(icons))) 115 | export APP_ICON := $(TOPDIR)/icon.png 116 | endif 117 | endif 118 | else 119 | export APP_ICON := $(TOPDIR)/$(ICON) 120 | endif 121 | 122 | ifeq ($(strip $(NO_SMDH)),) 123 | export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh 124 | endif 125 | 126 | ifneq ($(ROMFS),) 127 | export _3DSXFLAGS += --romfs=$(CURDIR)/$(ROMFS) 128 | endif 129 | 130 | .PHONY: $(BUILD) clean all 131 | 132 | #--------------------------------------------------------------------------------- 133 | all: $(BUILD) cia 134 | 135 | $(BUILD): 136 | @[ -d $@ ] || mkdir -p $@ 137 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 138 | 139 | #--------------------------------------------------------------------------------- 140 | clean: 141 | @echo clean ... 142 | @rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf $(TARGET)-strip.elf $(TARGET).cia $(TARGET).3ds 143 | #--------------------------------------------------------------------------------- 144 | $(TARGET)-strip.elf: $(BUILD) 145 | @$(STRIP) $(TARGET).elf -o $(TARGET)-strip.elf 146 | #--------------------------------------------------------------------------------- 147 | cci: $(TARGET)-strip.elf 148 | @makerom -f cci -rsf $(TARGET).rsf -target d -exefslogo -elf $(TARGET)-strip.elf -o $(TARGET).3ds 149 | #--------------------------------------------------------------------------------- 150 | cia: $(TARGET)-strip.elf 151 | @makerom -f cia -o $(TARGET).cia -elf $(TARGET)-strip.elf -rsf $(TARGET).rsf -exefslogo -target t -icon icon -banner banner 152 | @echo Built JKSM.cia 153 | #--------------------------------------------------------------------------------- 154 | send: $(BUILD) 155 | @3dslink $(TARGET).3dsx 156 | #--------------------------------------------------------------------------------- 157 | run: $(BUILD) 158 | @citra $(TARGET).3dsx 159 | 160 | #--------------------------------------------------------------------------------- 161 | else 162 | 163 | DEPENDS := $(OFILES:.o=.d) 164 | 165 | #--------------------------------------------------------------------------------- 166 | # main targets 167 | #--------------------------------------------------------------------------------- 168 | ifeq ($(strip $(NO_SMDH)),) 169 | $(OUTPUT).3dsx : $(OUTPUT).elf $(OUTPUT).smdh 170 | else 171 | $(OUTPUT).3dsx : $(OUTPUT).elf 172 | endif 173 | 174 | $(OUTPUT).elf : $(OFILES) 175 | 176 | #--------------------------------------------------------------------------------- 177 | # you need a rule like this for each extension you use as binary data 178 | #--------------------------------------------------------------------------------- 179 | %.bin.o : %.bin 180 | #--------------------------------------------------------------------------------- 181 | @echo $(notdir $<) 182 | @$(bin2o) 183 | 184 | #--------------------------------------------------------------------------------- 185 | %.ttf.o : %.ttf 186 | #--------------------------------------------------------------------------------- 187 | @echo $(notdir $<) 188 | @$(bin2o) 189 | 190 | # WARNING: This is not the right way to do this! TODO: Do it right! 191 | #--------------------------------------------------------------------------------- 192 | %.vsh.o : %.vsh 193 | #--------------------------------------------------------------------------------- 194 | @echo $(notdir $<) 195 | @python $(AEMSTRO)/aemstro_as.py $< ../$(notdir $<).shbin 196 | @bin2s ../$(notdir $<).shbin | $(PREFIX)as -o $@ 197 | @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h 198 | @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h 199 | @echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h 200 | @rm ../$(notdir $<).shbin 201 | 202 | -include $(DEPENDS) 203 | 204 | #--------------------------------------------------------------------------------------- 205 | endif 206 | #--------------------------------------------------------------------------------------- 207 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JKSM Rosalina 2 | This is a fork from: 3 | JKSM - JK's Save Manager 4 | --- 5 | This version's 3DSX is only compatible with the Rosalina entrypoint of the Homebrew Launcher. 6 | For the old *hax 3dsx please visit the original fork by JK. 7 | --- 8 | WARNING: This fork moves the JKSV folder from the root of the sdcard to the "3ds/data/JKSM" folder. You must move your saves there before you are able to restore it. -------------------------------------------------------------------------------- /banner: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phalk/JKSM/83267863779872b6a148bab30a3cae7ae462be54/banner -------------------------------------------------------------------------------- /data/font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phalk/JKSM/83267863779872b6a148bab30a3cae7ae462be54/data/font.ttf -------------------------------------------------------------------------------- /filter.txt: -------------------------------------------------------------------------------- 1 | 0x00000B00 2 | 0x00000C00 3 | 0x00026E00 4 | 0x00103000 5 | 0x00103500 6 | 0x00104300 7 | 0x00110100 8 | 0x00124200 9 | 0x00130800 10 | 0x00130900 11 | 0x00133700 12 | 0x00187800 13 | 0x00187900 14 | 0x00195400 15 | 0x00199700 16 | 0x001A1E00 17 | 0x001DDB00 18 | 0x001DEA00 19 | 0x00210100 20 | 0x00269500 21 | 0x00287000 22 | 0x00287100 23 | 0x00384900 24 | 0x00410200 25 | 0x00505600 26 | 0x00555500 27 | 0x00557700 28 | 0x005BF300 29 | 0x005DCA00 30 | 0x00610100 31 | 0x00686200 32 | 0x00686300 33 | 0x00710200 34 | 0x00771800 35 | 0x00800800 36 | 0x00810100 37 | 0x00840700 38 | 0x00910100 39 | 0x00997100 40 | 0x00997200 41 | 0x00997300 42 | 0x00997500 43 | 0x00997600 44 | 0x00997700 45 | 0x00997800 46 | 0x00997900 47 | 0x00997A00 48 | 0x00997B00 49 | 0x00998100 50 | 0x00998E00 51 | 0x00998F00 52 | 0x00999800 53 | 0x0099AA00 54 | 0x0099AB00 55 | 0x00A51500 56 | 0x00A54000 57 | 0x00A54100 58 | 0x00A54200 59 | 0x00A54300 60 | 0x00A54400 61 | 0x00A54500 62 | 0x00A54600 63 | 0x00A61700 64 | 0x00A73A00 65 | 0x00A8BF00 66 | 0x00B00000 67 | 0x00B00200 68 | 0x00B2B400 69 | 0x00C1BA00 70 | 0x00D39A00 71 | 0x00D40400 72 | 0x00D81D00 73 | 0x00E82A00 74 | 0x00EA5100 75 | 0x00F69F00 76 | 0x00F73D00 77 | 0x00F8AD00 78 | 0x00FA6500 79 | 0x00FAB100 80 | 0x00FE1100 81 | 0x00FEBA00 82 | 0x01105600 83 | 0x01198300 84 | 0x01600000 85 | 0x01610000 86 | 0x01D40400 87 | 0x01D47100 88 | 0x01F50400 89 | 0x02C23200 90 | 0x02C23300 91 | 0x03070C00 92 | 0x03C51100 93 | 0x03D17000 94 | 0x03DAA300 95 | 0x047C4200 96 | 0x050BAD00 97 | 0x060AA100 98 | 0x06D11900 99 | 0x06FFFF00 100 | 0x07F00000 101 | 0x08470100 102 | 0x08470200 103 | 0x09034200 104 | 0x096E7E00 105 | 0x096E7F00 106 | 0x09889900 107 | 0x0A0CA100 108 | 0x0A1B2C00 109 | 0x0A51E100 110 | 0x0A51E800 111 | 0x0A55C100 112 | 0x0A7FC800 113 | 0x0AB1BA00 114 | 0x0ADAD000 115 | 0x0B05AD00 116 | 0x0B0B1B00 117 | 0x0B198200 118 | 0x0B198900 119 | 0x0B735600 120 | 0x0BAC0000 121 | 0x0BAC0100 122 | 0x0BAC0200 123 | 0x0BAC0300 124 | 0x0BAC0400 125 | 0x0BAC0500 126 | 0x0BAC0600 127 | 0x0BAC0700 128 | 0x0BAC0800 129 | 0x0BAC0900 130 | 0x0BAC0A00 131 | 0x0BAC0B00 132 | 0x0BAC0C00 133 | 0x0BAC0D00 134 | 0x0BAC0E00 135 | 0x0BAC0F00 136 | 0x0BAC1000 137 | 0x0BAC1100 138 | 0x0BAC1200 139 | 0x0BAC1300 140 | 0x0BAC1400 141 | 0x0BAC1500 142 | 0x0BAC1600 143 | 0x0BAC1700 144 | 0x0BAC1800 145 | 0x0BAC1900 146 | 0x0BAC1A00 147 | 0x0BAC1B00 148 | 0x0BEEF500 149 | 0x0C2C0000 150 | 0x0C7EE000 151 | 0x0CCE2E00 152 | 0x0CE1CC00 153 | 0x0D5C4900 154 | 0x0D921E00 155 | 0x0DA00200 156 | 0x0DA7A500 157 | 0x0DEAD100 158 | 0x0DEAD200 159 | 0x0DED6600 160 | 0x0E7A5A00 161 | 0x0EB00000 162 | 0x0EB00100 163 | 0x0EC10000 164 | 0x0EC20000 165 | 0x0EC30000 166 | 0x0ED99000 167 | 0x0EFFEC00 168 | 0x0EFFED00 169 | 0x0F000700 170 | 0x0F002000 171 | 0x0F002100 172 | 0x0F002300 173 | 0x0F002400 174 | 0x0F002900 175 | 0x0F003100 176 | 0x0F003200 177 | 0x0F008900 178 | 0x0F010900 179 | 0x0F04ED00 180 | 0x0F0ACC00 181 | 0x0F0BAD00 182 | 0x0F0DEF00 183 | 0x0F0FC200 184 | 0x0F102000 185 | 0x0F12EE00 186 | 0x0F191900 187 | 0x0F19F000 188 | 0x0F1A6600 189 | 0x0F1BAD00 190 | 0x0F3D5C00 191 | 0x0F3D9900 192 | 0x0F5ACD00 193 | 0x0F64ED00 194 | 0x0F718300 195 | 0x0F800100 196 | 0x0F800200 197 | 0x0F800300 198 | 0x0F880300 199 | 0x0F907A00 200 | 0x0F917300 201 | 0x0FAFA900 202 | 0x0FE7CB00 203 | 0x0FF05000 204 | 0x0FF05100 205 | 0x0FF05300 206 | 0x0FF07F00 207 | 0x0FF12300 208 | 0x0FF12400 209 | 0x0FF32100 210 | 0x0FF33300 211 | 0x0FF3CC00 212 | 0x0FF3FF00 213 | 0x0FF40D00 214 | 0x0FF4FF00 215 | 0x0FFADD00 216 | 0x0FFCFC00 217 | 0x0FFEE000 218 | 0xA2F43B00 219 | 0x0FF40002 220 | 0x0FF40102 221 | 0x0FF40402 222 | 0x0FF40702 223 | 0x0FF40A02 224 | 0x0FF40B02 225 | 0x0FF41602 226 | 0x0F800902 227 | 0x0FF40E00 228 | 0x0FF40600 229 | 0x07FFFA00 230 | 0x0FF41800 231 | 0x0FE04000 232 | 0x0FE00C00 233 | 0x0FF40D00 234 | 0x0FF30300 235 | 0x0FF41B00 236 | 0x0FF41F00 237 | 0x0F807F00 238 | 0x0FF41E00 239 | 0x0FF42000 240 | 0x0FF3FF00 241 | 0x00000300 242 | 0x0FF40000 243 | 0x0FF40A00 -------------------------------------------------------------------------------- /icon: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phalk/JKSM/83267863779872b6a148bab30a3cae7ae462be54/icon -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phalk/JKSM/83267863779872b6a148bab30a3cae7ae462be54/icon.png -------------------------------------------------------------------------------- /include/3dsx.h: -------------------------------------------------------------------------------- 1 | #ifndef _DSX_H 2 | #define _DSX_H 3 | 4 | void start3dsxMode(); 5 | 6 | #endif // 3DSX_H 7 | -------------------------------------------------------------------------------- /include/archive.h: -------------------------------------------------------------------------------- 1 | #ifndef ARCHIVE_H 2 | #define ARCHIVE_H 3 | 4 | #include "titledata.h" 5 | 6 | /* 7 | These open the 3DS's archives 8 | return true or false 9 | out is the archive opened if it didn't fail 10 | showError is whether or not to show the popup if it fails 11 | */ 12 | bool openSaveArch(FS_Archive *out, const titleData dat, bool show); 13 | bool openSaveArch3dsx(FS_Archive *out); 14 | bool openExtdata(FS_Archive *out, const titleData dat, bool show); 15 | bool openSharedExt(FS_Archive *out, u32 id); 16 | bool openSysSave(FS_Archive *out, const titleData dat); 17 | bool openBossExt(FS_Archive *out, const titleData dat); 18 | 19 | #endif // ARCHIVE_H 20 | -------------------------------------------------------------------------------- /include/backup.h: -------------------------------------------------------------------------------- 1 | #ifndef BACKUP_H 2 | #define BACKUP_H 3 | 4 | #include "titledata.h" 5 | #include "menu.h" 6 | 7 | /* 8 | dat = titeData containing info for title 9 | arch = opened FS_Archive 10 | mode = where to export data to 11 | auto = whether or not to just grab date or get user input 12 | */ 13 | bool backupData(const titleData dat, FS_Archive arch, int mode, bool autoName); 14 | void autoBackup(menu m); 15 | #endif // BACKUP_H 16 | -------------------------------------------------------------------------------- /include/backupmenu.h: -------------------------------------------------------------------------------- 1 | #ifndef BACKUPMENU_H 2 | #define BACKUPMENU_H 3 | 4 | void backupMenu(); 5 | void sysBackupMenu(); 6 | 7 | #endif // BACKUPMENU_H 8 | -------------------------------------------------------------------------------- /include/date.h: -------------------------------------------------------------------------------- 1 | #ifndef DATE_H 2 | #define DATE_H 3 | 4 | #define FORMAT_YDM 0 5 | #define FORMAT_YMD 1 6 | 7 | #include 8 | 9 | char *GetDate(int Format); 10 | std::string RetTime(); 11 | 12 | #endif // DATE_H 13 | -------------------------------------------------------------------------------- /include/db.h: -------------------------------------------------------------------------------- 1 | #ifndef DB_H 2 | #define DB_H 3 | 4 | #include 5 | #include "titledata.h" 6 | 7 | FILE *dbCreate(const char *path); 8 | FILE *dbOpen(const char *path); 9 | 10 | void dbWriteCount(FILE *db, u32 count, u8 rev); 11 | u32 dbGetCount(FILE *db); 12 | u8 dbGetRev(FILE *db); 13 | 14 | void dbWriteData(FILE *db, const titleData w); 15 | titleData dbGetData(FILE *db); 16 | 17 | #endif // DB_G 18 | -------------------------------------------------------------------------------- /include/dev.h: -------------------------------------------------------------------------------- 1 | #ifndef DEV_H 2 | #define DEV_H 3 | 4 | void showDevMenu(); 5 | 6 | #endif // DEV_H 7 | -------------------------------------------------------------------------------- /include/extmenu.h: -------------------------------------------------------------------------------- 1 | #ifndef EXTMENU_H 2 | #define EXTMENU_H 3 | 4 | #include <3ds.h> 5 | 6 | void showExtMenu(); 7 | 8 | #endif // EXTMENU_H 9 | -------------------------------------------------------------------------------- /include/extra.h: -------------------------------------------------------------------------------- 1 | #ifndef EXTRA_H 2 | #define EXTRA_H 3 | 4 | void extrasMenu(); 5 | 6 | #endif // EXTRA_H 7 | -------------------------------------------------------------------------------- /include/file.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE_H 2 | #define FILE_H 3 | 4 | #include <3ds.h> 5 | #include 6 | #include 7 | 8 | #define seek_beg 0 9 | #define seek_cur 1 10 | #define seek_end 2 11 | 12 | class fsFile 13 | { 14 | public: 15 | //One is for reading, the other is for writing 16 | fsFile(FS_Archive _arch, std::u16string _path, u32 openFlags); 17 | fsFile(FS_Archive _arch, std::u16string _path, u32 openFlags, u64 createSize); 18 | //Ascii 19 | fsFile(FS_Archive _arch, const char *_path, u32 openFlags); 20 | fsFile(FS_Archive _arch, const char *_path, u32 openFlags, u64 createSize); 21 | //Directly 22 | fsFile(FS_ArchiveID _arch, FS_Path archPath, FS_Path filePath, u32 openFlags); 23 | //Bin 24 | fsFile(FS_Archive _arch, FS_Path _path, u32 openFlags); 25 | 26 | //returns if file is opened 27 | bool isOpened(); 28 | bool eof(); 29 | 30 | //Reads to buff. Returns number of read bytes 31 | Result read(void *buff, u32 *readOut, u32 max); 32 | //Same, only write 33 | Result write(void *dat, u32 *written, u32 size); 34 | //gets next byte in file 35 | u8 getByte(); 36 | //writes byte at offset 37 | void putByte(u8 put); 38 | 39 | void seek(int pos, u8 seekFrom); 40 | 41 | //Closes file 42 | bool close(); 43 | 44 | //returns fileSize 45 | u64 size(); 46 | u64 getOffset(); 47 | 48 | unsigned int getError(); 49 | 50 | private: 51 | Handle fileHandle; 52 | bool opened = false; 53 | FS_Archive arch; 54 | u64 fileSize = 0, offset = 0; 55 | unsigned int error; 56 | }; 57 | 58 | class dirList 59 | { 60 | public: 61 | dirList(FS_Archive arch, const std::u16string p); 62 | ~dirList(); 63 | void reassign(const std::u16string p); 64 | 65 | unsigned count(); 66 | 67 | bool isDir(int i); 68 | std::u16string retItem(int i); 69 | 70 | private: 71 | Handle d; 72 | FS_Archive a; 73 | std::u16string path; 74 | std::vector entry; 75 | }; 76 | 77 | #endif // FILE_H 78 | -------------------------------------------------------------------------------- /include/global.h: -------------------------------------------------------------------------------- 1 | #ifndef GLOBAL_H 2 | #define GLOBAL_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "titledata.h" 10 | 11 | //this is for backup/restore modes 12 | #define MODE_SAVE 0 13 | #define MODE_EXTDATA 1 14 | #define MODE_SYSSAVE 2 15 | #define MODE_BOSS 3 16 | #define MODE_SHARED 4 17 | 18 | #define BUILD_DATE std::u32string(U"2-10-2017") 19 | 20 | extern int state, prevState; 21 | extern u8 sysLanguage; 22 | extern titleData *curTitle; 23 | 24 | enum states 25 | { 26 | STATE_MAINMENU, 27 | STATE_TITLEMENU, 28 | STATE_BACKUPMENU, 29 | STATE_SAVEMENU, 30 | STATE_EXTMENU, 31 | STATE_NANDSELECT, 32 | STATE_NANDBACKUP, 33 | STATE_EXTRAS, 34 | STATE_SHARED, 35 | STATE_SHAREDBACKUP, 36 | STATE_DEVMENU 37 | }; 38 | 39 | void handleState(); 40 | 41 | //buffer size 42 | extern const unsigned buff_size; 43 | 44 | //This is the font used to print everything 45 | extern sftd_font *font; 46 | 47 | //SDMC Archive. Seems to write faster using this. Might just be me though 48 | extern FS_Archive sdArch; 49 | 50 | extern bool devMode, hbl, kill; 51 | //config 52 | extern bool centered, autoBack, useLang; 53 | 54 | //Allows app to be killed by hitting start 55 | void killApp(u32 up); 56 | 57 | //got tired of black, gray, and green all the time 58 | extern u8 clearColor[3]; 59 | extern u8 selColor[3]; 60 | extern u8 unSelColor[3]; 61 | 62 | void mainMenu(); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /include/gstr.h: -------------------------------------------------------------------------------- 1 | #ifndef GSTR_H 2 | #define GSTR_H 3 | 4 | #include 5 | 6 | std::string GetString(const char *hint); 7 | int getInt(const char *hint, int init, int maxValue); 8 | 9 | #endif // GSTR_H 10 | -------------------------------------------------------------------------------- /include/hbfilter.h: -------------------------------------------------------------------------------- 1 | #ifndef HBFILTER_H 2 | #define HBFILTER_H 3 | 4 | //filters homebrew titles. 5 | bool hbFilter(u64 id); 6 | void loadFilterList(); 7 | 8 | #endif // HBFILTER_H 9 | -------------------------------------------------------------------------------- /include/img.h: -------------------------------------------------------------------------------- 1 | #ifndef IMG_H 2 | #define IMG_H 3 | 4 | extern "C" 5 | { 6 | extern unsigned char topbarData[]; 7 | extern unsigned char progBarData[]; 8 | extern unsigned char textboxData[]; 9 | } 10 | 11 | #endif // IMG_H 12 | -------------------------------------------------------------------------------- /include/menu.h: -------------------------------------------------------------------------------- 1 | #ifndef MENU_H 2 | #define MENU_H 3 | 4 | #include 5 | #include 6 | 7 | class menuItem 8 | { 9 | public: 10 | menuItem(const std::u32string s, bool center, int x); 11 | void autoCenter(); 12 | void draw(int y, unsigned color); 13 | 14 | bool selected; 15 | std::u32string text; 16 | 17 | int x; 18 | }; 19 | 20 | class menu 21 | { 22 | public: 23 | menu(unsigned sx, unsigned sy, bool sMulti, bool _center); 24 | ~menu(); 25 | 26 | void addItem(const char *a); 27 | void addItem(const std::u16string a); 28 | void addItem(const std::u32string a); 29 | 30 | void updateItem(int i, const char *a); 31 | 32 | int getSelected(); 33 | void setSelected(int sel); 34 | void reset(); 35 | 36 | void centerOpts(); 37 | void autoVert(); 38 | 39 | unsigned getSize(); 40 | unsigned getSelectCount(); 41 | bool optSelected(int i); 42 | 43 | void draw(); 44 | 45 | void handleInput(u32 key, u32 held); 46 | 47 | private: 48 | bool multi, center; 49 | std::vector opts; 50 | int x, y, selected, start, fc; 51 | }; 52 | 53 | void prepMain(), prepBackMenu(), prepSaveMenu(); 54 | void prepExtMenu(), prepNandBackup(), prepSharedMenu(); 55 | void prepSharedBackMenu(), prepExtras(), prepDevMenu(); 56 | 57 | #endif // MENU_H 58 | -------------------------------------------------------------------------------- /include/nand.h: -------------------------------------------------------------------------------- 1 | #ifndef NAND_H 2 | #define NAND_H 3 | 4 | void nandStartSelect(); 5 | void nandBackup(); 6 | 7 | #endif // NAND_H 8 | -------------------------------------------------------------------------------- /include/restore.h: -------------------------------------------------------------------------------- 1 | #ifndef RESTORE_H 2 | #define RESTORE_H 3 | 4 | #include "titledata.h" 5 | #include "menu.h" 6 | 7 | bool restoreData(const titleData dat, FS_Archive arch, int mode); 8 | bool restoreDataSDPath(const titleData dat, FS_Archive arch, int mode); 9 | void autoRestore(menu m); 10 | 11 | #endif // RESTORE_H 12 | -------------------------------------------------------------------------------- /include/savemenu.h: -------------------------------------------------------------------------------- 1 | #ifndef SAVEMENU_H 2 | #define SAVEMENU_H 3 | 4 | #include <3ds.h> 5 | #include "titledata.h" 6 | 7 | void showSaveMenu(); 8 | 9 | #endif // SAVEMENU_H 10 | -------------------------------------------------------------------------------- /include/sd_cia.h: -------------------------------------------------------------------------------- 1 | #ifndef SD_CIA_H 2 | #define SD_CIA_H 3 | 4 | void sdStartSelect(); 5 | 6 | #endif // SD_CIA_H 7 | -------------------------------------------------------------------------------- /include/sdpath.h: -------------------------------------------------------------------------------- 1 | #ifndef SDPATH_H 2 | #define SDPATH_H 3 | 4 | #include 5 | 6 | std::u16string getSDPath(); 7 | 8 | #endif // SD_H 9 | -------------------------------------------------------------------------------- /include/shared.h: -------------------------------------------------------------------------------- 1 | #ifndef SHARED_H 2 | #define SHARED_H 3 | 4 | void sharedExtManager(); 5 | void sharedBackupMenu(); 6 | 7 | #endif // SHARED_H 8 | -------------------------------------------------------------------------------- /include/slot.h: -------------------------------------------------------------------------------- 1 | #ifndef SLOT_H 2 | #define SLOT_H 3 | 4 | #include 5 | #include "titledata.h" 6 | 7 | //nSlot = whether to allow new dir creation 8 | //Data = TitleData object containing info 9 | //Ext = Using ExtData 10 | std::u16string getFolder(const titleData dat, int mode, bool newFolder); 11 | 12 | #endif // SLOT_H 13 | -------------------------------------------------------------------------------- /include/smdh.h: -------------------------------------------------------------------------------- 1 | #ifndef SMDH_H 2 | #define SMDH_H 3 | 4 | #include <3ds.h> 5 | 6 | typedef struct 7 | { 8 | u32 magic; 9 | u16 version; 10 | u16 reserved; 11 | } smdhHeader_s; 12 | 13 | typedef struct 14 | { 15 | u16 shortDescription[0x40]; 16 | u16 longDescription[0x80]; 17 | u16 publisher[0x40]; 18 | } smdhTitle_s; 19 | 20 | typedef struct 21 | { 22 | u8 gameRatings[0x10]; 23 | u32 regionLock; 24 | u8 matchMakerId[0xC]; 25 | u32 flags; 26 | u16 eulaVersion; 27 | u16 reserved; 28 | u32 defaultFrame; 29 | u32 cecId; 30 | } smdhSettings_s; 31 | 32 | typedef struct 33 | { 34 | smdhHeader_s header; 35 | smdhTitle_s applicationTitles[16]; 36 | smdhSettings_s settings; 37 | u8 reserved[0x8]; 38 | u8 smallIconData[0x480]; 39 | u16 bigIconData[0x900]; 40 | } smdh_s; 41 | 42 | smdh_s *loadSMDH(u32 Low, u32 High, u8 Media); 43 | char16_t *loadTitle(u32 low, u32 high, FS_MediaType media); 44 | #endif // SMDH_H 45 | -------------------------------------------------------------------------------- /include/sys.h: -------------------------------------------------------------------------------- 1 | #ifndef SYS_H 2 | #define SYS_H 3 | 4 | void sysInit(); 5 | void sysExit(); 6 | 7 | #endif // SYS_H 8 | -------------------------------------------------------------------------------- /include/titledata.h: -------------------------------------------------------------------------------- 1 | #ifndef TITLEDATA_H 2 | #define TITLEDATA_H 3 | 4 | #include <3ds.h> 5 | #include 6 | #include 7 | #include "smdh.h" 8 | 9 | class titleData 10 | { 11 | public: 12 | bool init(u64 _id, FS_MediaType mediaType); 13 | void initId(); 14 | 15 | void printInfo(); 16 | 17 | u64 id; 18 | u32 high, low, unique, extdata; 19 | std::string prodCode; 20 | std::u16string name, nameSafe; 21 | std::u32string u32Name; 22 | FS_MediaType media; 23 | bool initd = false; 24 | }; 25 | 26 | #endif // TITLEDATA_H 27 | -------------------------------------------------------------------------------- /include/titles.h: -------------------------------------------------------------------------------- 1 | #ifndef TITLES_H 2 | #define TITLES_H 3 | 4 | #include 5 | #include "titledata.h" 6 | 7 | void sdTitlesInit(); 8 | void nandTitlesInit(); 9 | 10 | extern std::vector sdTitle; 11 | extern std::vector nandTitle; 12 | 13 | #endif // TITLES_H 14 | -------------------------------------------------------------------------------- /include/ui.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_H 2 | #define UI_H 3 | 4 | #include <3ds.h> 5 | #include 6 | 7 | bool confirm(const char *t); 8 | void showMessage(const char *t, const char *head); 9 | void showError(const char *t, unsigned error); 10 | 11 | class textbox 12 | { 13 | public: 14 | textbox(unsigned x, unsigned y, unsigned width, unsigned height, const char *text, const char *_head); 15 | void changeText(const char *nText); 16 | void draw(); 17 | 18 | unsigned X, Y; 19 | protected: 20 | unsigned Width, Height; 21 | unsigned headX; 22 | float xScale = 0, yScale = 0; 23 | std::string Text, head; 24 | }; 25 | 26 | class progressBar 27 | { 28 | public: 29 | progressBar(float _max, const char *t, const char *head); 30 | ~progressBar(); 31 | void draw(float cur); 32 | 33 | private: 34 | textbox *back; 35 | float max; 36 | }; 37 | 38 | class button 39 | { 40 | public: 41 | button(const char *sText, int sX, int sY, int sWidth, int sHeight); 42 | void draw(); 43 | bool isOver(touchPosition p); 44 | bool released(touchPosition p); 45 | 46 | private: 47 | bool Pressed; 48 | int X, Y, width, height; 49 | int textX, textY; 50 | std::string text; 51 | touchPosition Prev; 52 | }; 53 | 54 | void textboxInit(); 55 | void textboxExit(); 56 | void progressBarInit(); 57 | void progressBarExit(); 58 | void topBarInit(); 59 | void topBarExit(); 60 | void drawTopBar(const std::u32string nfo); 61 | 62 | #endif // UI_H 63 | -------------------------------------------------------------------------------- /include/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | #include 5 | #include 6 | 7 | #include "titledata.h" 8 | 9 | //return converted strings using ctrulib's utfX_to_utfX 10 | std::u32string tou32(const std::u16string t); 11 | std::u16string tou16(const char *t); 12 | std::string toString(const std::u16string t); 13 | 14 | //Returns the " : XXXX Data" 15 | std::u32string modeText(int mode); 16 | 17 | //Returns utf16 string with forbidden chars removed 18 | std::u16string safeString(const std::u16string s); 19 | std::u16string safeStringOld(const std::u16string s); 20 | 21 | //Writes the error given over the buffer for broken data 22 | void writeErrorToBuff(u8 *buff, size_t bSize, unsigned error); 23 | 24 | //Creates the directory for data 25 | void createTitleDir(const titleData t, int mode); 26 | void renameDir(const titleData t); 27 | 28 | //Deletes secure value 29 | bool deleteSV(const titleData t); 30 | 31 | //Returns path to folders to make it easier to change if needed 32 | std::u16string getPath(int mode); 33 | 34 | //Guess what these do. 35 | void deleteExtdata(const titleData dat); 36 | void createExtData(const titleData dat); 37 | 38 | //returns if dealing with extdata 39 | bool modeExtdata(int mode); 40 | 41 | //Makes a string odd if it's even. 42 | void evenString(std::string *test); 43 | 44 | //This detects if running under something as 3dsx 45 | bool runningUnder(); 46 | 47 | //returns if touchscreen is still being pressed anywhere 48 | bool touchPressed(touchPosition p); 49 | 50 | bool fexists(const char *path); 51 | 52 | //Starts and ends fs sessions for HBL mode 53 | void fsStart(); 54 | void fsEnd(); 55 | void fsCommitData(FS_Archive arch); 56 | Result FS_GetMediaType(FS_MediaType *m); 57 | 58 | //Sets up menus 59 | void prepareMenus(); 60 | 61 | sf2d_texture *createTexMem(struct img); 62 | #endif // UTIL_H 63 | -------------------------------------------------------------------------------- /source/3dsx.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "archive.h" 8 | #include "backup.h" 9 | #include "menu.h" 10 | #include "restore.h" 11 | #include "titledata.h" 12 | #include "global.h" 13 | #include "util.h" 14 | #include "ui.h" 15 | #include "extra.h" 16 | 17 | enum hblOpts 18 | { 19 | expSav, 20 | impSav, 21 | delSV, 22 | expExt, 23 | impExt, 24 | extra, 25 | exitapp 26 | }; 27 | 28 | void start3dsxMode() 29 | { 30 | u64 id; 31 | APT_GetProgramID(&id); 32 | 33 | fsStart(); 34 | FS_MediaType getMedia; 35 | FSUSER_GetMediaType(&getMedia); 36 | fsEnd(); 37 | 38 | //This doesn't work if you start the FS session. 39 | titleData data; 40 | data.init(id, getMedia); 41 | 42 | renameDir(data); 43 | 44 | menu hblMenu(0, 80, false, true); 45 | hblMenu.addItem("Export Save"); 46 | hblMenu.addItem("Import Save"); 47 | hblMenu.addItem("Delete Secure Value"); 48 | hblMenu.addItem("Export ExtData"); 49 | hblMenu.addItem("Import ExtData"); 50 | hblMenu.addItem("Extras/Config"); 51 | hblMenu.addItem("Exit"); 52 | 53 | std::u32string info = data.u32Name + U" : 3DSX Mode - " + BUILD_DATE; 54 | 55 | fsStart(); 56 | 57 | while(aptMainLoop() && !kill) 58 | { 59 | hidScanInput(); 60 | 61 | u32 down = hidKeysDown(); 62 | 63 | touchPosition p; 64 | hidTouchRead(&p); 65 | 66 | hblMenu.handleInput(down, 0); 67 | 68 | if(down & KEY_A) 69 | { 70 | FS_Archive arch; 71 | switch(hblMenu.getSelected()) 72 | { 73 | case hblOpts::expSav: 74 | if(openSaveArch3dsx(&arch)) 75 | { 76 | createTitleDir(data, MODE_SAVE); 77 | backupData(data, arch, MODE_SAVE, false); 78 | } 79 | break; 80 | case hblOpts::impSav: 81 | if(openSaveArch3dsx(&arch)) 82 | restoreData(data, arch, MODE_SAVE); 83 | break; 84 | case hblOpts::delSV: 85 | fsEnd(); 86 | if(deleteSV(data)) 87 | showMessage("Secure value successfully deleted!", "Success!"); 88 | fsStart(); 89 | break; 90 | case hblOpts::expExt: 91 | if(openExtdata(&arch, data, true)) 92 | { 93 | createTitleDir(data, MODE_EXTDATA); 94 | backupData(data, arch, MODE_EXTDATA, false); 95 | } 96 | break; 97 | case hblOpts::impExt: 98 | if(openExtdata(&arch, data, false)) 99 | restoreData(data, arch, MODE_EXTDATA); 100 | break; 101 | case hblOpts::extra: 102 | while(1) 103 | { 104 | extrasMenu(); 105 | 106 | if(hidKeysDown() & KEY_B) 107 | break; 108 | 109 | } 110 | break; 111 | case hblOpts::exitapp: 112 | kill = true; 113 | break; 114 | } 115 | FSUSER_CloseArchive(arch); 116 | } 117 | 118 | killApp(down); 119 | 120 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 121 | drawTopBar(info); 122 | hblMenu.draw(); 123 | sf2d_end_frame(); 124 | 125 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 126 | data.printInfo(); 127 | sf2d_end_frame(); 128 | 129 | sf2d_swapbuffers(); 130 | } 131 | 132 | fsEnd(); 133 | } 134 | -------------------------------------------------------------------------------- /source/archive.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | 3 | #include "titledata.h" 4 | #include "archive.h" 5 | #include "ui.h" 6 | 7 | //All the information used here was found on 3dbrew.org 8 | //thank them too. 9 | bool openSaveArch(FS_Archive *out, const titleData dat, bool show) 10 | { 11 | //binary path 12 | u32 path[3] = {dat.media, dat.low, dat.high}; 13 | 14 | FS_Path binPath = {PATH_BINARY, 12, path}; 15 | 16 | Result res = FSUSER_OpenArchive(out, ARCHIVE_USER_SAVEDATA, binPath); 17 | if(res) 18 | { 19 | if(show) 20 | showError("Error opening save archive", (unsigned)res); 21 | return false; 22 | } 23 | 24 | return true; 25 | } 26 | 27 | bool openSaveArch3dsx(FS_Archive *arch) 28 | { 29 | Result res = FSUSER_OpenArchive(arch, ARCHIVE_SAVEDATA, fsMakePath(PATH_EMPTY, "")); 30 | if(res) 31 | { 32 | showError("Error opening save archive", (unsigned)res); 33 | return false; 34 | } 35 | 36 | return true; 37 | } 38 | 39 | bool openExtdata(FS_Archive *out, const titleData dat, bool show) 40 | { 41 | u32 path[3] = {MEDIATYPE_SD, dat.extdata, 0}; 42 | 43 | FS_Path binPath = {PATH_BINARY, 12, path}; 44 | 45 | Result res = FSUSER_OpenArchive(out, ARCHIVE_EXTDATA, binPath); 46 | if(res) 47 | { 48 | if(show) 49 | showError("Error opening ExtData", (unsigned)res); 50 | return false; 51 | } 52 | 53 | return true; 54 | } 55 | 56 | bool openSharedExt(FS_Archive *out, u32 id) 57 | { 58 | u32 path[3] = {MEDIATYPE_NAND, id, 0x00048000}; 59 | 60 | FS_Path binPath = {PATH_BINARY, 12, path}; 61 | 62 | Result res = FSUSER_OpenArchive(out, ARCHIVE_SHARED_EXTDATA, binPath); 63 | if(res) 64 | { 65 | showError("Error opening Shared Extdata", (unsigned)res); 66 | return false; 67 | } 68 | 69 | return true; 70 | } 71 | 72 | bool openBossExt(FS_Archive *out, const titleData dat) 73 | { 74 | u32 path[3] = {MEDIATYPE_SD, dat.extdata, 0}; 75 | 76 | FS_Path binPath = {PATH_BINARY, 12, path}; 77 | 78 | Result res = FSUSER_OpenArchive(out, ARCHIVE_BOSS_EXTDATA, binPath); 79 | if(res) 80 | { 81 | showError("Error opening Boss Extdata", (unsigned)res); 82 | return false; 83 | } 84 | 85 | return true; 86 | } 87 | 88 | bool openSysModule(FS_Archive *out, const titleData dat) 89 | { 90 | u32 path[2] = {MEDIATYPE_NAND, (0x00010000 | dat.unique)}; 91 | 92 | FS_Path binPath = {PATH_BINARY, 8, path}; 93 | 94 | Result res = FSUSER_OpenArchive(out, ARCHIVE_SYSTEM_SAVEDATA, binPath); 95 | if(res) 96 | { 97 | return false; 98 | } 99 | 100 | return true; 101 | } 102 | 103 | bool openSysSave(FS_Archive *out, const titleData dat) 104 | { 105 | u32 path[2] = {MEDIATYPE_NAND, (0x00020000 | dat.unique)}; 106 | 107 | FS_Path binPath = {PATH_BINARY, 8, path}; 108 | 109 | Result res = FSUSER_OpenArchive(out, ARCHIVE_SYSTEM_SAVEDATA, binPath); 110 | if(res) 111 | { 112 | //try opening as module instead 113 | if(openSysModule(out, dat)) 114 | return true; 115 | else 116 | { 117 | showError("Error opening system save data", (unsigned)res); 118 | return false; 119 | } 120 | } 121 | 122 | return true; 123 | } 124 | -------------------------------------------------------------------------------- /source/backup.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | 6 | #include "global.h" 7 | #include "backup.h" 8 | #include "util.h" 9 | #include "slot.h" 10 | #include "ui.h" 11 | #include "date.h" 12 | #include "file.h" 13 | #include "titles.h" 14 | #include "archive.h" 15 | 16 | void copyFileToSD(FS_Archive arch, const std::u16string from, const std::u16string to) 17 | { 18 | fsFile in(arch, from, FS_OPEN_READ); 19 | fsFile out(sdArch, to, FS_OPEN_WRITE, in.size()); 20 | 21 | u8 *buff = new u8[buff_size]; 22 | std::string copyString = "Copying " + toString(from) + "..."; 23 | progressBar fileProg((float)in.size(), copyString.c_str(), "Copying file"); 24 | u32 read, written; 25 | do 26 | { 27 | in.read(buff, &read, buff_size); 28 | out.write(buff, &written, read); 29 | if(written != read) 30 | { 31 | showMessage("Something went wrong writing!", "UH OH!"); 32 | break; 33 | } 34 | 35 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 36 | fileProg.draw((float)in.getOffset()); 37 | sf2d_end_frame(); 38 | 39 | sf2d_swapbuffers(); 40 | } 41 | while(!in.eof()); 42 | 43 | delete[] buff; 44 | 45 | in.close(); 46 | out.close(); 47 | } 48 | 49 | void copyDirToSD(FS_Archive save, const std::u16string from, const std::u16string to) 50 | { 51 | //Use dirList to get list of dir 52 | dirList list(save, from); 53 | 54 | for(unsigned i = 0; i < list.count(); i++) 55 | { 56 | if(list.isDir(i)) 57 | { 58 | std::u16string newFrom = from; 59 | newFrom += list.retItem(i); 60 | newFrom += L'/'; 61 | 62 | std::u16string newTo = to; 63 | newTo += list.retItem(i); 64 | FSUSER_CreateDirectory(sdArch, fsMakePath(PATH_UTF16, newTo.data()), 0); 65 | newTo += L'/'; 66 | 67 | copyDirToSD(save, newFrom, newTo); 68 | } 69 | else 70 | { 71 | std::u16string fullFrom = from; 72 | fullFrom += list.retItem(i); 73 | 74 | std::u16string fullTo = to; 75 | fullTo += list.retItem(i); 76 | 77 | copyFileToSD(save, fullFrom, fullTo); 78 | } 79 | } 80 | } 81 | 82 | bool backupData(const titleData dat, FS_Archive arch, int mode, bool autoName) 83 | { 84 | //This is our path to SD folder. UTF16 85 | std::u16string pathOut; 86 | //holds name from user 87 | std::u16string slot; 88 | 89 | //if auto, just use date/time 90 | if(autoName) 91 | { 92 | slot = tou16(GetDate(FORMAT_YMD)); 93 | if(autoBack) 94 | slot += tou16(" - AutoBack"); 95 | } 96 | else 97 | slot = getFolder(dat, mode, true); 98 | 99 | if(slot.empty()) 100 | return false; 101 | 102 | //get path returns path to /3ds/data/JKSM/[DIR] 103 | pathOut = getPath(mode) + dat.nameSafe + (char16_t)'/' + slot; 104 | std::u16string recreate = pathOut;//need this later after directory is deleted. 105 | pathOut += (char16_t)'/'; 106 | 107 | //I only do this because games use more files for more slots. 108 | FSUSER_DeleteDirectoryRecursively(sdArch, fsMakePath(PATH_UTF16, pathOut.data())); 109 | //recreate it. 110 | FSUSER_CreateDirectory(sdArch, fsMakePath(PATH_UTF16, recreate.data()), 0); 111 | 112 | //archive root 113 | std::u16string pathIn = (char16_t *)"/"; 114 | 115 | copyDirToSD(arch, pathIn, pathOut); 116 | 117 | //This gets annoying in auto mode 118 | if(!autoName) 119 | showMessage("Finished!", "Success!"); 120 | 121 | return true; 122 | } 123 | 124 | void autoBackup(menu m) 125 | { 126 | showMessage("This can take a few minutes depending on how many titles are selected.", "Info"); 127 | 128 | 129 | progressBar autoDump((float)m.getSelectCount(), "Copying saves... ", "Auto Backup"); 130 | //Keep track of what's done 131 | float dumpCount = 0; 132 | for(unsigned i = 0; i < m.getSize(); i++) 133 | { 134 | //This is for titles with no save archive ex. Fantasy Life 135 | bool dumped = false; 136 | FS_Archive saveArch; 137 | if(m.optSelected(i) && openSaveArch(&saveArch, sdTitle[i], false)) //if it's selected and we can open save archive 138 | { 139 | createTitleDir(sdTitle[i], MODE_SAVE); 140 | backupData(sdTitle[i], saveArch, MODE_SAVE, true); 141 | dumpCount++; 142 | dumped = true; 143 | } 144 | FSUSER_CloseArchive(saveArch); 145 | 146 | FS_Archive extArch; 147 | if(m.optSelected(i) && openExtdata(&extArch, sdTitle[i], false)) 148 | { 149 | createTitleDir(sdTitle[i], MODE_EXTDATA); 150 | backupData(sdTitle[i], extArch, MODE_EXTDATA, true); 151 | 152 | //check first to make sure we don't count it twice because no save arch 153 | if(!dumped) 154 | dumpCount++; 155 | } 156 | FSUSER_CloseArchive(extArch); 157 | 158 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 159 | autoDump.draw(i); 160 | sf2d_end_frame(); 161 | sf2d_swapbuffers(); 162 | } 163 | 164 | showMessage("Finished!", "Success!"); 165 | } 166 | -------------------------------------------------------------------------------- /source/backupmenu.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | 6 | #include "backupmenu.h" 7 | #include "global.h" 8 | #include "titledata.h" 9 | #include "ui.h" 10 | #include "menu.h" 11 | #include "util.h" 12 | 13 | enum backOpts 14 | { 15 | saveDat, 16 | extDat, 17 | back, 18 | }; 19 | 20 | static menu backMenu(0, 96, false, true); 21 | 22 | void prepBackMenu() 23 | { 24 | backMenu.addItem("Save Data Options"); 25 | backMenu.addItem("Extra Data Options"); 26 | backMenu.addItem("Back"); 27 | 28 | backMenu.autoVert(); 29 | } 30 | 31 | void backupMenu() 32 | { 33 | if(curTitle == NULL) 34 | { 35 | showMessage("OH SHIT! THIS SHOULDN'T HAPPEN!", "curTitle is NULL!!!"); 36 | state = prevState; 37 | return; 38 | } 39 | 40 | std::u32string info = curTitle->u32Name; 41 | if(curTitle->media == MEDIATYPE_GAME_CARD) 42 | info += U" : Cart"; 43 | else 44 | info += U" : SD/CIA"; 45 | 46 | hidScanInput(); 47 | u32 down = hidKeysDown(); 48 | 49 | backMenu.handleInput(down, 0); 50 | 51 | if(down & KEY_A) 52 | { 53 | switch(backMenu.getSelected()) 54 | { 55 | case backOpts::saveDat: 56 | state = STATE_SAVEMENU; 57 | break; 58 | case backOpts::extDat: 59 | state = STATE_EXTMENU; 60 | break; 61 | case backOpts::back: 62 | state = prevState; 63 | break; 64 | } 65 | } 66 | else if(down & KEY_B) 67 | state = prevState; 68 | 69 | killApp(down); 70 | 71 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 72 | drawTopBar(info); 73 | backMenu.draw(); 74 | sf2d_end_frame(); 75 | 76 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 77 | sf2d_end_frame(); 78 | 79 | sf2d_swapbuffers(); 80 | } 81 | -------------------------------------------------------------------------------- /source/date.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "date.h" 6 | 7 | //This returns the date as a c string 8 | char *GetDate(int Format) 9 | { 10 | char *Ret = new char[24]; 11 | 12 | time_t Raw; 13 | time(&Raw); 14 | tm *Time = localtime(&Raw); 15 | 16 | switch(Format) 17 | { 18 | case FORMAT_YDM: 19 | { 20 | sprintf(Ret, "%04d-%02d-%02d_%02d-%02d-%02d", Time->tm_year + 1900, Time->tm_mday, Time->tm_mon + 1, Time->tm_hour, Time->tm_min, Time->tm_sec); 21 | break; 22 | } 23 | case FORMAT_YMD: 24 | { 25 | sprintf(Ret, "%04d-%02d-%02d_%02d-%02d-%02d", Time->tm_year + 1900, Time->tm_mon + 1, Time->tm_mday, Time->tm_hour, Time->tm_min, Time->tm_sec); 26 | break; 27 | } 28 | } 29 | 30 | return Ret; 31 | } 32 | 33 | //this returns the time for the top bar 34 | std::string RetTime() 35 | { 36 | time_t Raw; 37 | time(&Raw); 38 | tm *Time = localtime(&Raw); 39 | 40 | char Tmp[32]; 41 | 42 | sprintf(Tmp, "%02d:%02d", Time->tm_hour, Time->tm_min); 43 | 44 | return std::string(Tmp); 45 | } 46 | -------------------------------------------------------------------------------- /source/db.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | 6 | #include "db.h" 7 | #include "titledata.h" 8 | 9 | //opens, creates and returns a file for writing to. 10 | FILE *dbCreate(const char *path) 11 | { 12 | FILE *db = fopen(path, "wb"); 13 | return db; 14 | } 15 | 16 | //opens and returns file for reading 17 | FILE *dbOpen(const char *path) 18 | { 19 | FILE *db = fopen(path, "rb"); 20 | return db; 21 | } 22 | 23 | //This is for writing the number of titles installed 24 | void dbWriteCount(FILE *db, u32 count, u8 rev) 25 | { 26 | fwrite(&count, sizeof(uint16_t), 1, db); 27 | 28 | fputc(rev, db); 29 | } 30 | 31 | //this gets the count from the beginning 32 | //should be used first after opening for reading. 33 | u32 dbGetCount(FILE *db) 34 | { 35 | u32 ret = 0; 36 | fread(&ret, sizeof(uint16_t), 1, db); 37 | 38 | fgetc(db); 39 | 40 | return ret; 41 | } 42 | 43 | //This was a spacer byte, but I'll use it for this. 44 | u8 dbGetRev(FILE *db) 45 | { 46 | fseek(db, 2, SEEK_SET); 47 | u8 ret = fgetc(db); 48 | fseek(db, 0, SEEK_SET); 49 | 50 | return ret; 51 | } 52 | 53 | void copyu16(char16_t *out, std::u16string in) 54 | { 55 | memset(out, 0, sizeof(char16_t) * 0x40); 56 | for(unsigned i = 0; i < in.length(); i++) 57 | out[i] = in.data()[i]; 58 | } 59 | 60 | //writes needed data from titleData 'w' to file 61 | void dbWriteData(FILE *db, const titleData w) 62 | { 63 | //UTF16 title 64 | char16_t titleOut[0x40]; 65 | copyu16(titleOut, w.name); 66 | fwrite(titleOut, sizeof(char16_t), 0x40, db); 67 | fputc(0, db); 68 | 69 | //ASCII product code 70 | char prodOut[16]; 71 | memset(prodOut, 0, 16); 72 | sprintf(prodOut, "%s", w.prodCode.c_str()); 73 | fwrite(prodOut, 1, 16, db); 74 | fputc(0, db); 75 | 76 | fwrite(&w.id, sizeof(u64), 1, db); 77 | 78 | fputc(0, db); 79 | } 80 | 81 | //reads and returns a titleData object from db 82 | titleData dbGetData(FILE *db) 83 | { 84 | titleData ret; 85 | 86 | char16_t title[0x40]; 87 | fread(title, sizeof(char16_t), 0x40, db); 88 | ret.name.assign(title); 89 | 90 | fgetc(db); 91 | 92 | char prodCode[16]; 93 | fread(prodCode, 1, 16, db); 94 | ret.prodCode.assign(prodCode); 95 | 96 | fgetc(db); 97 | 98 | fread(&ret.id, sizeof(u64), 1, db); 99 | 100 | //last 0x00 101 | fgetc(db); 102 | 103 | //this takes care of a few things needed 104 | ret.initId(); 105 | 106 | return ret; 107 | } 108 | -------------------------------------------------------------------------------- /source/dev.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | 5 | #include "dev.h" 6 | #include "menu.h" 7 | #include "util.h" 8 | #include "global.h" 9 | #include "ui.h" 10 | 11 | //This is just for testing stuff. 12 | 13 | static menu devMenu(0, 0, false, true); 14 | 15 | void prepDevMenu() 16 | { 17 | devMenu.addItem("fsStart"); 18 | devMenu.addItem("fsEnd"); 19 | devMenu.addItem("Back"); 20 | 21 | devMenu.autoVert(); 22 | } 23 | 24 | enum devOpts 25 | { 26 | _fsStart, 27 | _fsEnd, 28 | _back 29 | }; 30 | 31 | void showDevMenu() 32 | { 33 | hidScanInput(); 34 | 35 | u32 down = hidKeysDown(); 36 | 37 | devMenu.handleInput(down, 0); 38 | 39 | if(down & KEY_A) 40 | { 41 | switch(devMenu.getSelected()) 42 | { 43 | case devOpts::_fsStart: 44 | fsStart(); 45 | break; 46 | case devOpts::_fsEnd: 47 | fsEnd(); 48 | break; 49 | case devOpts::_back: 50 | state = STATE_MAINMENU; 51 | break; 52 | } 53 | } 54 | else if(down & KEY_B) 55 | state = STATE_MAINMENU; 56 | 57 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 58 | drawTopBar(U"DevMenu"); 59 | devMenu.draw(); 60 | sf2d_end_frame(); 61 | 62 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 63 | sf2d_end_frame(); 64 | 65 | sf2d_swapbuffers(); 66 | } 67 | -------------------------------------------------------------------------------- /source/extmenu.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | 6 | #include "extmenu.h" 7 | #include "archive.h" 8 | #include "titledata.h" 9 | #include "backup.h" 10 | #include "restore.h" 11 | #include "global.h" 12 | #include "ui.h" 13 | #include "util.h" 14 | #include "menu.h" 15 | 16 | enum extOpts 17 | { 18 | expExt, 19 | impExt, 20 | browseExt, 21 | delExt, 22 | back 23 | }; 24 | 25 | static menu extMenu(128, 80, false, true); 26 | 27 | void prepExtMenu() 28 | { 29 | extMenu.addItem("Export ExtData"); 30 | extMenu.addItem("Import ExtData"); 31 | extMenu.addItem("Browse for ExtData"); 32 | extMenu.addItem("Delete ExtData"); 33 | extMenu.addItem("Back"); 34 | 35 | extMenu.autoVert(); 36 | } 37 | 38 | void showExtMenu() 39 | { 40 | std::u32string info = curTitle->u32Name + U" : Extra Data"; 41 | 42 | hidScanInput(); 43 | 44 | u32 down = hidKeysDown(); 45 | 46 | touchPosition p; 47 | hidTouchRead(&p); 48 | 49 | extMenu.handleInput(down, 0); 50 | 51 | killApp(down); 52 | 53 | if(down & KEY_A) 54 | { 55 | FS_Archive extData; 56 | switch(extMenu.getSelected()) 57 | { 58 | case extOpts::expExt: 59 | if(openExtdata(&extData, *curTitle, true)) 60 | { 61 | createTitleDir(*curTitle, MODE_EXTDATA); 62 | backupData(*curTitle, extData, MODE_EXTDATA, false); 63 | } 64 | break; 65 | case extOpts::impExt: 66 | if(openExtdata(&extData, *curTitle, true)) 67 | restoreData(*curTitle, extData, MODE_EXTDATA); 68 | else 69 | { 70 | if(confirm("Would you like to try to create Extra Data for this title?")) 71 | createExtData(*curTitle); 72 | } 73 | break; 74 | case extOpts::browseExt: 75 | if(openExtdata(&extData, *curTitle, true)) 76 | restoreDataSDPath(*curTitle, extData, MODE_EXTDATA); 77 | else 78 | { 79 | if(confirm("Would you like to try to create Extra Data for this title?")) 80 | createExtData(*curTitle); 81 | } 82 | break; 83 | case extOpts::delExt: 84 | if(confirm("Are you sure you want to delete this title's extdata?")) 85 | deleteExtdata(*curTitle); 86 | break; 87 | case extOpts::back: 88 | state = STATE_BACKUPMENU; 89 | break; 90 | } 91 | FSUSER_CloseArchive(extData); 92 | } 93 | 94 | else if(down & KEY_B) 95 | state = STATE_BACKUPMENU; 96 | 97 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 98 | drawTopBar(info); 99 | extMenu.draw(); 100 | sf2d_end_frame(); 101 | 102 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 103 | sf2d_end_frame(); 104 | 105 | sf2d_swapbuffers(); 106 | } 107 | -------------------------------------------------------------------------------- /source/extra.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "extra.h" 9 | #include "global.h" 10 | #include "menu.h" 11 | #include "archive.h" 12 | #include "ui.h" 13 | #include "gstr.h" 14 | #include "file.h" 15 | 16 | /*These are extra things I added. 17 | I wasn't sure if there was a cia coin setter 18 | besides Nintendo's official one. 19 | */ 20 | 21 | void setPlayCoins() 22 | { 23 | FS_Archive shared; 24 | if(openSharedExt(&shared, 0xf000000b)) 25 | { 26 | fsFile gameCoin(shared, "/gamecoin.dat", FS_OPEN_READ | FS_OPEN_WRITE); 27 | 28 | int coinAmount = 0; 29 | gameCoin.seek(0x4, seek_beg); 30 | coinAmount = gameCoin.getByte(); 31 | coinAmount += gameCoin.getByte() << 8; 32 | 33 | coinAmount = getInt("Enter a number between 0 and 300", coinAmount, 300); 34 | if(coinAmount != -1) 35 | { 36 | gameCoin.seek(-2, seek_cur); 37 | gameCoin.putByte(coinAmount); 38 | gameCoin.putByte(coinAmount >> 8); 39 | } 40 | 41 | gameCoin.close(); 42 | } 43 | } 44 | 45 | void saveColBin() 46 | { 47 | FILE *colBin = fopen("colBin", "wb"); 48 | 49 | fwrite(clearColor, 1, 3, colBin); 50 | fwrite(selColor, 1, 3, colBin); 51 | fwrite(unSelColor, 1, 3, colBin); 52 | 53 | fclose(colBin); 54 | } 55 | 56 | void setBGColor() 57 | { 58 | showMessage("Enter RGB info for the color wanted.", "Info"); 59 | 60 | int RGB[3]; 61 | 62 | if( (RGB[0] = getInt("Background Red", clearColor[0], 255)) != -1 && (RGB[1] = getInt("Background Green", clearColor[1], 255)) != -1 && (RGB[2] = getInt("Background Blue", clearColor[2], 255)) != -1) 63 | { 64 | for(int i = 0; i < 3; i++) 65 | clearColor[i] = RGB[i]; 66 | 67 | sf2d_set_clear_color(RGBA8(clearColor[0], clearColor[1], clearColor[2], 255)); 68 | 69 | saveColBin(); 70 | } 71 | } 72 | 73 | void setSelColor() 74 | { 75 | showMessage("Enter RGB info for the color wanted.", "Info"); 76 | 77 | int RGB[3]; 78 | 79 | if( (RGB[0] = getInt("Selected Red", selColor[0], 255)) != -1 && (RGB[1] = getInt("Selected Green", selColor[1], 255)) != -1 && (RGB[2] = getInt("Selected Blue", selColor[2], 255)) != -1) 80 | { 81 | for(int i = 0; i < 3; i++) 82 | selColor[i] = RGB[i]; 83 | 84 | saveColBin(); 85 | } 86 | } 87 | 88 | void setUnselColor() 89 | { 90 | showMessage("Enter RGB info for the color wanted.", "Info"); 91 | 92 | int RGB[3]; 93 | if( (RGB[0] = getInt("Unselected Red", unSelColor[0], 255)) != -1 && (RGB[1] = getInt("Unselected Green", unSelColor[1], 255)) != -1 && (RGB[2] = getInt("Unselected Blue", unSelColor[2], 255)) != -1) 94 | { 95 | for(int i = 0; i < 3; i++) 96 | unSelColor[i] = RGB[i]; 97 | 98 | saveColBin(); 99 | } 100 | } 101 | 102 | enum extraOpts 103 | { 104 | setPlay, 105 | centeredText, 106 | autoBackAtRest, 107 | useSysLang, 108 | bgColor, 109 | slColor, 110 | unslColor, 111 | back 112 | }; 113 | 114 | std::string onOff(bool onOff) 115 | { 116 | if(onOff) 117 | return "On"; 118 | 119 | return "Off"; 120 | } 121 | 122 | void saveCfg() 123 | { 124 | FILE *config = fopen("config", "wb"); 125 | 126 | fputc(centered, config); 127 | fputc(autoBack, config); 128 | fputc(useLang, config); 129 | 130 | fclose(config); 131 | } 132 | 133 | void switchBool(bool *sw) 134 | { 135 | if(*sw) 136 | *sw = false; 137 | else 138 | *sw = true; 139 | } 140 | 141 | static menu extra(136, 80, false, true); 142 | 143 | void prepExtras() 144 | { 145 | extra.addItem("Set Play Coins"); 146 | extra.addItem(std::string("Centered text: " + onOff(centered)).c_str()); 147 | extra.addItem(std::string("Auto Backup: " + onOff(autoBack)).c_str()); 148 | extra.addItem(std::string("Use System Language: " + onOff(useLang)).c_str()); 149 | extra.addItem("Set Background Color"); 150 | extra.addItem("Set Selected Item Color"); 151 | extra.addItem("Set Unselected Item Color"); 152 | extra.addItem("Back"); 153 | 154 | extra.autoVert(); 155 | } 156 | 157 | static const std::string helpDescs[] = 158 | { 159 | "Sets play coins to a number between 0 - 300", 160 | "Sets whether title select, nand title select, and folder select menus are centered. (Requires reboot to take effect.)", 161 | "Automatically creates a backup when save data is imported. Just in case!", 162 | "Uses system language when getting titles. Defaults to English if title is empty.", 163 | "Sets the background color. Asks for RGB info in that order", 164 | "Sets the color of selected options in menus. Asks for RGB info in that order", 165 | "Sets the color of unselected menu options. Asks for RGB info in that order", 166 | "This means go back." 167 | }; 168 | 169 | void extrasMenu() 170 | { 171 | hidScanInput(); 172 | 173 | u32 down = hidKeysDown(); 174 | 175 | extra.handleInput(down, 0); 176 | 177 | if(down & KEY_A) 178 | { 179 | switch(extra.getSelected()) 180 | { 181 | case extraOpts::setPlay: 182 | setPlayCoins(); 183 | break; 184 | case extraOpts::centeredText: 185 | switchBool(¢ered); 186 | extra.updateItem(extraOpts::centeredText, std::string("Centered text: " + onOff(centered)).c_str()); 187 | saveCfg(); 188 | break; 189 | case extraOpts::autoBackAtRest: 190 | switchBool(&autoBack); 191 | extra.updateItem(extraOpts::autoBackAtRest, std::string("Auto Backup: " + onOff(autoBack)).c_str()); 192 | saveCfg(); 193 | break; 194 | case extraOpts::useSysLang: 195 | switchBool(&useLang); 196 | extra.updateItem(extraOpts::useSysLang, std::string("Use System Language: " + onOff(useLang)).c_str()); 197 | saveCfg(); 198 | break; 199 | case extraOpts::bgColor: 200 | setBGColor(); 201 | break; 202 | case extraOpts::slColor: 203 | setSelColor(); 204 | break; 205 | case extraOpts::unslColor: 206 | setUnselColor(); 207 | break; 208 | case extraOpts::back: 209 | state = STATE_MAINMENU; 210 | break; 211 | } 212 | } 213 | else if(down & KEY_B) 214 | state = STATE_MAINMENU; 215 | 216 | killApp(down); 217 | 218 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 219 | drawTopBar(U"Config/Extras"); 220 | extra.draw(); 221 | sf2d_end_frame(); 222 | 223 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 224 | sftd_draw_text_wrap(font, 0, 0, RGBA8(255, 255, 255, 255), 12, 320, helpDescs[extra.getSelected()].c_str()); 225 | sf2d_end_frame(); 226 | 227 | sf2d_swapbuffers(); 228 | } 229 | -------------------------------------------------------------------------------- /source/file.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "file.h" 8 | #include "util.h" 9 | #include "ui.h" 10 | 11 | fsFile::fsFile(FS_Archive _arch, std::u16string _path, u32 openFlags) 12 | { 13 | arch = _arch; 14 | error = FSUSER_OpenFile(&fileHandle, arch, fsMakePath(PATH_UTF16, _path.data()), openFlags, 0); 15 | if(error) 16 | { 17 | opened = false; 18 | } 19 | else 20 | { 21 | FSFILE_GetSize(fileHandle, &fileSize); 22 | opened = true; 23 | } 24 | } 25 | 26 | fsFile::fsFile(FS_Archive _arch, std::u16string _path, u32 openFlags, u64 createSize) 27 | { 28 | arch = _arch; 29 | error = FSUSER_OpenFile(&fileHandle, arch, fsMakePath(PATH_UTF16, _path.data()), openFlags, 0); 30 | if(error) 31 | { 32 | error = FSUSER_CreateFile(arch, fsMakePath(PATH_UTF16, _path.data()), 0, createSize); 33 | if(error) 34 | { 35 | opened = false; 36 | return; 37 | } 38 | error = FSUSER_OpenFile(&fileHandle, arch, fsMakePath(PATH_UTF16, _path.data()), openFlags, 0); 39 | if(error) 40 | opened = false; 41 | else 42 | opened = true; 43 | } 44 | } 45 | 46 | fsFile::fsFile(FS_Archive _arch, const char *_path, u32 openFlags) 47 | { 48 | arch = _arch; 49 | error = FSUSER_OpenFile(&fileHandle, arch, fsMakePath(PATH_ASCII, _path), openFlags, 0); 50 | if(error) 51 | opened = false; 52 | else 53 | { 54 | FSFILE_GetSize(fileHandle, &fileSize); 55 | opened = true; 56 | } 57 | } 58 | 59 | 60 | fsFile::fsFile(FS_Archive _arch, const char *_path, u32 openFlags, u64 createSize) 61 | { 62 | arch = _arch; 63 | error = FSUSER_OpenFile(&fileHandle, arch, fsMakePath(PATH_ASCII, _path), openFlags, 0); 64 | if(error) 65 | { 66 | error = FSUSER_CreateFile(arch, fsMakePath(PATH_ASCII, _path), 0, createSize); 67 | if(error) 68 | { 69 | opened = false; 70 | return; 71 | } 72 | error = FSUSER_OpenFile(&fileHandle, arch, fsMakePath(PATH_ASCII, _path), openFlags, 0); 73 | if(error) 74 | opened = false; 75 | else 76 | opened = true; 77 | } 78 | } 79 | 80 | fsFile::fsFile(FS_ArchiveID _arch, FS_Path archPath, FS_Path filePath, u32 openFlags) 81 | { 82 | error = FSUSER_OpenFileDirectly(&fileHandle, _arch, archPath, filePath, openFlags, 0); 83 | if(error == 0) 84 | opened = true; 85 | else 86 | opened = false; 87 | } 88 | 89 | fsFile::fsFile(FS_Archive _arch, FS_Path _path, u32 openFlags) 90 | { 91 | error = FSUSER_OpenFile(&fileHandle, _arch, _path, openFlags, 0); 92 | if(error) 93 | opened = false; 94 | else 95 | opened = true; 96 | } 97 | 98 | bool fsFile::isOpened() 99 | { 100 | return opened; 101 | } 102 | 103 | bool fsFile::eof() 104 | { 105 | return offset < fileSize ? false : true; 106 | } 107 | 108 | Result fsFile::read(void *buff, u32 *readOut, u32 max) 109 | { 110 | error = FSFILE_Read(fileHandle, readOut, offset, buff, max); 111 | if(error) 112 | { 113 | if(*readOut > max) 114 | *readOut = max; 115 | 116 | writeErrorToBuff((u8 *)buff, *readOut, error); 117 | 118 | } 119 | 120 | offset += *readOut; 121 | 122 | return error; 123 | } 124 | 125 | Result fsFile::write(void *dat, u32 *written, u32 size) 126 | { 127 | *written = 0; 128 | error = FSFILE_Write(fileHandle, written, offset, dat, size, FS_WRITE_FLUSH); 129 | 130 | offset += *written; 131 | 132 | return error; 133 | } 134 | 135 | void fsFile::seek(int pos, u8 seekFrom) 136 | { 137 | switch(seekFrom) 138 | { 139 | case 0: 140 | offset = pos; 141 | break; 142 | case 1: 143 | offset = offset + pos; 144 | break; 145 | case 2: 146 | offset = fileSize + pos; 147 | break; 148 | } 149 | } 150 | 151 | u8 fsFile::getByte() 152 | { 153 | u8 ret; 154 | FSFILE_Read(fileHandle, NULL, offset, &ret, 1); 155 | ++offset; 156 | return ret; 157 | } 158 | 159 | void fsFile::putByte(u8 put) 160 | { 161 | FSFILE_Write(fileHandle, NULL, offset, &put, 1, FS_WRITE_FLUSH); 162 | ++offset; 163 | } 164 | 165 | bool fsFile::close() 166 | { 167 | error = FSFILE_Close(fileHandle); 168 | 169 | return error == 0; 170 | } 171 | 172 | u64 fsFile::size() 173 | { 174 | return fileSize; 175 | } 176 | 177 | u64 fsFile::getOffset() 178 | { 179 | return offset; 180 | } 181 | 182 | unsigned int fsFile::getError() 183 | { 184 | return error; 185 | } 186 | 187 | struct 188 | { 189 | bool operator()(const FS_DirectoryEntry& a, const FS_DirectoryEntry& b) 190 | { 191 | for(uint32_t i = 0; i < 0x106; i++) 192 | { 193 | int charA = tolower(a.name[i]), charB = tolower(b.name[i]); 194 | if(charA != charB) 195 | return charA < charB; 196 | } 197 | 198 | return false; 199 | } 200 | } sortDirs; 201 | 202 | dirList::dirList(FS_Archive arch, const std::u16string p) 203 | { 204 | //keep archive data 205 | a = arch; 206 | 207 | //save path 208 | path = p; 209 | 210 | //open path given by p 211 | FSUSER_OpenDirectory(&d, a, fsMakePath(PATH_UTF16, p.data())); 212 | 213 | //loop until we stop reading anymore entries 214 | u32 read = 0; 215 | do 216 | { 217 | FS_DirectoryEntry getEnt; 218 | FSDIR_Read(d, &read, 1, &getEnt); 219 | if(read == 1) 220 | entry.push_back(getEnt); 221 | } 222 | while(read > 0); 223 | 224 | FSDIR_Close(d); 225 | 226 | std::sort(entry.begin(), entry.end(), sortDirs); 227 | } 228 | 229 | //clears vector used 230 | dirList::~dirList() 231 | { 232 | entry.clear(); 233 | } 234 | 235 | //same thing as contructor. can be used to reinit dirList too 236 | void dirList::reassign(const std::u16string p) 237 | { 238 | entry.clear(); 239 | 240 | FSUSER_OpenDirectory(&d, a, fsMakePath(PATH_UTF16, p.data())); 241 | 242 | u32 read = 0; 243 | do 244 | { 245 | FS_DirectoryEntry getEnt; 246 | FSDIR_Read(d, &read, 1, &getEnt); 247 | if(read == 1) 248 | entry.push_back(getEnt); 249 | } 250 | while(read > 0); 251 | 252 | FSDIR_Close(d); 253 | 254 | std::sort(entry.begin(), entry.end(), sortDirs); 255 | } 256 | 257 | unsigned dirList::count() 258 | { 259 | return entry.size(); 260 | } 261 | 262 | //returns true if item is a directory 263 | bool dirList::isDir(int i) 264 | { 265 | return entry[i].attributes == FS_ATTRIBUTE_DIRECTORY; 266 | } 267 | 268 | //returns entry's name as u16string 269 | std::u16string dirList::retItem(int i) 270 | { 271 | return std::u16string((char16_t *)entry[i].name); 272 | } 273 | -------------------------------------------------------------------------------- /source/global.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "global.h" 9 | #include "date.h" 10 | #include "sys.h" 11 | #include "menu.h" 12 | #include "sd_cia.h" 13 | #include "titledata.h" 14 | #include "backupmenu.h" 15 | #include "savemenu.h" 16 | #include "extmenu.h" 17 | #include "titles.h" 18 | #include "nand.h" 19 | #include "hbfilter.h" 20 | #include "extra.h" 21 | #include "shared.h" 22 | #include "dev.h" 23 | #include "ui.h" 24 | 25 | unsigned const buff_size = 0x20000; 26 | 27 | sftd_font * font; 28 | 29 | FS_Archive sdArch; 30 | 31 | bool hbl = false, devMode = false, kill = false; 32 | 33 | //config 34 | bool centered = true, autoBack = false, useLang = false; 35 | 36 | //default colors 37 | u8 clearColor[3] = {0, 0, 0}; 38 | u8 selColor[3] = {0, 255, 0}; 39 | u8 unSelColor[3] = {128, 128, 128}; 40 | 41 | //I needed a quick way to get most of it under one loop without having to completely rewrite it 42 | //This is what I came up with. 43 | int state = states::STATE_MAINMENU, prevState = states::STATE_MAINMENU; 44 | u8 sysLanguage = 1; 45 | titleData *curTitle = NULL; 46 | 47 | void handleState() 48 | { 49 | switch(state) 50 | { 51 | case states::STATE_MAINMENU: 52 | mainMenu(); 53 | break; 54 | case states::STATE_TITLEMENU: 55 | sdStartSelect(); 56 | break; 57 | case states::STATE_BACKUPMENU: 58 | backupMenu(); 59 | break; 60 | case states::STATE_SAVEMENU: 61 | showSaveMenu(); 62 | break; 63 | case states::STATE_EXTMENU: 64 | showExtMenu(); 65 | break; 66 | case states::STATE_NANDSELECT: 67 | nandStartSelect(); 68 | break; 69 | case states::STATE_NANDBACKUP: 70 | nandBackup(); 71 | break; 72 | case states::STATE_EXTRAS: 73 | extrasMenu(); 74 | break; 75 | case states::STATE_SHARED: 76 | sharedExtManager(); 77 | break; 78 | case states::STATE_SHAREDBACKUP: 79 | sharedBackupMenu(); 80 | break; 81 | case states::STATE_DEVMENU: 82 | showDevMenu(); 83 | break; 84 | default: 85 | showMessage("This shouldn't happen.", "Umm..."); 86 | state = states::STATE_MAINMENU; 87 | break; 88 | } 89 | } 90 | 91 | void killApp(u32 up) 92 | { 93 | if(up & KEY_START) 94 | kill = true; 95 | } 96 | 97 | enum mMenuOpts 98 | { 99 | cia, 100 | sys, 101 | shared, 102 | ref, 103 | filter, 104 | extra, 105 | exitapp, 106 | dev 107 | }; 108 | 109 | static menu mMenu(136, 80, false, true); 110 | 111 | void prepMain() 112 | { 113 | mMenu.addItem("Titles"); 114 | mMenu.addItem("System Titles"); 115 | mMenu.addItem("Shared ExtData"); 116 | mMenu.addItem("Refresh Games"); 117 | mMenu.addItem("Download Filter"); 118 | mMenu.addItem("Config/Extras"); 119 | mMenu.addItem("Exit"); 120 | 121 | if(devMode) 122 | mMenu.addItem("Dev"); 123 | 124 | mMenu.autoVert(); 125 | } 126 | 127 | void mainMenu() 128 | { 129 | 130 | hidScanInput(); 131 | 132 | u32 down = hidKeysDown(); 133 | 134 | mMenu.handleInput(down, 0); 135 | if(down & KEY_A) 136 | { 137 | switch(mMenu.getSelected()) 138 | { 139 | case mMenuOpts::cia: 140 | state = states::STATE_TITLEMENU; 141 | break; 142 | case mMenuOpts::sys: 143 | state = states::STATE_NANDSELECT; 144 | break; 145 | case mMenuOpts::shared: 146 | state = states::STATE_SHARED; 147 | break; 148 | case mMenuOpts::ref: 149 | remove("titles"); 150 | sdTitlesInit(); 151 | break; 152 | case mMenuOpts::filter: 153 | remove("filter.txt"); 154 | loadFilterList(); 155 | break; 156 | case mMenuOpts::extra: 157 | state = STATE_EXTRAS; 158 | break; 159 | case mMenuOpts::exitapp: 160 | kill = true; 161 | break; 162 | case mMenuOpts::dev: 163 | state = STATE_DEVMENU; 164 | break; 165 | } 166 | } 167 | else if(down & KEY_B) 168 | kill = true; 169 | 170 | killApp(down); 171 | 172 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 173 | drawTopBar(std::u32string(U"JKSM - " + BUILD_DATE)); 174 | mMenu.draw(); 175 | sf2d_end_frame(); 176 | 177 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 178 | sf2d_end_frame(); 179 | 180 | sf2d_swapbuffers(); 181 | } 182 | -------------------------------------------------------------------------------- /source/gstr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include <3ds.h> 4 | #include 5 | #include 6 | #include 7 | 8 | #include "gstr.h" 9 | #include "global.h" 10 | #include "date.h" 11 | #include "ui.h" 12 | 13 | std::string GetString(const char *hint) 14 | { 15 | hidScanInput(); 16 | 17 | u32 held = hidKeysHeld(); 18 | if(held & KEY_L) 19 | return GetDate(FORMAT_YDM); 20 | else if(held & KEY_R) 21 | return GetDate(FORMAT_YMD); 22 | 23 | SwkbdState keyState; 24 | char input[64]; 25 | 26 | swkbdInit(&keyState, SWKBD_TYPE_NORMAL, 2, 64); 27 | swkbdSetHintText(&keyState, hint); 28 | swkbdSetFeatures(&keyState, SWKBD_PREDICTIVE_INPUT); 29 | SwkbdDictWord dates[2]; 30 | swkbdSetDictWord(&dates[0], "2016", GetDate(FORMAT_YDM)); 31 | swkbdSetDictWord(&dates[1], "2016", GetDate(FORMAT_YMD)); 32 | swkbdSetInitialText(&keyState, GetDate(FORMAT_YMD)); 33 | swkbdSetDictionary(&keyState, dates, 2); 34 | 35 | swkbdInputText(&keyState, input, 64); 36 | 37 | return std::string(input); 38 | } 39 | 40 | int getInt(const char *hint, int init, int maxValue) 41 | { 42 | SwkbdState keyState; 43 | char input[8]; 44 | 45 | swkbdInit(&keyState, SWKBD_TYPE_NUMPAD, 2, 8); 46 | swkbdSetHintText(&keyState, hint); 47 | if(init != -1) 48 | { 49 | sprintf(input, "%i", init); 50 | swkbdSetInitialText(&keyState, input); 51 | } 52 | 53 | SwkbdButton pressed = swkbdInputText(&keyState, input, 8); 54 | int ret; 55 | //Cancel 56 | if(pressed == SWKBD_BUTTON_LEFT) 57 | ret = -1; 58 | else 59 | { 60 | ret = strtol(input, NULL, 10); 61 | if(ret > maxValue) 62 | ret = maxValue; 63 | } 64 | return ret; 65 | } 66 | -------------------------------------------------------------------------------- /source/hbfilter.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "hbfilter.h" 8 | #include "util.h" 9 | #include "ui.h" 10 | 11 | std::vector filterID; 12 | 13 | bool downloadFilter() 14 | { 15 | u32 wifi; 16 | ACU_GetWifiStatus(&wifi); 17 | if(wifi == 0) 18 | return false; 19 | 20 | httpcContext filter; 21 | 22 | Result res = httpcOpenContext(&filter, HTTPC_METHOD_GET, "https://raw.githubusercontent.com/J-D-K/JKSM/master/filter.txt", 1); 23 | if(res) 24 | { 25 | showError("Open context.", (unsigned)res); 26 | return false; 27 | } 28 | 29 | res = httpcSetSSLOpt(&filter, SSLCOPT_DisableVerify); 30 | if(res) 31 | { 32 | showError("Set SSL Opt.", (u32)res); 33 | } 34 | 35 | res = httpcBeginRequest(&filter); 36 | if(res) 37 | { 38 | showError("Begin request.", (u32)res); 39 | return false; 40 | } 41 | 42 | u32 code; 43 | res = httpcGetResponseStatusCode(&filter, &code); 44 | if(res || code != 200) 45 | { 46 | showMessage("Not found?", "wut"); 47 | return false; 48 | } 49 | 50 | u32 fSize; 51 | res = httpcGetDownloadSizeState(&filter, NULL, &fSize); 52 | if(res) 53 | { 54 | showError("Download size.", (u32)res); 55 | return false; 56 | } 57 | 58 | u8 *buff = new u8[fSize]; 59 | res = httpcDownloadData(&filter, buff, fSize, NULL); 60 | if(res) 61 | { 62 | showError("Download data.", (u32)res); 63 | delete[] buff; 64 | return false; 65 | } 66 | 67 | FILE *filterTxt = fopen("filter.txt", "wb"); 68 | fwrite(buff, 1, fSize, filterTxt); 69 | fclose(filterTxt); 70 | 71 | delete[] buff; 72 | 73 | showMessage("Filter downloaded.", "Info"); 74 | 75 | return true; 76 | } 77 | 78 | void loadFilterList() 79 | { 80 | filterID.clear(); 81 | if(fexists("filter.txt")) 82 | { 83 | FILE *load = fopen("filter.txt", "r"); 84 | 85 | char id[16]; 86 | 87 | while(fgets(id, 16, load)) 88 | { 89 | if(id[0] != '#') 90 | { 91 | u32 newID = strtoul(id, NULL, 16); 92 | filterID.push_back(newID); 93 | } 94 | } 95 | 96 | fclose(load); 97 | } 98 | else 99 | { 100 | if(downloadFilter()) 101 | loadFilterList(); 102 | } 103 | } 104 | 105 | bool hbFilter(u64 id) 106 | { 107 | u32 low = (u32)id; 108 | //Don't need code specifically for retroarch. 109 | //Thank you ksanislo for titledb 110 | for(unsigned i = 0; i < filterID.size(); i++) 111 | { 112 | if(low == filterID[i]) 113 | return true; 114 | } 115 | return false; 116 | } 117 | -------------------------------------------------------------------------------- /source/main.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "sys.h" 9 | #include "global.h" 10 | #include "util.h" 11 | #include "3dsx.h" 12 | #include "titles.h" 13 | 14 | int main(int argc, const char * argv[]) 15 | { 16 | hidInit(); 17 | hidScanInput(); 18 | u32 held = hidKeysHeld(); 19 | 20 | if((held & KEY_R) && (held & KEY_L)) { devMode = true; } 21 | 22 | sysInit(); 23 | sdTitlesInit(); 24 | nandTitlesInit(); 25 | while(aptMainLoop() && !kill) 26 | { 27 | handleState(); 28 | } 29 | 30 | sysExit(); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /source/menu.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "global.h" 8 | #include "menu.h" 9 | 10 | #define FONT_SIZE 12 11 | 12 | menuItem::menuItem(const std::u32string s, bool center, int _x) 13 | { 14 | selected = false; 15 | text.assign(s); 16 | if(center) 17 | autoCenter(); 18 | else 19 | x = _x; 20 | } 21 | 22 | void menuItem::autoCenter() 23 | { 24 | x = (400 / 2) - (sftd_get_wtext_width(font, 12, (wchar_t *)text.data()) / 2); 25 | if(x < 0) 26 | x = 0; 27 | } 28 | 29 | void menuItem::draw(int y, unsigned color) 30 | { 31 | sftd_draw_wtext(font, x, y, color, 12, (wchar_t *)text.data()); 32 | } 33 | 34 | menu::menu(unsigned sx, unsigned sy, bool sMulti, bool _center) 35 | { 36 | x = sx; 37 | y = sy; 38 | multi = sMulti; 39 | center = _center; 40 | selected = 0; 41 | start = 0; 42 | fc = 0; 43 | } 44 | 45 | menu::~menu() 46 | { 47 | opts.clear(); 48 | } 49 | 50 | void menu::addItem(const char *a) 51 | { 52 | char32_t *tmp = new char32_t[128]; 53 | memset(tmp, 0, sizeof(char32_t) * 128); 54 | utf8_to_utf32((uint32_t *)tmp, (uint8_t *)a, 128); 55 | 56 | std::u32string t; 57 | t.assign(tmp); 58 | 59 | menuItem add(t, center, x); 60 | 61 | opts.push_back(add); 62 | 63 | delete[] tmp; 64 | } 65 | 66 | void menu::addItem(const std::u16string a) 67 | { 68 | char32_t *tmp = new char32_t[128]; 69 | memset(tmp, 0, sizeof(char32_t) * 128); 70 | utf16_to_utf32((uint32_t *)tmp, (uint16_t *)a.data(), 128); 71 | 72 | std::u32string t; 73 | t.assign(tmp); 74 | 75 | menuItem add(t, center, x); 76 | 77 | opts.push_back(add); 78 | 79 | delete[] tmp; 80 | } 81 | 82 | void menu::updateItem(int i, const char *a) 83 | { 84 | char32_t tmp[128]; 85 | memset(tmp, 0, 128); 86 | 87 | utf8_to_utf32((uint32_t *)tmp, (uint8_t *)a, 128); 88 | 89 | menuItem update(tmp, center, x); 90 | 91 | opts[i] = update; 92 | } 93 | 94 | void menu::draw() 95 | { 96 | int i, length; 97 | 98 | //Set length for printing 99 | if((opts.size() - 1) < 15) 100 | length = opts.size(); 101 | else 102 | //Scrolling needs start set 103 | length = start + 15; 104 | 105 | for(i = start; i < length; i++) 106 | { 107 | if(i == selected) 108 | { 109 | opts[i].draw(y + ((i - start) * 14), RGBA8(selColor[0], selColor[1], selColor[2], 255)); 110 | } 111 | else if(opts[i].selected) 112 | opts[i].draw(y + ((i - start) * 14), RGBA8(200, 0, 0, 255)); 113 | else 114 | opts[i].draw(y + ((i - start) * 14), RGBA8(unSelColor[0], unSelColor[1], unSelColor[2], 255)); 115 | } 116 | 117 | } 118 | 119 | void menu::handleInput(u32 key, u32 held) 120 | { 121 | //Honestly. I don't even know anymore. 122 | //I stopped touching this. It works, but it's a mess. 123 | 124 | //keep frame count for scrolling 125 | if( (held & KEY_UP) || (held & KEY_DOWN)) 126 | fc++; 127 | else 128 | fc = 0; 129 | if(fc > 10) 130 | fc = 0; 131 | 132 | int size = opts.size() - 1; 133 | if((key & KEY_UP) || ((held & KEY_UP) && fc == 10)) 134 | { 135 | selected--; 136 | if(selected < 0) 137 | selected = size; 138 | 139 | if((start > selected) && (start > 0)) 140 | start--; 141 | if(size < 15) 142 | start = 0; 143 | else if(selected == size && size > 15) 144 | start = size - 14; 145 | } 146 | else if((key & KEY_DOWN) || ((held & KEY_DOWN) && fc == 10)) 147 | { 148 | selected++; 149 | if(selected > size) 150 | selected = 0; 151 | 152 | if((selected > (start + 14)) && ((start + 14) < size)) 153 | start++; 154 | if(selected == 0) 155 | start = 0; 156 | } 157 | else if(key & KEY_RIGHT) 158 | { 159 | selected += 7; 160 | if(selected > size) 161 | selected = size; 162 | if((selected - 14) > start) 163 | start = selected - 14; 164 | } 165 | else if(key & KEY_LEFT) 166 | { 167 | selected -= 7; 168 | if(selected < 0) 169 | selected = 0; 170 | if(selected < start) 171 | start = selected; 172 | } 173 | else if((key & KEY_L) && multi) 174 | { 175 | if(opts[selected].selected) 176 | opts[selected].selected = false; 177 | else 178 | opts[selected].selected = true; 179 | } 180 | else if((key & KEY_R) && multi) 181 | { 182 | if(opts[0].selected && opts[1].selected) 183 | { 184 | for(unsigned i = 0; i < opts.size(); i++) 185 | opts[i].selected = false; 186 | } 187 | else 188 | { 189 | for(unsigned i = 0; i < opts.size(); i++) 190 | opts[i].selected = true; 191 | } 192 | } 193 | 194 | } 195 | 196 | void menu::reset() 197 | { 198 | selected = 0; 199 | start = 0; 200 | opts.clear(); 201 | } 202 | 203 | void menu::centerOpts() 204 | { 205 | for(unsigned i = 0; i < opts.size(); i++) 206 | opts[i].autoCenter(); 207 | } 208 | 209 | void menu::autoVert() 210 | { 211 | 212 | unsigned usedVert; 213 | if(getSize() > 15) 214 | usedVert = 15 * 14; 215 | else 216 | usedVert = getSize() * 14; 217 | y = 16 + (224 / 2) - (usedVert / 2); 218 | } 219 | 220 | int menu::getSelected() 221 | { 222 | return selected; 223 | } 224 | 225 | void menu::setSelected(int sel) 226 | { 227 | selected = sel; 228 | } 229 | 230 | unsigned menu::getSize() 231 | { 232 | return opts.size(); 233 | } 234 | 235 | unsigned menu::getSelectCount() 236 | { 237 | unsigned ret = 0; 238 | for(unsigned i = 0; i < opts.size(); i++) 239 | { 240 | if(opts[i].selected) 241 | ret++; 242 | } 243 | 244 | return ret; 245 | } 246 | 247 | bool menu::optSelected(int i) 248 | { 249 | return opts[i].selected; 250 | } 251 | -------------------------------------------------------------------------------- /source/nand.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "titles.h" 8 | #include "nand.h" 9 | #include "backup.h" 10 | #include "restore.h" 11 | #include "util.h" 12 | #include "ui.h" 13 | #include "global.h" 14 | #include "menu.h" 15 | #include "titledata.h" 16 | #include "archive.h" 17 | 18 | titleData * sysTitle = NULL; 19 | 20 | static menu nandMenu(40, 20, false, false); 21 | 22 | void prepNandSelect() 23 | { 24 | for(unsigned i = 0; i < nandTitle.size(); i++) 25 | nandMenu.addItem(nandTitle[i].name); 26 | if(centered) 27 | nandMenu.centerOpts(); 28 | 29 | nandMenu.autoVert(); 30 | } 31 | 32 | void nandStartSelect() 33 | { 34 | hidScanInput(); 35 | 36 | u32 down = hidKeysDown(); 37 | u32 held = hidKeysHeld(); 38 | 39 | nandMenu.handleInput(down, held); 40 | 41 | if(down & KEY_A) 42 | { 43 | sysTitle = &nandTitle[nandMenu.getSelected()]; 44 | state = STATE_NANDBACKUP; 45 | } 46 | else if(down & KEY_B) 47 | state = STATE_MAINMENU; 48 | 49 | killApp(down); 50 | 51 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 52 | nandMenu.draw(); 53 | drawTopBar(U"Select System Title"); 54 | sf2d_end_frame(); 55 | 56 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 57 | nandTitle[nandMenu.getSelected()].printInfo(); 58 | sf2d_end_frame(); 59 | 60 | sf2d_swapbuffers(); 61 | } 62 | 63 | enum sysOpts 64 | { 65 | expSys, 66 | impSys, 67 | expExt, 68 | impExt, 69 | expBoss, 70 | impBoss, 71 | back 72 | }; 73 | 74 | static menu nBackupMenu(112, 72, false, true); 75 | 76 | void prepNandBackup() 77 | { 78 | nBackupMenu.addItem("Export System Save"); 79 | nBackupMenu.addItem("Import System Save"); 80 | nBackupMenu.addItem("Export ExtData"); 81 | nBackupMenu.addItem("Import ExtData"); 82 | nBackupMenu.addItem("Export Boss ExtData"); 83 | nBackupMenu.addItem("Import Boss ExtData"); 84 | nBackupMenu.addItem("Back"); 85 | 86 | nBackupMenu.autoVert(); 87 | } 88 | 89 | void nandBackup() 90 | { 91 | std::u32string info = tou32(sysTitle->name) + U" : NAND"; 92 | 93 | hidScanInput(); 94 | 95 | u32 down = hidKeysDown(); 96 | 97 | nBackupMenu.handleInput(down, 0); 98 | 99 | if(down & KEY_A) 100 | { 101 | FS_Archive arch; 102 | switch(nBackupMenu.getSelected()) 103 | { 104 | case sysOpts::expSys: 105 | if(openSysSave(&arch, *sysTitle)) 106 | { 107 | renameDir(*sysTitle); 108 | createTitleDir(*sysTitle, MODE_SYSSAVE); 109 | backupData(*sysTitle, arch, MODE_SYSSAVE, false); 110 | } 111 | break; 112 | case sysOpts::impSys: 113 | if(openSysSave(&arch, *sysTitle)) 114 | { 115 | restoreData(*sysTitle, arch, MODE_SYSSAVE); 116 | } 117 | break; 118 | case sysOpts::expExt: 119 | if(openExtdata(&arch, *sysTitle, true)) 120 | { 121 | renameDir(*sysTitle); 122 | createTitleDir(*sysTitle, MODE_EXTDATA); 123 | backupData(*sysTitle, arch, MODE_EXTDATA, false); 124 | } 125 | break; 126 | case sysOpts::impExt: 127 | if(openExtdata(&arch, *sysTitle, true)) 128 | { 129 | restoreData(*sysTitle, arch, MODE_EXTDATA); 130 | } 131 | break; 132 | case sysOpts::expBoss: 133 | if(openBossExt(&arch, *sysTitle)) 134 | { 135 | renameDir(*sysTitle); 136 | createTitleDir(*sysTitle, MODE_BOSS); 137 | backupData(*sysTitle, arch, MODE_BOSS, false); 138 | } 139 | break; 140 | case sysOpts::impBoss: 141 | if(openBossExt(&arch, *sysTitle)) 142 | { 143 | restoreData(*sysTitle, arch, MODE_BOSS); 144 | } 145 | break; 146 | case sysOpts::back: 147 | state = states::STATE_NANDSELECT; 148 | break; 149 | } 150 | FSUSER_CloseArchive(arch); 151 | } 152 | else if(down & KEY_B) 153 | state = states::STATE_NANDSELECT; 154 | 155 | killApp(down); 156 | 157 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 158 | drawTopBar(info); 159 | nBackupMenu.draw(); 160 | sf2d_end_frame(); 161 | 162 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 163 | sf2d_end_frame(); 164 | 165 | sf2d_swapbuffers(); 166 | 167 | 168 | } 169 | -------------------------------------------------------------------------------- /source/progBar.c: -------------------------------------------------------------------------------- 1 | //1000 2 | unsigned char progBarData[] = { 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xB5, 12 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 13 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 14 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 15 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0x59, 0xDC, 0xDC, 0xDC, 0x0C, 16 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 17 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 18 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 28 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 29 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 30 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 31 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 32 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 33 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 34 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 44 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0x59, 0xFF, 0xFF, 0xFF, 0x00, 45 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 46 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 47 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 48 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0x59, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 49 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 50 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0x83, 60 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 61 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 62 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 63 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xB5, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 64 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xF1, 0xDC, 0xDC, 0xDC, 0x59, 0xFF, 0xFF, 0xFF, 0x00, 65 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 66 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 67 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 68 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 69 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 70 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 71 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 72 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 73 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 74 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 75 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 76 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 77 | 0xDC, 0xDC, 0xDC, 0x0C, 0xDC, 0xDC, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 78 | 0xDC, 0xDC, 0xDC, 0x59, 0xDC, 0xDC, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 79 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 80 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 81 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 82 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xDC, 0xDC, 0xDC, 0x59, 83 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 84 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 85 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 86 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 87 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 88 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 89 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 90 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 91 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 92 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 93 | 0xDC, 0xDC, 0xDC, 0xB5, 0xDC, 0xDC, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 94 | 0xDC, 0xDC, 0xDC, 0xF1, 0xDC, 0xDC, 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xDC, 0xDC, 0xDC, 0x59, 95 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 96 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 97 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0x83, 0xDC, 0xDC, 0xDC, 0xFF, 98 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 99 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 100 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 101 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 102 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 103 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 104 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 105 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 106 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 107 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 108 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 109 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0x0C, 0xDC, 0xDC, 0xDC, 0x59, 110 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 111 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 112 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 113 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xB5, 0xDC, 0xDC, 0xDC, 0xF1, 114 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 115 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 116 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 117 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 118 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 119 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 120 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 121 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 122 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 123 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 124 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 125 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 126 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 127 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 128 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 129 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 130 | 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 131 | 0xFF, 0x34, 0xAB, 0x00, 0xFF, 0x35, 0xAB, 0x00, 0xFF, 0x34, 0xAB, 0x00, 0xFF, 0x34, 0xAB, 0x00, 132 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133 | 0xFF, 0x34, 0xAB, 0x00, 0xFF, 0x34, 0xAB, 0x00, 0xFF, 0x34, 0xAB, 0x00, 0xFF, 0x35, 0xAB, 0x00, 134 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 135 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 139 | 0xFF, 0x34, 0xAB, 0x00, 0xFF, 0x35, 0xAB, 0x00, 0xFF, 0x34, 0xAB, 0x00, 0xFF, 0x34, 0xAB, 0x00, 140 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 141 | 0xFF, 0x34, 0xAC, 0x00, 0xFF, 0x34, 0xAC, 0x00, 0xFF, 0x32, 0xB1, 0x00, 0xFF, 0x32, 0xB1, 0x00, 142 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 143 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 144 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 145 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 146 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 147 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 148 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 149 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 150 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 151 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 152 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 153 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 154 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 155 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 156 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 157 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 159 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 160 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 161 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 162 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 163 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 165 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 170 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 172 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 173 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 174 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 175 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 176 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 177 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 178 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 179 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 182 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 183 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 184 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 185 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 186 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 187 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 188 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 189 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 190 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 191 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 192 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 193 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 194 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 195 | 0xFF, 0x2F, 0xB7, 0x00, 0xFF, 0x30, 0xB6, 0x00, 0xFF, 0x2D, 0xBC, 0x00, 0xFF, 0x2D, 0xBB, 0x00, 196 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 197 | 0xFF, 0x2B, 0xC2, 0x00, 0xFF, 0x2B, 0xC1, 0x00, 0xFF, 0x28, 0xC7, 0x00, 0xFF, 0x29, 0xC7, 0x00, 198 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 200 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 201 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 202 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 203 | 0xFF, 0x26, 0xCC, 0x00, 0xFF, 0x26, 0xCC, 0x00, 0xFF, 0x24, 0xD1, 0x00, 0xFF, 0x24, 0xD1, 0x00, 204 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 205 | 0xFF, 0x21, 0xD6, 0x00, 0xFF, 0x21, 0xD7, 0x00, 0xFF, 0x1F, 0xDC, 0x00, 0xFF, 0x1F, 0xDC, 0x00, 206 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 207 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 208 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 209 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 210 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 211 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 212 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 213 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 214 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 215 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 216 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 217 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 220 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 221 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 222 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 223 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 224 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 225 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 226 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 227 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 228 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 229 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 230 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 233 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 234 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 237 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 238 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 241 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 242 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 243 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 244 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 245 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 246 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 247 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 248 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 249 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 250 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 252 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 254 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 255 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 258 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 259 | }; 260 | -------------------------------------------------------------------------------- /source/restore.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | 6 | #include "restore.h" 7 | #include "backup.h" 8 | #include "archive.h" 9 | #include "slot.h" 10 | #include "global.h" 11 | #include "util.h" 12 | #include "ui.h" 13 | #include "sdpath.h" 14 | #include "file.h" 15 | #include "titles.h" 16 | #include "archive.h" 17 | 18 | void copyFiletoArch(FS_Archive arch, const std::u16string from, const std::u16string to, int mode) 19 | { 20 | fsFile in(sdArch, from, FS_OPEN_READ); 21 | fsFile out(arch, to, FS_OPEN_WRITE, in.size()); 22 | 23 | u8 *buff = new u8[buff_size]; 24 | std::string copyString = "Copying " + toString(from) + "..."; 25 | progressBar fileProg((float)in.size(), copyString.c_str(), "Copying File"); 26 | u32 read, written; 27 | do 28 | { 29 | in.read(buff, &read, buff_size); 30 | out.write(buff, &written, read); 31 | if(written != read) 32 | { 33 | showMessage("Something went wrong writing to the archive file!", "UH OH!"); 34 | break; 35 | } 36 | 37 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 38 | fileProg.draw(in.getOffset()); 39 | sf2d_end_frame(); 40 | 41 | sf2d_swapbuffers(); 42 | } 43 | while(!in.eof()); 44 | 45 | delete[] buff; 46 | 47 | in.close(); 48 | out.close(); 49 | } 50 | 51 | void copyDirToArch(FS_Archive arch, const std::u16string from, const std::u16string to, int mode) 52 | { 53 | dirList list(sdArch, from); 54 | for(unsigned i = 0; i < list.count(); i++) 55 | { 56 | if(list.isDir(i)) 57 | { 58 | std::u16string newFrom = from + list.retItem(i) + (char16_t)'/'; 59 | 60 | std::u16string newTo = to + list.retItem(i); 61 | FSUSER_CreateDirectory(arch, fsMakePath(PATH_UTF16, newTo.data()), 0); 62 | newTo += L'/'; 63 | 64 | copyDirToArch(arch, newFrom, newTo, mode); 65 | } 66 | else 67 | { 68 | std::u16string sdPath = from + list.retItem(i); 69 | 70 | std::u16string archPath = to + list.retItem(i); 71 | 72 | copyFiletoArch(arch, sdPath, archPath, mode); 73 | } 74 | } 75 | } 76 | 77 | bool restoreData(const titleData dat, FS_Archive arch, int mode) 78 | { 79 | std::u16string sdPath; 80 | 81 | std::u16string keepName = getFolder(dat, mode, false); 82 | if(keepName.empty()) 83 | return false; 84 | 85 | std::string ask = "Are you sure you want to import " + toString(keepName) + "?"; 86 | if(!confirm(ask.c_str())) 87 | return false; 88 | 89 | if(autoBack) 90 | backupData(dat, arch, mode, true); 91 | 92 | sdPath = getPath(mode) + dat.nameSafe + (char16_t)'/' + keepName + (char16_t)'/'; 93 | 94 | std::u16string archPath = (char16_t *)"/"; 95 | 96 | if(!modeExtdata(mode)) 97 | FSUSER_DeleteDirectoryRecursively(arch, fsMakePath(PATH_ASCII, "/")); 98 | 99 | 100 | copyDirToArch(arch, sdPath, archPath, mode); 101 | 102 | //If we're not restoring some kind of extdata, commit save data 103 | if(!modeExtdata(mode)) 104 | { 105 | fsCommitData(arch); 106 | //If we're running under something from the hbl, end the session, delete the SV and start it again. 107 | if(hbl) 108 | fsEnd(); 109 | 110 | deleteSV(dat); 111 | 112 | if(hbl) 113 | fsStart(); 114 | } 115 | 116 | 117 | showMessage("Finished", "Success!"); 118 | 119 | return true; 120 | } 121 | 122 | bool restoreDataSDPath(const titleData dat, FS_Archive arch, int mode) 123 | { 124 | std::u16string sdPath = getSDPath(); 125 | if(sdPath.length() < 2) 126 | return false; 127 | 128 | std::u16string archPath = (char16_t *)"/"; 129 | 130 | if(!modeExtdata(mode)) 131 | FSUSER_DeleteDirectoryRecursively(arch, fsMakePath(PATH_ASCII, "/")); 132 | 133 | if(autoBack) 134 | backupData(dat, arch, mode, true); 135 | 136 | copyDirToArch(arch, sdPath, archPath, mode); 137 | 138 | if(!modeExtdata(mode)) 139 | { 140 | fsCommitData(arch); 141 | 142 | if(hbl) 143 | fsEnd(); 144 | 145 | deleteSV(dat); 146 | 147 | if(hbl) 148 | fsStart(); 149 | } 150 | 151 | showMessage("Finished!", "Success!"); 152 | 153 | return true; 154 | } 155 | 156 | void autoRestore(menu m) 157 | { 158 | //This still needs user input. 159 | for(unsigned i = 0; i < m.getSize(); i++) 160 | { 161 | FS_Archive saveArch; 162 | if(m.optSelected(i) && openSaveArch(&saveArch, sdTitle[i], false)) 163 | restoreData(sdTitle[i], saveArch, MODE_SAVE); 164 | FSUSER_CloseArchive(saveArch); 165 | 166 | FS_Archive extArch; 167 | if(m.optSelected(i) && openExtdata(&extArch, sdTitle[i], false)) 168 | restoreData(sdTitle[i], extArch, MODE_EXTDATA); 169 | FSUSER_CloseArchive(extArch); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /source/savemenu.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "savemenu.h" 8 | #include "archive.h" 9 | #include "backup.h" 10 | #include "restore.h" 11 | #include "menu.h" 12 | #include "titledata.h" 13 | #include "global.h" 14 | #include "ui.h" 15 | #include "util.h" 16 | 17 | #include "file.h" 18 | 19 | enum saveOpts 20 | { 21 | expSav, 22 | impSav, 23 | browseSav, 24 | delSV, 25 | delSav, 26 | back, 27 | fun 28 | }; 29 | 30 | static menu saveMenu(128, 80, false, true); 31 | 32 | void prepSaveMenu() 33 | { 34 | saveMenu.addItem("Export Save"); 35 | saveMenu.addItem("Import Save"); 36 | saveMenu.addItem("Browse SD for Data"); 37 | saveMenu.addItem("Delete Secure Value"); 38 | saveMenu.addItem("Delete Save Data"); 39 | saveMenu.addItem("Back"); 40 | 41 | saveMenu.autoVert(); 42 | } 43 | 44 | void showSaveMenu() 45 | { 46 | std::u32string info = curTitle->u32Name + U" : Save Data"; 47 | 48 | hidScanInput(); 49 | 50 | u32 down = hidKeysDown(); 51 | 52 | touchPosition p; 53 | hidTouchRead(&p); 54 | 55 | saveMenu.handleInput(down, 0); 56 | 57 | if(down & KEY_A) 58 | { 59 | FS_Archive saveArch; 60 | switch(saveMenu.getSelected()) 61 | { 62 | case saveOpts::expSav: 63 | if(openSaveArch(&saveArch, *curTitle, true)) 64 | { 65 | createTitleDir(*curTitle, MODE_SAVE); 66 | backupData(*curTitle, saveArch, MODE_SAVE, false); 67 | } 68 | break; 69 | case saveOpts::impSav: 70 | if(openSaveArch(&saveArch, *curTitle, true)) 71 | restoreData(*curTitle, saveArch, MODE_SAVE); 72 | break; 73 | case saveOpts::browseSav: 74 | if(openSaveArch(&saveArch, *curTitle, true)) 75 | restoreDataSDPath(*curTitle, saveArch, MODE_SAVE); 76 | break; 77 | case saveOpts::delSV: 78 | if(deleteSV(*curTitle)) 79 | showMessage("Secure value successfully deleted!", "Success!"); 80 | break; 81 | case saveOpts::delSav: 82 | if(openSaveArch(&saveArch, *curTitle, true) && confirm("Are you sure you want to delete this title's current save data?")) 83 | { 84 | FSUSER_DeleteDirectoryRecursively(saveArch, fsMakePath(PATH_ASCII, "/")); 85 | FSUSER_ControlArchive(saveArch, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0); 86 | } 87 | break; 88 | case saveOpts::back: 89 | state = STATE_BACKUPMENU; 90 | break; 91 | } 92 | FSUSER_CloseArchive(saveArch); 93 | } 94 | else if(down & KEY_B) 95 | { 96 | state = STATE_BACKUPMENU; 97 | } 98 | 99 | killApp(down); 100 | 101 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 102 | drawTopBar(info); 103 | saveMenu.draw(); 104 | sf2d_end_frame(); 105 | 106 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 107 | sf2d_end_frame(); 108 | 109 | sf2d_swapbuffers(); 110 | } 111 | -------------------------------------------------------------------------------- /source/sd_cia.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "titles.h" 9 | #include "menu.h" 10 | #include "global.h" 11 | #include "util.h" 12 | #include "ui.h" 13 | #include "backup.h" 14 | #include "restore.h" 15 | 16 | const std::string helpText = "Press L to select multiple. Press R to select all. Press Y to backup selected. Press X to restore selected."; 17 | 18 | //Help button 19 | static button help("Help", 224, 208, 96, 32); 20 | 21 | static menu titleMenu(40, 20, true, false); 22 | 23 | void prepSDSelect() 24 | { 25 | titleMenu.reset(); 26 | for(unsigned i = 0; i < sdTitle.size(); i++) 27 | titleMenu.addItem(sdTitle[i].name); 28 | if(centered) 29 | titleMenu.centerOpts(); 30 | 31 | titleMenu.autoVert(); 32 | } 33 | 34 | void cartCheck() 35 | { 36 | bool ins = false; 37 | FSUSER_CardSlotIsInserted(&ins); 38 | if(ins && sdTitle[0].media == MEDIATYPE_SD) 39 | { 40 | uint64_t cardId = 0; 41 | AM_GetTitleList(NULL, MEDIATYPE_GAME_CARD, 1, &cardId); 42 | titleData cardData; 43 | if(cardData.init(cardId, MEDIATYPE_GAME_CARD)) 44 | { 45 | sdTitle.insert(sdTitle.begin(), cardData); 46 | prepSDSelect(); 47 | } 48 | } 49 | else if(!ins && sdTitle[0].media == MEDIATYPE_GAME_CARD) 50 | { 51 | sdTitle.erase(sdTitle.begin(), sdTitle.begin() + 1); 52 | prepSDSelect(); 53 | } 54 | } 55 | 56 | void sdStartSelect() 57 | { 58 | cartCheck(); 59 | if(sdTitle.size() < 1) 60 | { 61 | showMessage("No installed titles were found!", "Nope..."); 62 | state = states::STATE_MAINMENU; 63 | return; 64 | } 65 | 66 | hidScanInput(); 67 | 68 | u32 down = hidKeysDown(); 69 | u32 held = hidKeysHeld(); 70 | 71 | titleMenu.handleInput(down, held); 72 | 73 | touchPosition pos; 74 | hidTouchRead(&pos); 75 | 76 | if(down & KEY_A) 77 | { 78 | unsigned selected = titleMenu.getSelected(); 79 | curTitle = &sdTitle[selected]; 80 | renameDir(sdTitle[selected]); 81 | prevState = states::STATE_TITLEMENU; 82 | state = states::STATE_BACKUPMENU; 83 | } 84 | else if(help.released(pos)) 85 | { 86 | showMessage(helpText.c_str(), "Help"); 87 | } 88 | else if(down & KEY_Y) 89 | { 90 | autoBackup(titleMenu); 91 | } 92 | else if(down & KEY_X) 93 | { 94 | autoRestore(titleMenu); 95 | } 96 | else if(down & KEY_B) 97 | state = states::STATE_MAINMENU; 98 | 99 | killApp(down); 100 | 101 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 102 | drawTopBar(U"Select a title"); 103 | titleMenu.draw(); 104 | sf2d_end_frame(); 105 | 106 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 107 | sdTitle[titleMenu.getSelected()].printInfo(); 108 | help.draw(); 109 | sf2d_end_frame(); 110 | 111 | sf2d_swapbuffers(); 112 | } 113 | -------------------------------------------------------------------------------- /source/sdpath.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | 4 | #include "sdpath.h" 5 | #include "menu.h" 6 | #include "global.h" 7 | #include "util.h" 8 | #include "ui.h" 9 | #include "file.h" 10 | 11 | void copyListToMenu(menu *m, dirList d) 12 | { 13 | m->reset(); 14 | 15 | m->addItem(".."); 16 | for(unsigned i = 0; i < d.count(); i++) 17 | m->addItem(d.retItem(i)); 18 | } 19 | 20 | void enterDir(dirList *d, menu *m, std::u16string *path) 21 | { 22 | path->append(d->retItem(m->getSelected() - 1)); 23 | path->append((char16_t *)"/"); 24 | 25 | d->reassign(*path); 26 | 27 | m->reset(); 28 | 29 | copyListToMenu(m, *d); 30 | } 31 | 32 | void upDir(dirList *d, menu *m, std::u16string *path) 33 | { 34 | if(path->length() < 2) 35 | return; 36 | 37 | unsigned i; 38 | for(i = (path->length() - 2); i > 0; i--) 39 | { 40 | if(path->c_str()[i] == L'/') 41 | break; 42 | } 43 | path->assign(*path, 0, i + 1); 44 | 45 | m->reset(); 46 | 47 | d->reassign(*path); 48 | 49 | copyListToMenu(m, *d); 50 | } 51 | 52 | std::u16string getSDPath() 53 | { 54 | //Current path on SD 55 | std::u16string cPath = (char16_t *)"/"; 56 | 57 | //Menu for browsing 58 | menu sdBrowse(8, 16, false, false); 59 | 60 | //get listing and copy to sdBrowse 61 | dirList sdList(sdArch, cPath); 62 | copyListToMenu(&sdBrowse, sdList); 63 | 64 | button help("Help", 224, 208, 96, 32); 65 | std::string helpText = "Locate directory containing the save files you want to import. Press Y when finished. Press X to cancel. "; 66 | 67 | while(1) 68 | { 69 | hidScanInput(); 70 | 71 | u32 down = hidKeysDown(); 72 | u32 held = hidKeysHeld(); 73 | 74 | sdBrowse.handleInput(down, held); 75 | 76 | touchPosition p; 77 | hidTouchRead(&p); 78 | 79 | if(down & KEY_A) 80 | { 81 | unsigned sel = sdBrowse.getSelected(); 82 | if(sel == 0) 83 | upDir(&sdList, &sdBrowse, &cPath); 84 | else if(sdList.isDir(sel - 1)) 85 | enterDir(&sdList, &sdBrowse, &cPath); 86 | } 87 | else if(down & KEY_B) 88 | upDir(&sdList, &sdBrowse, &cPath); 89 | else if(down & KEY_Y) 90 | { 91 | if(sdList.isDir(sdBrowse.getSelected() - 1) && confirm("Use this directory to restore? Everything in it will be copied to current game's save archive. ")) 92 | { 93 | cPath += sdList.retItem(sdBrowse.getSelected() - 1); 94 | cPath += L'/'; 95 | break; 96 | } 97 | } 98 | else if(down & KEY_X) 99 | { 100 | cPath = (char16_t *)""; 101 | break; 102 | } 103 | else if(help.released(p)) 104 | showMessage(helpText.c_str(), "Help"); 105 | 106 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 107 | sftd_draw_text(font, 0, 0, RGBA8(255, 255, 255, 255), 12, toString(cPath).c_str()); 108 | sdBrowse.draw(); 109 | help.draw(); 110 | sf2d_end_frame(); 111 | 112 | sf2d_swapbuffers(); 113 | } 114 | 115 | return cPath; 116 | } 117 | -------------------------------------------------------------------------------- /source/shared.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | 4 | #include "shared.h" 5 | #include "archive.h" 6 | #include "backup.h" 7 | #include "restore.h" 8 | #include "global.h" 9 | #include "menu.h" 10 | #include "util.h" 11 | #include "ui.h" 12 | 13 | //I stole these from 3dbrew. Kill me. 14 | std::string descs[] = 15 | { 16 | "From 3DBrew.org: Home Menu attempts to open this archive during boot, if FS:OpenArchive doesn't return an error Home Menu seems to then launch the System Transfer application. Home Menu doesn't actually use this archive at all except for checking whether it exists.", 17 | "From 3DBrew.org: NAND JPEG/MPO files and phtcache.bin from the camera application are stored here. This also contains UploadData.dat. ", 18 | "From 3DBrew.org: NAND M4A files from the sound application are stored here ", 19 | "From 3DBrew.org: ???", 20 | "From 3DBrew.org: Contains idb.dat, idbt.dat, gamecoin.dat, ubll.lst, CFL_DB.dat, and CFL_OldDB.dat. These files contain cleartext Miis and some data relating (including cached ICN data) to Play/Usage Records.", 21 | "From 3DBrew.org: Contains bashotorya.dat and bashotorya2.dat.", 22 | "From 3DBrew.org: ???", 23 | "From 3DBrew.org: Contains versionlist.dat, used by Home Menu for the software update notification added with 7.0.0-13.", 24 | "This means go back." 25 | }; 26 | 27 | enum sharedOpts 28 | { 29 | e0, 30 | f1, 31 | f2, 32 | f9, 33 | fb, 34 | fc, 35 | fd, 36 | fe 37 | }; 38 | 39 | enum sharedBack 40 | { 41 | _exp, 42 | _imp, 43 | _back 44 | }; 45 | 46 | titleData selShared; 47 | 48 | static menu sharedBackMenu(136, 96, false, true); 49 | 50 | void prepSharedBackMenu() 51 | { 52 | sharedBackMenu.addItem("Export Data"); 53 | sharedBackMenu.addItem("Import Data"); 54 | sharedBackMenu.addItem("Back"); 55 | 56 | sharedBackMenu.autoVert(); 57 | } 58 | 59 | void sharedBackupMenu() 60 | { 61 | std::u32string info = tou32(selShared.nameSafe) + U" : Shared Extdata"; 62 | 63 | hidScanInput(); 64 | 65 | u32 down = hidKeysDown(); 66 | 67 | sharedBackMenu.handleInput(down, 0); 68 | 69 | if(down & KEY_A) 70 | { 71 | FS_Archive arch; 72 | switch(sharedBackMenu.getSelected()) 73 | { 74 | case sharedBack::_exp: 75 | if(openSharedExt(&arch, selShared.extdata)) 76 | { 77 | createTitleDir(selShared, MODE_SHARED); 78 | backupData(selShared, arch, MODE_SHARED, false); 79 | } 80 | break; 81 | case sharedBack::_imp: 82 | if(openSharedExt(&arch, selShared.extdata)) 83 | restoreData(selShared, arch, MODE_SHARED); 84 | break; 85 | case sharedBack::_back: 86 | state = states::STATE_SHARED; 87 | break; 88 | } 89 | FSUSER_CloseArchive(arch); 90 | } 91 | else if(down & KEY_B) 92 | state = states::STATE_SHARED; 93 | 94 | //oops forgot this last time 95 | killApp(down); 96 | 97 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 98 | drawTopBar(info); 99 | sharedBackMenu.draw(); 100 | sf2d_end_frame(); 101 | 102 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 103 | sf2d_end_frame(); 104 | 105 | sf2d_swapbuffers(); 106 | } 107 | 108 | static menu sharedMenu(128, 72, false, true); 109 | 110 | void prepSharedMenu() 111 | { 112 | sharedMenu.addItem("E0000000"); 113 | sharedMenu.addItem("F0000001"); 114 | sharedMenu.addItem("F0000002"); 115 | sharedMenu.addItem("F0000009"); 116 | sharedMenu.addItem("F000000B"); 117 | sharedMenu.addItem("F000000C"); 118 | sharedMenu.addItem("F000000D"); 119 | sharedMenu.addItem("F000000E"); 120 | 121 | sharedMenu.autoVert(); 122 | } 123 | 124 | void sharedExtManager() 125 | { 126 | std::u32string info = U"Shared ExtData"; 127 | 128 | hidScanInput(); 129 | 130 | u32 down = hidKeysDown(); 131 | u32 held = hidKeysHeld(); 132 | 133 | sharedMenu.handleInput(down, held); 134 | 135 | if(down & KEY_A) 136 | { 137 | titleData sharedDat; 138 | switch(sharedMenu.getSelected()) 139 | { 140 | case sharedOpts::e0: 141 | sharedDat.extdata = 0xE0000000; 142 | sharedDat.nameSafe = tou16("E0000000"); 143 | break; 144 | case sharedOpts::f1: 145 | sharedDat.extdata = 0xF0000001; 146 | sharedDat.nameSafe = tou16("F0000001"); 147 | break; 148 | case sharedOpts::f2: 149 | sharedDat.extdata = 0xF0000002; 150 | sharedDat.nameSafe = tou16("F0000002"); 151 | break; 152 | case sharedOpts::f9: 153 | sharedDat.extdata = 0xF0000009; 154 | sharedDat.nameSafe = tou16("F0000009"); 155 | break; 156 | case sharedOpts::fb: 157 | sharedDat.extdata = 0xF000000B; 158 | sharedDat.nameSafe = tou16("F000000B"); 159 | break; 160 | case sharedOpts::fc: 161 | sharedDat.extdata = 0xF000000C; 162 | sharedDat.nameSafe = tou16("F000000C"); 163 | break; 164 | case sharedOpts::fd: 165 | sharedDat.extdata = 0xF000000D; 166 | sharedDat.nameSafe = tou16("F000000D"); 167 | break; 168 | case sharedOpts::fe: 169 | sharedDat.extdata = 0xF000000E; 170 | sharedDat.nameSafe = tou16("F000000E"); 171 | break; 172 | } 173 | selShared = sharedDat; 174 | state = states::STATE_SHAREDBACKUP; 175 | } 176 | else if(down & KEY_B) 177 | state = states::STATE_MAINMENU; 178 | 179 | killApp(down); 180 | 181 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 182 | drawTopBar(info); 183 | sharedMenu.draw(); 184 | sf2d_end_frame(); 185 | 186 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 187 | sftd_draw_text_wrap(font, 0, 0, RGBA8(255, 255, 255, 255), 12, 320, descs[sharedMenu.getSelected()].c_str()); 188 | sf2d_end_frame(); 189 | 190 | sf2d_swapbuffers(); 191 | } 192 | -------------------------------------------------------------------------------- /source/slot.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "slot.h" 8 | #include "titledata.h" 9 | #include "gstr.h" 10 | #include "menu.h" 11 | #include "global.h" 12 | #include "util.h" 13 | #include "ui.h" 14 | #include "sdpath.h" 15 | #include "file.h" 16 | 17 | void reinitDirMenu(menu *m, dirList *dir, std::u16string path, bool newFolder) 18 | { 19 | m->reset(); 20 | dir->reassign(path); 21 | 22 | for(u32 i = 0; i < dir->count(); i++) 23 | m->addItem(dir->retItem(i)); 24 | if(newFolder) 25 | m->addItem("New"); 26 | if(centered) 27 | m->centerOpts(); 28 | } 29 | 30 | std::u16string getFolder(const titleData dat, int mode, bool newFolder) 31 | { 32 | std::u16string ret; 33 | std::u16string path = getPath(mode) + dat.nameSafe + (char16_t)'/'; 34 | 35 | dirList dir(sdArch, path); 36 | if(dir.count() == 0 && !newFolder) 37 | { 38 | showMessage("Didn't find any data to import!", "Nope"); 39 | return ret; 40 | } 41 | 42 | menu folderMenu(40, 20, false, centered); 43 | for(unsigned i = 0; i < dir.count(); i++) 44 | folderMenu.addItem(dir.retItem(i)); 45 | if(newFolder) 46 | folderMenu.addItem("New"); 47 | if(centered) 48 | folderMenu.centerOpts(); 49 | 50 | while(true) 51 | { 52 | hidScanInput(); 53 | 54 | u32 down, held; 55 | down = hidKeysDown(); 56 | held = hidKeysHeld(); 57 | 58 | folderMenu.handleInput(down, held); 59 | 60 | if( (down & KEY_A) && ((u32)folderMenu.getSelected() + 1 > dir.count())) 61 | { 62 | ret = tou16(GetString("Enter a name for the new folder.").c_str()); 63 | break; 64 | } 65 | else if(down & KEY_A) 66 | { 67 | ret = dir.retItem(folderMenu.getSelected()); 68 | break; 69 | } 70 | else if(down & KEY_X) 71 | { 72 | std::u16string newName = tou16(GetString("Enter a new name.").c_str()); 73 | if(!newName.empty() && (u32)folderMenu.getSelected() < dir.count()) 74 | { 75 | std::u16string oldPath = path + dir.retItem(folderMenu.getSelected()); 76 | std::u16string newPath = path + newName; 77 | 78 | FSUSER_RenameDirectory(sdArch, fsMakePath(PATH_UTF16, oldPath.data()), sdArch, fsMakePath(PATH_UTF16, newPath.data())); 79 | 80 | reinitDirMenu(&folderMenu, &dir, path, newFolder); 81 | } 82 | } 83 | else if(down & KEY_Y) 84 | { 85 | std::string confString = "Are you sure you want to delete '" + toString(dir.retItem(folderMenu.getSelected())) + "'?"; 86 | if(confirm(confString.c_str())) 87 | { 88 | std::u16string delPath = path + dir.retItem(folderMenu.getSelected()); 89 | 90 | FSUSER_DeleteDirectoryRecursively(sdArch, fsMakePath(PATH_UTF16, delPath.data())); 91 | 92 | reinitDirMenu(&folderMenu, &dir, path, newFolder); 93 | if(dir.count() == 0 && !newFolder) 94 | break; 95 | } 96 | } 97 | else if(down & KEY_B) 98 | break; 99 | 100 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 101 | drawTopBar(U"Select a folder. X = Rename, Y = Delete"); 102 | folderMenu.draw(); 103 | sf2d_end_frame(); 104 | 105 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 106 | sf2d_end_frame(); 107 | 108 | sf2d_swapbuffers(); 109 | } 110 | 111 | return ret; 112 | } 113 | -------------------------------------------------------------------------------- /source/smdh.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | 6 | #include "smdh.h" 7 | #include "global.h" 8 | #include "file.h" 9 | #include "ui.h" 10 | 11 | //Pretty much stolen from the hbl 12 | /*smdh_s *loadSMDH(u32 Low, u32 High, u8 Media) 13 | { 14 | smdh_s *ret = new smdh_s; 15 | u32 archPath[] = {Low, High, Media, 0x0}; 16 | static const u32 filePath[] = { 0x0, 0x0, 0x2, 0x6E6F6369, 0x0}; 17 | 18 | FS_Path binArchPath = {PATH_BINARY, 0x10, archPath}; 19 | FS_Path binFilePath = {PATH_BINARY, 0x14, filePath}; 20 | 21 | fsFile smdh(ARCHIVE_SAVEDATA_AND_CONTENT, binArchPath, binFilePath, FS_OPEN_READ); 22 | if(smdh.isOpened() && (smdh.read(ret, NULL, sizeof(smdh_s)) == 0)) 23 | { 24 | smdh.close(); 25 | return ret; 26 | } 27 | else 28 | { 29 | smdh.close(); 30 | delete ret; 31 | return NULL; 32 | } 33 | }*/ 34 | 35 | smdh_s *loadSMDH(u32 Low, u32 High, u8 Media) 36 | { 37 | //Pretty much stolen from hb_menu. It's the only thing I could find with how to open this. 38 | Handle FileHandle; 39 | 40 | u32 archPath[] = {Low, High, Media, 0x0}; 41 | static const u32 filePath[] = { 0x0, 0x0, 0x2, 0x6E6F6369, 0x0}; 42 | smdh_s *Ret = new smdh_s; 43 | 44 | FS_Path binArchPath = {PATH_BINARY, 0x10, archPath}; 45 | FS_Path binFilePath = {PATH_BINARY, 0x14, filePath}; 46 | 47 | Result Res = FSUSER_OpenFileDirectly(&FileHandle, ARCHIVE_SAVEDATA_AND_CONTENT, binArchPath, binFilePath, FS_OPEN_READ, 0); 48 | if(Res == 0) 49 | { 50 | //For bytes read. 51 | u32 Read; 52 | 53 | //Read it into Out 54 | FSFILE_Read(FileHandle, &Read, 0, Ret, sizeof(smdh_s)); 55 | } 56 | else 57 | { 58 | delete Ret; 59 | Ret = NULL; 60 | } 61 | 62 | FSFILE_Close(FileHandle); 63 | return Ret; 64 | } 65 | -------------------------------------------------------------------------------- /source/sys.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "font_ttf.h" 10 | #include "global.h" 11 | #include "ui.h" 12 | #include "menu.h" 13 | #include "util.h" 14 | #include "titles.h" 15 | #include "hbfilter.h" 16 | 17 | void loadImgs() 18 | { 19 | topBarInit(); 20 | textboxInit(); 21 | progressBarInit(); 22 | } 23 | 24 | void freeImgs() 25 | { 26 | topBarExit(); 27 | textboxExit(); 28 | progressBarExit(); 29 | } 30 | 31 | void loadCol() 32 | { 33 | FILE *colBin = fopen("colBin", "rb"); 34 | 35 | fread(clearColor, 1, 3, colBin); 36 | fread(selColor, 1, 3, colBin); 37 | fread(unSelColor, 1, 3, colBin); 38 | 39 | fclose(colBin); 40 | } 41 | 42 | void loadCfg() 43 | { 44 | FILE *config = fopen("config", "rb"); 45 | 46 | centered = fgetc(config); 47 | autoBack = fgetc(config); 48 | useLang = fgetc(config); 49 | 50 | fclose(config); 51 | } 52 | 53 | //I just use this so I don't have to type so much. I'm lazy 54 | void createDir(const char *path) 55 | { 56 | FSUSER_CreateDirectory(sdArch, fsMakePath(PATH_ASCII, path), 0); 57 | } 58 | 59 | void sysInit() 60 | { 61 | romfsInit(); 62 | mkdir("/3ds/data/JKSM", 0777); 63 | chdir("/3ds/data/JKSM"); 64 | 65 | if(fexists("colBin")) 66 | loadCol(); 67 | if(fexists("config")) 68 | loadCfg(); 69 | 70 | //Start sf2d 71 | sf2d_init(); 72 | //Set clear to black 73 | sf2d_set_clear_color(RGBA8(clearColor[0], clearColor[1], clearColor[2], 255)); 74 | 75 | loadImgs(); 76 | 77 | //Start sftd 78 | sftd_init(); 79 | //Load font 80 | font = sftd_load_font_mem(font_ttf, font_ttf_size); 81 | 82 | //Start 3ds services 83 | amInit(); 84 | aptInit(); 85 | srvInit(); 86 | acInit(); 87 | cfguInit(); 88 | httpcInit(0); 89 | 90 | loadFilterList(); 91 | 92 | //Open SDMC archive 93 | Result Res = FSUSER_OpenArchive(&sdArch, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, "")); 94 | if(Res) 95 | { 96 | showError("Error opening SDMC archive", (unsigned)Res); 97 | } 98 | 99 | if(useLang) 100 | CFGU_GetSystemLanguage(&sysLanguage); 101 | 102 | createDir("/3ds/data/JKSM/Saves"); 103 | createDir("/3ds/data/JKSM/ExtData"); 104 | createDir("/3ds/data/JKSM/SysSave"); 105 | createDir("/3ds/data/JKSM/Boss"); 106 | createDir("/3ds/data/JKSM/Shared"); 107 | 108 | prepareMenus(); 109 | } 110 | 111 | void sysExit() 112 | { 113 | //Close SDMC 114 | FSUSER_CloseArchive(sdArch); 115 | 116 | //exit services 117 | amExit(); 118 | aptExit(); 119 | srvExit(); 120 | hidExit(); 121 | acExit(); 122 | cfguExit(); 123 | httpcExit(); 124 | 125 | freeImgs(); 126 | 127 | sftd_free_font(font); 128 | sftd_fini(); 129 | sf2d_fini(); 130 | romfsExit(); 131 | } 132 | -------------------------------------------------------------------------------- /source/titledata.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | 6 | #include "titledata.h" 7 | #include "global.h" 8 | #include "smdh.h" 9 | #include "util.h" 10 | 11 | u32 extdataRedirect(u32 low) 12 | { 13 | //Pokemon Y 14 | if(low == 0x00055E00) 15 | return 0x0000055D; 16 | //Pokemon OR 17 | else if(low == 0x0011C400) 18 | return 0x000011C5; 19 | //Pokemon Moon 20 | else if(low == 0x00175E00) 21 | return 0x00001648; 22 | //Fire Emblem Conquest + SE NA 23 | else if(low == 0x00179600 || low == 0x00179800) 24 | return 0x00001794; 25 | //FE Conquest + SE EURO 26 | else if(low == 0x00179700 || low == 0x0017A800) 27 | return 0x00001795; 28 | //FE If/JPN 29 | else if(low == 0x0012DD00 || low == 0x0012DE00) 30 | return 0x000012DC; 31 | 32 | return (low >> 8); 33 | } 34 | 35 | bool titleData::init(u64 _id, FS_MediaType mediaType) 36 | { 37 | id = _id; 38 | media = mediaType; 39 | 40 | //split id and setup other ids 41 | low = (u32)id; 42 | high = (u32)(id >> 32); 43 | unique = (low >> 8); 44 | 45 | //some titles use a different id for extdata 46 | extdata = extdataRedirect(low); 47 | 48 | smdh_s *smdh = loadSMDH(low, high, media); 49 | if(smdh == NULL) 50 | return false; 51 | 52 | name = (char16_t *)smdh->applicationTitles[sysLanguage].shortDescription; 53 | //Default to english if title is empty for language 54 | if(name.empty()) 55 | name = (char16_t *)smdh->applicationTitles[1].shortDescription; 56 | u32Name = tou32(name); 57 | nameSafe = safeString(name); 58 | 59 | delete smdh; 60 | 61 | //Product code 62 | char tmp[16]; 63 | AM_GetTitleProductCode(media, id, tmp); 64 | prodCode.assign(tmp); 65 | 66 | initd = true; 67 | 68 | return true; 69 | } 70 | 71 | void titleData::initId() 72 | { 73 | high = id >> 32; 74 | low = id; 75 | 76 | unique = (low >> 8); 77 | 78 | extdata = extdataRedirect(low); 79 | 80 | media = MEDIATYPE_SD; 81 | 82 | nameSafe = safeString(name); 83 | u32Name = tou32(name); 84 | 85 | initd = true; 86 | } 87 | 88 | void titleData::printInfo() 89 | { 90 | sftd_draw_textf(font, 0, 0, RGBA8(0, 255, 255, 255), 12, "High ID : %08X", high); 91 | sftd_draw_textf(font, 0, 14, RGBA8(255, 255, 0, 255), 12, "Low ID : %08X", low); 92 | sftd_draw_textf(font, 0, 28, RGBA8(0, 255, 0, 255), 12, "Prod. Code : %s", prodCode.c_str()); 93 | if(media == MEDIATYPE_GAME_CARD) 94 | sftd_draw_text(font, 0, 42, RGBA8(255, 0, 0, 255), 12, "Game Card"); 95 | else if(media == MEDIATYPE_SD) 96 | sftd_draw_text(font, 0, 42, RGBA8(255, 0, 0, 255), 12, "SD/CIA Title"); 97 | } 98 | -------------------------------------------------------------------------------- /source/titles.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "hbfilter.h" 11 | #include "titles.h" 12 | #include "db.h" 13 | #include "ui.h" 14 | #include "global.h" 15 | #include "util.h" 16 | 17 | std::vector sdTitle; 18 | std::vector nandTitle; 19 | 20 | //Not real alphabetical sorting, but close enough. 21 | struct 22 | { 23 | bool operator()(const titleData a, const titleData b) 24 | { 25 | for(unsigned i = 0; i < a.name.length(); i++) 26 | { 27 | int aChar = tolower(a.name[i]), bChar = tolower(b.name[i]); 28 | if(aChar != bChar) 29 | return aChar < bChar; 30 | } 31 | 32 | return false; 33 | } 34 | } sortTitles; 35 | 36 | bool checkHigh(u64 id) 37 | { 38 | u32 high = id >> 32; 39 | //Games + Demos 40 | return (high == 0x00040000 || high == 0x00040002); 41 | } 42 | 43 | extern void prepSDSelect(); 44 | 45 | void sdTitlesInit() 46 | { 47 | //for refresh games 48 | sdTitle.clear(); 49 | if(fexists("titles")) 50 | { 51 | FILE *read = dbOpen("titles"); 52 | 53 | //Check to make sure cache is updated since I changed it. 54 | if(dbGetRev(read) == 1) 55 | { 56 | u32 count = dbGetCount(read); 57 | sdTitle.reserve(count); 58 | 59 | for(unsigned i = 0; i < count; i++) 60 | { 61 | titleData newData = dbGetData(read); 62 | newData.media = MEDIATYPE_SD; 63 | sdTitle.push_back(newData); 64 | } 65 | 66 | fclose(read); 67 | } 68 | else 69 | { 70 | fclose(read); 71 | remove("titles"); 72 | sdTitlesInit(); 73 | } 74 | } 75 | else 76 | { 77 | //get title count for sdmc 78 | u32 count; 79 | AM_GetTitleCount(MEDIATYPE_SD, &count); 80 | sdTitle.reserve(count); 81 | 82 | //get ids 83 | u64 *ids = new u64[count]; 84 | AM_GetTitleList(NULL, MEDIATYPE_SD, count, ids); 85 | 86 | progressBar load((float)count, "Installed SD Titles...", "Loading"); 87 | for(unsigned i = 0; i < count; i++) 88 | { 89 | if( (checkHigh(ids[i]) && !hbFilter(ids[i])) || devMode) 90 | { 91 | titleData newTitle; 92 | if(newTitle.init(ids[i], MEDIATYPE_SD)) 93 | sdTitle.push_back(newTitle); 94 | } 95 | 96 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 97 | sf2d_end_frame(); 98 | 99 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 100 | load.draw((float)i); 101 | sf2d_end_frame(); 102 | 103 | sf2d_swapbuffers(); 104 | } 105 | delete[] ids; 106 | 107 | std::sort(sdTitle.begin(), sdTitle.end(), sortTitles); 108 | 109 | FILE *db = dbCreate("titles"); 110 | dbWriteCount(db, sdTitle.size(), 1); 111 | for(unsigned i = 0; i < sdTitle.size(); i++) 112 | dbWriteData(db, sdTitle[i]); 113 | fclose(db); 114 | } 115 | 116 | prepSDSelect(); 117 | } 118 | 119 | bool nandFilter(u64 id) 120 | { 121 | u32 low = (u32)id; 122 | //camera applet 123 | if(low == 0x00009002 || low == 0x00008402 || low == 0x00009902 || low == 0x0000AA02 || low == 0x0000B202) 124 | return true; 125 | 126 | return false; 127 | } 128 | 129 | void sysSaveRedirect(titleData *dat) 130 | { 131 | //this is for browser and ar games 132 | if(dat->low > 0x20000000) 133 | dat->unique = (0x0000FFFF & dat->unique); 134 | if(dat->low == 0x2002CF00) 135 | { 136 | dat->unique = 0x0000008F; 137 | dat->extdata = 0x0000008F; 138 | } 139 | } 140 | 141 | extern void prepNandSelect(); 142 | 143 | void nandTitlesInit() 144 | { 145 | nandTitle.clear(); 146 | if(fexists("nand")) 147 | { 148 | FILE *read = dbOpen("nand"); 149 | 150 | if(dbGetRev(read) == 1) 151 | { 152 | u32 count = dbGetCount(read); 153 | nandTitle.reserve(count); 154 | 155 | for(unsigned i = 0; i < count; i++) 156 | { 157 | titleData newNand = dbGetData(read); 158 | newNand.media = MEDIATYPE_NAND; 159 | sysSaveRedirect(&newNand); 160 | nandTitle.push_back(newNand); 161 | } 162 | fclose(read); 163 | } 164 | else 165 | { 166 | fclose(read); 167 | remove("nand"); 168 | nandTitlesInit(); 169 | } 170 | } 171 | else 172 | { 173 | u32 count; 174 | AM_GetTitleCount(MEDIATYPE_NAND, &count); 175 | 176 | u64 *ids = new u64[count]; 177 | AM_GetTitleList(NULL, MEDIATYPE_NAND, count, ids); 178 | 179 | progressBar load((float)count, "NAND Titles...", "Loading"); 180 | for(unsigned i = 0; i < count; i++) 181 | { 182 | if(!(nandFilter(ids[i]) && ids[i] != 0) || devMode) 183 | { 184 | titleData newData; 185 | if( (newData.init(ids[i], MEDIATYPE_NAND) && !newData.name.empty())) 186 | { 187 | sysSaveRedirect(&newData); 188 | nandTitle.push_back(newData); 189 | } 190 | } 191 | 192 | sf2d_start_frame(GFX_TOP, GFX_LEFT); 193 | sf2d_end_frame(); 194 | 195 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 196 | load.draw((float)i); 197 | sf2d_end_frame(); 198 | 199 | sf2d_swapbuffers(); 200 | } 201 | delete[] ids; 202 | 203 | std::sort(nandTitle.begin(), nandTitle.end(), sortTitles); 204 | 205 | FILE *nand = dbCreate("nand"); 206 | dbWriteCount(nand, nandTitle.size(), 1); 207 | for(unsigned i = 0; i < nandTitle.size(); i++) 208 | dbWriteData(nand, nandTitle[i]); 209 | fclose(nand); 210 | } 211 | 212 | prepNandSelect(); 213 | } 214 | -------------------------------------------------------------------------------- /source/topBar.c: -------------------------------------------------------------------------------- 1 | //1000 2 | unsigned char topbarData[] = { 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 80 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 84 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 88 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 89 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 92 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 93 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 97 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 98 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 99 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 100 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 102 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 103 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 104 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 106 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 107 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 108 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 109 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 110 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 111 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 112 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 113 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 114 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 118 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 120 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 121 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 122 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 126 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 128 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 129 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 130 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 | 0xFF, 0xC9, 0xC9, 0xC8, 0xFF, 0xC8, 0xC9, 0xC8, 0xFF, 0xC9, 0xC8, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 132 | 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC8, 0xC9, 0xC9, 133 | 0xFF, 0xC8, 0xC9, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xCA, 0xC9, 0xC9, 0xFF, 0xCA, 0xCA, 0xC9, 134 | 0xFF, 0xC8, 0xC8, 0xC8, 0xFF, 0xC8, 0xC8, 0xC8, 0xFF, 0xCA, 0xCA, 0xCA, 0xFF, 0xCA, 0xC9, 0xC9, 135 | 0xFF, 0xC9, 0xC9, 0xC8, 0xFF, 0xC9, 0xC8, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC8, 0xC9, 0xC9, 136 | 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC8, 0xC9, 0xC9, 0xFF, 0xC8, 0xC9, 0xC9, 137 | 0xFF, 0xC9, 0xC8, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xCA, 0xCA, 0xCA, 0xFF, 0xCA, 0xCA, 0xCA, 138 | 0xFF, 0xC9, 0xC9, 0xC8, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xCA, 0xC9, 0xCA, 0xFF, 0xCA, 0xCA, 0xCA, 139 | 0xFF, 0xCC, 0xCB, 0xCC, 0xFF, 0xCB, 0xCB, 0xCB, 0xFF, 0xCD, 0xCE, 0xCE, 0xFF, 0xCE, 0xCE, 0xCE, 140 | 0xFF, 0xCB, 0xCB, 0xCB, 0xFF, 0xCB, 0xCC, 0xCB, 0xFF, 0xCD, 0xCD, 0xCE, 0xFF, 0xCD, 0xCD, 0xCD, 141 | 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xD1, 0xD1, 0xD1, 0xFF, 0xD1, 0xD1, 0xD1, 142 | 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xD0, 0xD1, 0xD1, 0xFF, 0xD1, 0xD1, 0xD1, 143 | 0xFF, 0xCC, 0xCC, 0xCB, 0xFF, 0xCB, 0xCB, 0xCC, 0xFF, 0xCE, 0xCD, 0xCE, 0xFF, 0xCD, 0xCD, 0xCE, 144 | 0xFF, 0xCB, 0xCC, 0xCC, 0xFF, 0xCB, 0xCC, 0xCC, 0xFF, 0xCD, 0xCD, 0xCD, 0xFF, 0xCE, 0xCD, 0xCE, 145 | 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xD0, 0xCF, 0xCF, 0xFF, 0xD1, 0xD1, 0xD1, 0xFF, 0xD1, 0xD1, 0xD1, 146 | 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xD1, 0xD1, 0xD1, 0xFF, 0xD0, 0xD0, 0xD1, 147 | 0xFF, 0xC8, 0xC8, 0xC9, 0xFF, 0xC8, 0xC9, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 148 | 0xFF, 0xC8, 0xC9, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC8, 0xC8, 0xC9, 0xFF, 0xC8, 0xC9, 0xC9, 149 | 0xFF, 0xC8, 0xC9, 0xC9, 0xFF, 0xC8, 0xC9, 0xC9, 0xFF, 0xCA, 0xCA, 0xCA, 0xFF, 0xCA, 0xCA, 0xCA, 150 | 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xCA, 0xC9, 0xCA, 0xFF, 0xCA, 0xC9, 0xCA, 151 | 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC8, 0xC9, 0xC9, 0xFF, 0xC9, 0xC9, 0xC8, 0xFF, 0xC9, 0xC8, 0xC9, 152 | 0xFF, 0xC9, 0xC8, 0xC9, 0xFF, 0xC9, 0xC9, 0xC8, 0xFF, 0xC8, 0xC9, 0xC9, 0xFF, 0xC8, 0xC9, 0xC9, 153 | 0xFF, 0xC9, 0xC8, 0xC9, 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xCA, 0xCA, 0xCA, 0xFF, 0xCA, 0xCA, 0xCA, 154 | 0xFF, 0xC9, 0xC9, 0xC9, 0xFF, 0xC9, 0xC8, 0xC9, 0xFF, 0xCA, 0xCA, 0xCA, 0xFF, 0xC9, 0xCA, 0xCA, 155 | 0xFF, 0xCB, 0xCB, 0xCC, 0xFF, 0xCC, 0xCC, 0xCC, 0xFF, 0xCD, 0xCD, 0xCD, 0xFF, 0xCD, 0xCD, 0xCE, 156 | 0xFF, 0xCC, 0xCB, 0xCB, 0xFF, 0xCB, 0xCB, 0xCB, 0xFF, 0xCD, 0xCE, 0xCD, 0xFF, 0xCD, 0xCD, 0xCD, 157 | 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xD1, 0xD1, 0xD1, 0xFF, 0xD1, 0xD1, 0xD1, 158 | 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xD1, 0xD1, 0xD1, 0xFF, 0xD1, 0xD1, 0xD1, 159 | 0xFF, 0xCB, 0xCB, 0xCC, 0xFF, 0xCB, 0xCB, 0xCC, 0xFF, 0xCE, 0xCE, 0xCD, 0xFF, 0xCE, 0xCD, 0xCE, 160 | 0xFF, 0xCB, 0xCB, 0xCB, 0xFF, 0xCC, 0xCC, 0xCC, 0xFF, 0xCD, 0xCD, 0xCE, 0xFF, 0xCD, 0xCE, 0xCD, 161 | 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xD0, 0xCF, 0xCF, 0xFF, 0xD1, 0xD0, 0xD1, 0xFF, 0xD1, 0xD1, 0xD1, 162 | 0xFF, 0xCF, 0xCF, 0xCF, 0xFF, 0xD0, 0xCF, 0xCF, 0xFF, 0xD1, 0xD0, 0xD1, 0xFF, 0xD1, 0xD1, 0xD1, 163 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 165 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 170 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 172 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 173 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 174 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 175 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 176 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 177 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 178 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 179 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 182 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 183 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 184 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 185 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 186 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 187 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 188 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 189 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 190 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 191 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 192 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 193 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 194 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 195 | 0xFF, 0xD3, 0xD2, 0xD3, 0xFF, 0xD3, 0xD3, 0xD3, 0xFF, 0xD5, 0xD5, 0xD4, 0xFF, 0xD5, 0xD4, 0xD5, 196 | 0xFF, 0xD2, 0xD2, 0xD3, 0xFF, 0xD2, 0xD2, 0xD3, 0xFF, 0xD4, 0xD4, 0xD4, 0xFF, 0xD4, 0xD4, 0xD4, 197 | 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD7, 0xD8, 0xD8, 0xFF, 0xD8, 0xD8, 0xD7, 198 | 0xFF, 0xD7, 0xD6, 0xD6, 0xFF, 0xD7, 0xD6, 0xD7, 0xFF, 0xD8, 0xD8, 0xD7, 0xFF, 0xD8, 0xD7, 0xD8, 199 | 0xFF, 0xD2, 0xD3, 0xD3, 0xFF, 0xD2, 0xD2, 0xD3, 0xFF, 0xD4, 0xD4, 0xD4, 0xFF, 0xD4, 0xD4, 0xD4, 200 | 0xFF, 0xD2, 0xD2, 0xD3, 0xFF, 0xD3, 0xD3, 0xD3, 0xFF, 0xD4, 0xD4, 0xD4, 0xFF, 0xD5, 0xD4, 0xD4, 201 | 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD8, 0xD8, 0xD7, 0xFF, 0xD8, 0xD8, 0xD8, 202 | 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD8, 0xD7, 0xD8, 0xFF, 0xD8, 0xD8, 0xD7, 203 | 0xFF, 0xDA, 0xDA, 0xD9, 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xDB, 0xDC, 0xDC, 0xFF, 0xDB, 0xDC, 0xDC, 204 | 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xDA, 0xDA, 0xD9, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDC, 0xDC, 0xDB, 205 | 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDE, 0xDE, 0xDF, 0xFF, 0xDE, 0xDF, 0xDE, 206 | 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDD, 0xDE, 0xDD, 0xFF, 0xDF, 0xDE, 0xDF, 0xFF, 0xDE, 0xDF, 0xDE, 207 | 0xFF, 0xDA, 0xD9, 0xDA, 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDC, 0xDB, 0xDB, 208 | 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xD9, 0xD9, 0xDA, 0xFF, 0xDB, 0xDB, 0xDC, 0xFF, 0xDC, 0xDB, 0xDB, 209 | 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDF, 0xDE, 0xDF, 210 | 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDE, 0xDF, 0xDE, 0xFF, 0xDE, 0xDF, 0xDE, 211 | 0xFF, 0xD3, 0xD2, 0xD3, 0xFF, 0xD3, 0xD3, 0xD3, 0xFF, 0xD5, 0xD4, 0xD4, 0xFF, 0xD4, 0xD4, 0xD4, 212 | 0xFF, 0xD3, 0xD3, 0xD3, 0xFF, 0xD3, 0xD3, 0xD3, 0xFF, 0xD5, 0xD5, 0xD5, 0xFF, 0xD4, 0xD4, 0xD4, 213 | 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xD8, 0xD8, 0xD8, 214 | 0xFF, 0xD6, 0xD6, 0xD7, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xD8, 0xD8, 0xD8, 215 | 0xFF, 0xD2, 0xD3, 0xD3, 0xFF, 0xD3, 0xD3, 0xD2, 0xFF, 0xD4, 0xD4, 0xD5, 0xFF, 0xD4, 0xD4, 0xD4, 216 | 0xFF, 0xD3, 0xD3, 0xD3, 0xFF, 0xD3, 0xD2, 0xD3, 0xFF, 0xD5, 0xD4, 0xD4, 0xFF, 0xD5, 0xD4, 0xD4, 217 | 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD6, 0xD6, 0xD6, 0xFF, 0xD7, 0xD8, 0xD8, 0xFF, 0xD8, 0xD8, 0xD8, 218 | 0xFF, 0xD6, 0xD6, 0xD7, 0xFF, 0xD6, 0xD7, 0xD6, 0xFF, 0xD8, 0xD8, 0xD8, 0xFF, 0xD8, 0xD8, 0xD8, 219 | 0xFF, 0xD9, 0xDA, 0xD9, 0xFF, 0xD9, 0xD9, 0xDA, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDC, 0xDB, 0xDB, 220 | 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xD9, 0xD9, 0xDA, 0xFF, 0xDB, 0xDB, 0xDB, 0xFF, 0xDB, 0xDB, 0xDB, 221 | 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDF, 0xDF, 0xDE, 222 | 0xFF, 0xDD, 0xDE, 0xDD, 0xFF, 0xDD, 0xDD, 0xDE, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDE, 0xDE, 0xDE, 223 | 0xFF, 0xD9, 0xDA, 0xDA, 0xFF, 0xDA, 0xDA, 0xD9, 0xFF, 0xDC, 0xDB, 0xDB, 0xFF, 0xDC, 0xDB, 0xDB, 224 | 0xFF, 0xDA, 0xDA, 0xDA, 0xFF, 0xD9, 0xD9, 0xDA, 0xFF, 0xDC, 0xDC, 0xDC, 0xFF, 0xDB, 0xDB, 0xDB, 225 | 0xFF, 0xDE, 0xDD, 0xDD, 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDE, 0xDF, 0xDE, 0xFF, 0xDE, 0xDF, 0xDF, 226 | 0xFF, 0xDD, 0xDD, 0xDD, 0xFF, 0xDD, 0xDE, 0xDE, 0xFF, 0xDE, 0xDF, 0xDF, 0xFF, 0xDF, 0xDE, 0xDF, 227 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 228 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 229 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 230 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 233 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 234 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 237 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 238 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 241 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 242 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 243 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 244 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 245 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 246 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 247 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 248 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 249 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 250 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 252 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 254 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 255 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 258 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 259 | }; 260 | -------------------------------------------------------------------------------- /source/ui.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "ui.h" 9 | #include "global.h" 10 | #include "img.h" 11 | #include "util.h" 12 | #include "date.h" 13 | 14 | bool confirm(const char *t) 15 | { 16 | bool ret = false; 17 | 18 | button yes("Yes (A)", 40, 176, 96, 32); 19 | button no("No (B)", 180, 176, 96, 32); 20 | textbox back(24, 24, 280, 200, t, "Confirm"); 21 | while(true) 22 | { 23 | hidScanInput(); 24 | 25 | u32 down = hidKeysDown(); 26 | 27 | touchPosition p; 28 | hidTouchRead(&p); 29 | 30 | if(yes.released(p) || (down & KEY_A)) 31 | { 32 | ret = true; 33 | break; 34 | } 35 | else if(no.released(p) || (down & KEY_B)) 36 | { 37 | ret = false; 38 | break; 39 | } 40 | 41 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 42 | back.draw(); 43 | yes.draw(); 44 | no.draw(); 45 | sf2d_end_frame(); 46 | 47 | sf2d_swapbuffers(); 48 | } 49 | 50 | return ret; 51 | } 52 | 53 | void showMessage(const char *t, const char *head) 54 | { 55 | button ok("OK (A)", 116, 176, 96, 32); 56 | textbox back(24, 24, 280, 200, t, head); 57 | 58 | while(true) 59 | { 60 | hidScanInput(); 61 | 62 | touchPosition p; 63 | hidTouchRead(&p); 64 | 65 | u32 down = hidKeysDown(); 66 | 67 | if(ok.released(p) || down & KEY_A) 68 | break; 69 | 70 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 71 | back.draw(); 72 | ok.draw(); 73 | sf2d_end_frame(); 74 | 75 | sf2d_swapbuffers(); 76 | } 77 | } 78 | 79 | void showError(const char *t, unsigned error) 80 | { 81 | char full[256]; 82 | sprintf(full, "%s : %08X", t, error); 83 | button ok("OK (A)", 116, 176, 96, 32); 84 | textbox back(24, 24, 280, 200, full, "Error:"); 85 | 86 | while(true) 87 | { 88 | hidScanInput(); 89 | 90 | touchPosition p; 91 | hidTouchRead(&p); 92 | 93 | u32 down = hidKeysDown(); 94 | 95 | if(ok.released(p) || down & KEY_A) 96 | break; 97 | 98 | sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); 99 | back.draw(); 100 | ok.draw(); 101 | sf2d_end_frame(); 102 | 103 | sf2d_swapbuffers(); 104 | } 105 | } 106 | 107 | static sf2d_texture *progFull, *tbox, *bar; 108 | 109 | void textboxInit() 110 | { 111 | tbox = sf2d_create_texture(48, 56, TEXFMT_RGBA8, SF2D_PLACE_RAM); 112 | 113 | memcpy(tbox->tex.data, textboxData, 0x4000); 114 | } 115 | 116 | void textboxExit() 117 | { 118 | sf2d_free_texture(tbox); 119 | } 120 | 121 | textbox::textbox(unsigned x, unsigned y, unsigned width, unsigned height, const char *text, const char *_head) 122 | { 123 | Text = text; 124 | evenString(&Text); 125 | head = _head; 126 | 127 | X = x; 128 | Y = y; 129 | Width = width; 130 | Height = height; 131 | 132 | headX = X + ((width / 2) - (sftd_get_text_width(font, 12, head.c_str()) / 2)); 133 | 134 | if(Width > 32) 135 | xScale = (float)((Width - 32) / 16); 136 | if(Height > 32) 137 | yScale = (float)((Height - 32) / 16); 138 | } 139 | 140 | void textbox::draw() 141 | { 142 | //Top 143 | sf2d_draw_texture_part(tbox, X, Y, 0, 0, 16, 24); 144 | sf2d_draw_texture_part_scale(tbox, X + 16, Y, 16, 0, 16, 24, xScale, 1); 145 | sf2d_draw_texture_part(tbox, (X + 16) + (16 * xScale), Y, 32, 0, 16, 24); 146 | 147 | //Mid 148 | sf2d_draw_texture_part_scale(tbox, X, Y + 24, 0, 24, 16, 16, 1, yScale); 149 | sf2d_draw_texture_part_scale(tbox, X + 16, Y + 24, 16, 24, 16, 16, xScale, yScale); 150 | sf2d_draw_texture_part_scale(tbox, (X + 16) + (16 * xScale), Y + 24, 32, 24, 16, 16, 1, yScale); 151 | 152 | //Bottom 153 | sf2d_draw_texture_part(tbox, X, (Y + 16) + (16 * yScale), 0, 40, 16, 16); 154 | sf2d_draw_texture_part_scale(tbox, X + 16, (Y + 16) + (16 * yScale), 16, 40, 16, 16, xScale, 1); 155 | sf2d_draw_texture_part(tbox, (X + 16) + (16 * xScale), (Y + 16) + (16 * yScale), 32, 40, 16, 16); 156 | 157 | //Text 158 | sftd_draw_text(font, headX, Y + 4, RGBA8(0, 0, 0, 255), 12, head.c_str()); 159 | sftd_draw_text_wrap(font, X + 8, Y + 26, RGBA8(0, 0, 0, 255), 12, (X + Width) - 8, Text.c_str()); 160 | } 161 | 162 | 163 | void progressBarInit() 164 | { 165 | progFull = sf2d_create_texture(2, 16, TEXFMT_RGBA8, SF2D_PLACE_RAM); 166 | 167 | memcpy(progFull->tex.data, progBarData, 0x1000); 168 | } 169 | 170 | void progressBarExit() 171 | { 172 | sf2d_free_texture(progFull); 173 | } 174 | 175 | progressBar::progressBar(float _max, const char *t, const char *head) 176 | { 177 | back = new textbox(24, 24, 280, 200, t, head); 178 | max = _max; 179 | } 180 | 181 | progressBar::~progressBar() 182 | { 183 | delete back; 184 | } 185 | 186 | void progressBar::draw(float cur) 187 | { 188 | float prog = (float)(cur / max) * 100; 189 | float xScale = (float)(prog * 128) / 100; 190 | 191 | back->draw(); 192 | sf2d_draw_rectangle(back->X + 8, back->Y + 160, 256, 16, RGBA8(0, 0, 0, 255)); 193 | sf2d_draw_texture_scale(progFull, back->X + 8, back->Y + 160, xScale, 1); 194 | } 195 | 196 | button::button(const char * sText, int sX, int sY, int sWidth, int sHeight) 197 | { 198 | X = sX; 199 | Y = sY; 200 | width = sWidth; 201 | height = sHeight; 202 | text = sText; 203 | 204 | textX = X + 8; 205 | textY = Y + 8; 206 | 207 | Pressed = false; 208 | } 209 | 210 | void button::draw() 211 | { 212 | sf2d_draw_rectangle(X - 1, Y - 1, width + 2, height + 2, RGBA8(64, 64, 64, 255)); 213 | if(Pressed) 214 | sf2d_draw_rectangle(X, Y, width, height, RGBA8(200, 200, 200, 255)); 215 | else 216 | sf2d_draw_rectangle(X, Y, width, height, RGBA8(244, 244, 244, 255)); 217 | 218 | sftd_draw_text(font, textX, textY, RGBA8(0, 0, 0, 255), 12, text.c_str()); 219 | } 220 | 221 | //This checks whether the stylus is inside the button 222 | bool button::isOver(touchPosition p) 223 | { 224 | return (p.px > X && p.px < X + width) && (p.py > Y && p.py < Y + height); 225 | } 226 | 227 | //Checks if the stylus was removed. 228 | bool button::released(touchPosition p) 229 | { 230 | Prev = p; 231 | if(isOver(p)) 232 | { 233 | Pressed = true; 234 | } 235 | else 236 | { 237 | //This should now only return true if 238 | //the stylus is lifted directly off. 239 | //should return false now if moved away to different part 240 | if(Pressed && !touchPressed(p)) 241 | { 242 | Pressed = false; 243 | return true; 244 | } 245 | else 246 | { 247 | Pressed = false; 248 | } 249 | } 250 | return false; 251 | } 252 | 253 | void topBarInit() 254 | { 255 | bar = sf2d_create_texture(16, 16, TEXFMT_RGBA8, SF2D_PLACE_RAM); 256 | 257 | memcpy(bar->tex.data, topbarData, 0x1000); 258 | } 259 | 260 | void topBarExit() 261 | { 262 | sf2d_free_texture(bar); 263 | } 264 | 265 | void drawTopBar(const std::u32string nfo) 266 | { 267 | //the bar 268 | sf2d_draw_texture_scale(bar, 0, 0, 25, 1); 269 | 270 | //nfo is wide text, UTF32 271 | sftd_draw_wtext(font, 0, 0, RGBA8(0, 0, 0, 255), 12, (wchar_t *)nfo.data()); 272 | 273 | //time 274 | sftd_draw_text(font, 360, 0, RGBA8(0, 0, 0, 255), 12, RetTime().c_str()); 275 | } 276 | -------------------------------------------------------------------------------- /source/util.cpp: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | 6 | #include "global.h" 7 | #include "util.h" 8 | #include "titledata.h" 9 | #include "file.h" 10 | #include "ui.h" 11 | #include "smdh.h" 12 | #include "archive.h" 13 | #include "menu.h" 14 | 15 | static Handle fsHandle; 16 | 17 | std::u32string tou32(const std::u16string t) 18 | { 19 | char32_t tmp[256]; 20 | memset(tmp, 0, 256); 21 | 22 | utf16_to_utf32((uint32_t *)tmp, (uint16_t *)t.data(), 256); 23 | 24 | return std::u32string(tmp); 25 | } 26 | 27 | 28 | std::u16string tou16(const char *t) 29 | { 30 | char16_t tmp[256]; 31 | memset(tmp, 0, 256); 32 | 33 | utf8_to_utf16((uint16_t *)tmp, (uint8_t *)t, 256); 34 | 35 | return std::u16string(tmp); 36 | } 37 | 38 | std::string toString(const std::u16string t) 39 | { 40 | std::string ret; 41 | 42 | for(unsigned i = 0; i < t.length(); i++) 43 | ret += t[i]; 44 | 45 | return ret; 46 | } 47 | 48 | std::u32string modeText(int mode) 49 | { 50 | switch(mode) 51 | { 52 | case MODE_SAVE: 53 | return U" : Save"; 54 | break; 55 | case MODE_EXTDATA: 56 | return U" : ExtData"; 57 | break; 58 | case MODE_BOSS: 59 | return U" : Boss ExtData"; 60 | break; 61 | case MODE_SYSSAVE: 62 | return U" : System Save"; 63 | break; 64 | case MODE_SHARED: 65 | return U" : Shared ExtData"; 66 | break; 67 | default: 68 | return U""; 69 | break; 70 | } 71 | } 72 | 73 | void writeErrorToBuff(u8 *buff, size_t bSize, unsigned error) 74 | { 75 | char bytes[16]; 76 | sprintf(bytes, "****%08X****", error); 77 | 78 | for(unsigned i = 0, cByte = 0; i < bSize; i++, cByte++) 79 | { 80 | if(cByte > 15) 81 | cByte = 0; 82 | buff[i] = bytes[cByte]; 83 | } 84 | } 85 | 86 | void createTitleDir(const titleData t, int mode) 87 | { 88 | std::u16string create = getPath(mode) + t.nameSafe; 89 | 90 | FSUSER_CreateDirectory(sdArch, fsMakePath(PATH_UTF16, create.data()), 0); 91 | } 92 | 93 | void renameU16(std::u16string oldName, std::u16string newName) 94 | { 95 | FSUSER_RenameDirectory(sdArch, fsMakePath(PATH_UTF16, oldName.data()), sdArch, fsMakePath(PATH_UTF16, newName.data())); 96 | } 97 | 98 | void renameDir(const titleData t) 99 | { 100 | std::u16string oldName, oldPath, newPath; 101 | if(hbl) 102 | { 103 | //get old one with '_'s 104 | oldName = safeStringOld(t.name); 105 | 106 | //Rename save dirs 107 | oldPath = getPath(MODE_SAVE) + oldName; 108 | newPath = getPath(MODE_SAVE) + t.nameSafe; 109 | renameU16(oldPath, newPath); 110 | 111 | //rename extdat 112 | oldPath = getPath(MODE_EXTDATA) + oldName; 113 | newPath = getPath(MODE_EXTDATA) + t.nameSafe; 114 | renameU16(oldPath, newPath); 115 | } 116 | else if(t.media == MEDIATYPE_SD || t.media == MEDIATYPE_GAME_CARD) 117 | { 118 | oldName = safeStringOld(t.name); 119 | 120 | oldPath = getPath(MODE_SAVE) + oldName; 121 | newPath = getPath(MODE_SAVE) + t.nameSafe; 122 | renameU16(oldPath, newPath); 123 | 124 | oldPath = getPath(MODE_EXTDATA) + oldName; 125 | newPath = getPath(MODE_EXTDATA) + t.nameSafe; 126 | renameU16(oldPath, newPath); 127 | } 128 | else if(t.media == MEDIATYPE_NAND) 129 | { 130 | oldName = safeStringOld(t.name); 131 | 132 | oldPath = getPath(MODE_SYSSAVE) + oldName; 133 | newPath = getPath(MODE_SYSSAVE) + t.nameSafe; 134 | renameU16(oldPath, newPath); 135 | 136 | oldPath = getPath(MODE_EXTDATA) + oldName; 137 | newPath = getPath(MODE_EXTDATA) + t.nameSafe; 138 | renameU16(oldPath, newPath); 139 | 140 | oldPath = getPath(MODE_BOSS) + oldName; 141 | newPath = getPath(MODE_BOSS) + t.nameSafe; 142 | renameU16(oldPath, newPath); 143 | } 144 | } 145 | 146 | bool deleteSV(const titleData t) 147 | { 148 | u64 in = ((u64)SECUREVALUE_SLOT_SD << 32) | (t.unique << 8); 149 | u8 out; 150 | 151 | Result res = FSUSER_ControlSecureSave(SECURESAVE_ACTION_DELETE, &in, 8, &out, 1); 152 | if(res) 153 | { 154 | showError("Failed to delete secure value", (u32)res); 155 | return false; 156 | } 157 | 158 | return true; 159 | } 160 | 161 | std::u16string getPath(int mode) 162 | { 163 | switch(mode) 164 | { 165 | case MODE_SAVE: 166 | return tou16("/3ds/data/JKSM/Saves/"); 167 | break; 168 | case MODE_EXTDATA: 169 | return tou16("/3ds/data/JKSM/ExtData/"); 170 | break; 171 | case MODE_BOSS: 172 | return tou16("/3ds/data/JKSM/Boss/"); 173 | break; 174 | case MODE_SYSSAVE: 175 | return tou16("/3ds/data/JKSM/SysSave/"); 176 | break; 177 | case MODE_SHARED: 178 | return tou16("/3ds/data/JKSM/Shared/"); 179 | break; 180 | default: 181 | return tou16("/3ds/data/JKSM/"); 182 | break; 183 | } 184 | } 185 | 186 | bool runningUnder() 187 | { 188 | u64 id; 189 | APT_GetProgramID(&id); 190 | 191 | return id != 0x0004000002c23200; 192 | } 193 | 194 | void deleteExtdata(const titleData dat) 195 | { 196 | FS_ExtSaveDataInfo del = {MEDIATYPE_SD, 0, 0, dat.extdata, 0}; 197 | 198 | Result res = FSUSER_DeleteExtSaveData(del); 199 | if(res) 200 | showError("Error deleting Extra Data", (u32)res); 201 | else 202 | showMessage("Extra Data deleted!", "Success"); 203 | } 204 | 205 | void createExtData(const titleData dat) 206 | { 207 | FS_ExtSaveDataInfo create = {MEDIATYPE_SD, 0, 0, dat.extdata, 0}; 208 | smdh_s *tempSmdh = loadSMDH(dat.low, dat.high, dat.media); 209 | 210 | //100 should be enough, right? 211 | Result res; 212 | if(tempSmdh == NULL) 213 | { 214 | u8 *emptySmdh = new u8[sizeof(smdh_s)]; 215 | memset(emptySmdh, 0, sizeof(smdh_s)); 216 | res = FSUSER_CreateExtSaveData(create, 100, 100, 0x10000000, sizeof(smdh_s), emptySmdh); 217 | delete[] emptySmdh; 218 | } 219 | else 220 | res = FSUSER_CreateExtSaveData(create, 100, 100, 0x10000000, sizeof(smdh_s), (u8 *)tempSmdh); 221 | if(res) 222 | { 223 | showError("Error creating Extra Data", (u32)res); 224 | } 225 | else 226 | showMessage("ExtData created!", "Success!"); 227 | 228 | delete tempSmdh; 229 | } 230 | 231 | void evenString(std::string *test) 232 | { 233 | if(test->length() % 2 == 0) 234 | test->append(" "); 235 | } 236 | 237 | //Just returns whether or not the touch screen is pressed anywhere. 238 | bool touchPressed(touchPosition p) 239 | { 240 | return (p.px > 0 || p.py > 0); 241 | } 242 | 243 | bool modeExtdata(int mode) 244 | { 245 | return (mode == MODE_EXTDATA || mode == MODE_BOSS || mode == MODE_SHARED); 246 | } 247 | 248 | bool fexists(const char *path) 249 | { 250 | FILE *test = fopen(path, "r"); 251 | if(test == NULL) 252 | return false; 253 | 254 | fclose(test); 255 | 256 | return true; 257 | } 258 | 259 | void fsStart() 260 | { 261 | srvGetServiceHandleDirect(&fsHandle, "fs:USER"); 262 | FSUSER_Initialize(fsHandle); 263 | fsUseSession(fsHandle); 264 | } 265 | 266 | void fsEnd() 267 | { 268 | fsEndUseSession(); 269 | } 270 | 271 | void fsCommitData(FS_Archive arch) 272 | { 273 | FSUSER_ControlArchive(arch, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0); 274 | } 275 | 276 | //I seriously can't remember why I put space in there. I don't like it anymore. 277 | const char16_t oldVerboten[] = { L' ', L'.', L',', L'/', L'\\', L'<', L'>', L':', L'"', L'|', L'?', L'*'};//12 278 | const char16_t newVerboten[] = { L'.', L',', L'/', L'\\', L'<', L'>', L':', L'"', L'|', L'?', L'*'}; 279 | 280 | bool isVerbotenOld(char16_t d) 281 | { 282 | for(int i = 0; i < 12; i++) 283 | { 284 | if(d == oldVerboten[i]) 285 | return true; 286 | } 287 | 288 | return false; 289 | } 290 | 291 | bool isVerboten(char16_t d) 292 | { 293 | for(int i = 0; i < 11; i++) 294 | { 295 | if(d == newVerboten[i]) 296 | return true; 297 | } 298 | 299 | return false; 300 | } 301 | 302 | std::u16string safeStringOld(const std::u16string s) 303 | { 304 | std::u16string ret; 305 | for(unsigned i = 0; i < s.length(); i++) 306 | { 307 | if(isVerbotenOld(s[i])) 308 | ret += L'_'; 309 | else 310 | ret += s[i]; 311 | } 312 | return ret; 313 | } 314 | 315 | std::u16string safeString(const std::u16string s) 316 | { 317 | std::u16string ret; 318 | for(unsigned i = 0; i < s.length(); i++) 319 | { 320 | if(isVerboten(s[i])) 321 | ret += ' '; 322 | else 323 | ret += s[i]; 324 | } 325 | 326 | int i; 327 | for(i = ret.length() - 1; i > 0; i--) 328 | { 329 | if(ret[i] != L' ') 330 | break; 331 | } 332 | 333 | ret.erase(i + 1, ret.length() - i); 334 | 335 | return ret; 336 | } 337 | 338 | void prepareMenus() 339 | { 340 | prepMain(); 341 | prepBackMenu(); 342 | prepSaveMenu(); 343 | prepExtMenu(); 344 | prepNandBackup(); 345 | prepSharedMenu(); 346 | prepSharedBackMenu(); 347 | prepExtras(); 348 | if(devMode) 349 | prepDevMenu(); 350 | } 351 | --------------------------------------------------------------------------------