diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..56f0316 --- /dev/null +++ b/Makefile @@ -0,0 +1,219 @@ +NO_CTRCOMMON := 1 + +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") +endif + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +CTRCOMMON = $(TOPDIR)/../ctrcommon + +TOPDIR ?= $(CURDIR) +include $(DEVKITARM)/3ds_rules + +include $(TOPDIR)/resources/AppInfo + +APP_TITLE := $(shell echo "$(APP_TITLE)" | cut -c1-128) +APP_DESCRIPTION := $(shell echo "$(APP_DESCRIPTION)" | cut -c1-256) +APP_AUTHOR := $(shell echo "$(APP_AUTHOR)" | cut -c1-128) +APP_PRODUCT_CODE := $(shell echo $(APP_PRODUCT_CODE) | cut -c1-16) +APP_UNIQUE_ID := $(shell echo $(APP_UNIQUE_ID) | cut -c1-7) + +BUILD := build +SOURCES := source +DATA := data +INCLUDES := $(SOURCES) include +ICON := resources/icon.png + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard + +COMMON_FLAGS := -g -Wall -Wno-strict-aliasing -O3 -mword-relocations -fomit-frame-pointer -ffast-math $(ARCH) $(INCLUDE) -DARM11 -D_3DS $(BUILD_FLAGS) + +CXXFLAGS := $(COMMON_FLAGS) -std=gnu++11 +ifeq ($(ENABLE_EXCEPTIONS),) + CXXFLAGS += -fno-rtti -fno-exceptions +endif + +CFLAGS := $(COMMON_FLAGS) -std=gnu99 + +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +LIBS := -lctru -lm +LIBDIRS := $(PORTLIBS) $(CTRULIB) ./lib +ifeq ($(NO_CTRCOMMON),) + LIBS := -lctrcommon -lctru -lm + LIBDIRS := $(CTRCOMMON) $(PORTLIBS) $(CTRULIB) ./lib +endif + +RSF_3DS = $(TOPDIR)/template-3ds.rsf +RSF_CIA = $(TOPDIR)/template-cia.rsf + +ifeq ($(OS),Windows_NT) + MAKEROM = $(CTRCOMMON)/tools/makerom.exe + BANNERTOOL = $(CTRCOMMON)/tools/bannertool.exe +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Linux) + MAKEROM = $(CTRCOMMON)/tools/makerom-linux + BANNERTOOL = $(CTRCOMMON)/tools/bannertool-linux + endif + ifeq ($(UNAME_S),Darwin) + MAKEROM = $(CTRCOMMON)/tools/makerom-mac + BANNERTOOL = $(CTRCOMMON)/tools/bannertool-mac + endif +endif + +ifneq ("$(wildcard $(TOPDIR)/resources/banner.cgfx)","") + BANNER_IMAGE := $(TOPDIR)/resources/banner.cgfx + BANNER_IMAGE_ARG := -ci $(BANNER_IMAGE) +else + BANNER_IMAGE := $(TOPDIR)/resources/banner.png + BANNER_IMAGE_ARG := -i $(BANNER_IMAGE) +endif + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +recurse = $(shell find $2 -type $1 -name '$3' 2> /dev/null) + +null := +SPACE := $(null) $(null) +export OUTPUT_D := $(CURDIR)/output +export OUTPUT_N := $(subst $(SPACE),,$(APP_TITLE)) +export OUTPUT := $(OUTPUT_D)/$(OUTPUT_N) +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir) $(call recurse,d,$(CURDIR)/$(dir),*)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir) $(call recurse,d,$(CURDIR)/$(dir),*)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(call recurse,f,$(dir),*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(call recurse,f,$(dir),*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(call recurse,f,$(dir),*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(call recurse,f,$(dir),*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +export APP_ICON := $(TOPDIR)/$(ICON) + +.PHONY: $(BUILD) clean all + +#--------------------------------------------------------------------------------- +all: $(BUILD) + +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT_D) + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +.PHONY: all +all: $(OUTPUT).zip + +$(OUTPUT_D): + @[ -d $@ ] || mkdir -p $@ + +banner.bnr: $(BANNER_IMAGE) $(TOPDIR)/resources/audio.wav + @$(BANNERTOOL) makebanner $(BANNER_IMAGE_ARG) -a $(TOPDIR)/resources/audio.wav -o banner.bnr > /dev/null + +icon.icn: $(TOPDIR)/resources/icon.png + @$(BANNERTOOL) makesmdh -s "$(APP_TITLE)" -l "$(APP_TITLE)" -p "$(APP_AUTHOR)" -i $(TOPDIR)/resources/icon.png -o icon.icn > /dev/null + +$(OUTPUT).elf: $(OFILES) + +stripped.elf: $(OUTPUT).elf + @cp $(OUTPUT).elf stripped.elf + @$(PREFIX)strip stripped.elf + +$(OUTPUT).3dsx: stripped.elf + +$(OUTPUT).3ds: stripped.elf banner.bnr icon.icn + @$(MAKEROM) -f cci -o $(OUTPUT).3ds -rsf $(RSF_3DS) -target d -exefslogo -elf stripped.elf -icon icon.icn -banner banner.bnr -DAPP_TITLE="$(APP_TITLE)" -DAPP_PRODUCT_CODE="$(APP_PRODUCT_CODE)" -DAPP_UNIQUE_ID="$(APP_UNIQUE_ID)" + @echo "built ... $(notdir $@)" + +$(OUTPUT).cia: stripped.elf banner.bnr icon.icn + @$(MAKEROM) -f cia -o $(OUTPUT).cia -rsf $(RSF_CIA) -target t -exefslogo -elf stripped.elf -icon icon.icn -banner banner.bnr -DAPP_TITLE="$(APP_TITLE)" -DAPP_PRODUCT_CODE="$(APP_PRODUCT_CODE)" -DAPP_UNIQUE_ID="$(APP_UNIQUE_ID)" + @echo "built ... $(notdir $@)" + +$(OUTPUT).zip: $(OUTPUT_D) $(OUTPUT).elf $(OUTPUT).3dsx $(OUTPUT).smdh $(OUTPUT).3ds $(OUTPUT).cia + @cd $(OUTPUT_D); \ + mkdir -p 3ds/$(OUTPUT_N); \ + cp $(OUTPUT_N).3dsx 3ds/$(OUTPUT_N); \ + cp $(OUTPUT_N).smdh 3ds/$(OUTPUT_N); \ + zip -r $(OUTPUT_N).zip $(OUTPUT_N).elf $(OUTPUT_N).3ds $(OUTPUT_N).cia 3ds > /dev/null; \ + rm -r 3ds + @echo "built ... $(notdir $@)" + +#--------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +# WARNING: This is not the right way to do this! TODO: Do it right! +#--------------------------------------------------------------------------------- +%.vsh.o : %.vsh +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @python $(AEMSTRO)/aemstro_as.py $< ../$(notdir $<).shbin + @bin2s ../$(notdir $<).shbin | $(PREFIX)as -o $@ + @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h + @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h + @echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h + @rm ../$(notdir $<).shbin + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..0fce74a --- /dev/null +++ b/build.bat @@ -0,0 +1,3 @@ +make clean +make +PAUSE diff --git a/resources/AppInfo b/resources/AppInfo new file mode 100644 index 0000000..5c5e12e --- /dev/null +++ b/resources/AppInfo @@ -0,0 +1,5 @@ +APP_TITLE = SFontT +APP_DESCRIPTION = Shared Font Tool +APP_AUTHOR = DNAsdw +APP_PRODUCT_CODE = CTR-P-ASFA +APP_UNIQUE_ID = 0xF0001 diff --git a/resources/audio.wav b/resources/audio.wav new file mode 100644 index 0000000..8bdb0e1 Binary files /dev/null and b/resources/audio.wav differ diff --git a/resources/banner.png b/resources/banner.png new file mode 100644 index 0000000..905e819 Binary files /dev/null and b/resources/banner.png differ diff --git a/resources/icon.png b/resources/icon.png new file mode 100644 index 0000000..e4f8be7 Binary files /dev/null and b/resources/icon.png differ diff --git a/source/ext_svc.h b/source/ext_svc.h new file mode 100644 index 0000000..24af094 --- /dev/null +++ b/source/ext_svc.h @@ -0,0 +1,9 @@ +#ifndef EXT_SVC_H_ +#define EXT_SVC_H_ + +Result ext_svcInvalidateProcessDataCache(Handle handle, u32 addr, u32 size); +Result ext_svcFlushProcessDataCache(Handle handle, u32 addr, u32 size); +Result ext_svcStartInterProcessDma(Handle* hdma, Handle dstProcess, void* dst, Handle srcProcess, const void* src, u32 size, u32* config); +Result ext_svcGetDmaState(u32* state, Handle dma); + +#endif // EXT_SVC_H_ diff --git a/source/ext_svc.s b/source/ext_svc.s new file mode 100644 index 0000000..ad5f881 --- /dev/null +++ b/source/ext_svc.s @@ -0,0 +1,33 @@ + +.global ext_svcInvalidateProcessDataCache +.type ext_svcInvalidateProcessDataCache, %function +ext_svcInvalidateProcessDataCache: + svc 0x52 + bx lr + +.global ext_svcFlushProcessDataCache +.type ext_svcFlushProcessDataCache, %function +ext_svcFlushProcessDataCache: + svc 0x54 + bx lr + +.global ext_svcStartInterProcessDma +.type ext_svcStartInterProcessDma, %function +ext_svcStartInterProcessDma: + stmfd sp!, {r0, r4, r5} + ldr r0, [sp, #0xC] + ldr r4, [sp, #0xC + 0x4] + ldr r5, [sp, #0xC + 0x8] + svc 0x55 + ldmfd sp!, {r2, r4, r5} + str r1, [r2] + bx lr + +.global ext_svcGetDmaState +.type ext_svcGetDmaState, %function +ext_svcGetDmaState: + str r0, [sp, #-0x4]! + svc 0x57 + ldr r3, [sp], #4 + str r1, [r3] + bx lr diff --git a/source/main.c b/source/main.c new file mode 100644 index 0000000..e398253 --- /dev/null +++ b/source/main.c @@ -0,0 +1,470 @@ +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wmultichar" + +#include +#include <3ds.h> +#include "ext_svc.h" + +#define CURRENT_PROCESS_HANDLE (0xffff8001) + +#define CONVERT_ENDIAN(n) (((n) >> 24 & 0xFF) | ((n) >> 8 & 0xFF00) | (((n) & 0xFF00) << 8) | (((n) & 0xFF) << 24)) +const u32 BinFileSigFONT = CONVERT_ENDIAN('CFNT'); +const u32 BinRuntimeSigFONT = CONVERT_ENDIAN('CFNU'); +const u32 BinBlockSigFINF = CONVERT_ENDIAN('FINF'); + +bool g_bNew3DS = false; +u32 g_uAddress = 0x18000000; + +typedef enum SharedFontType +{ + SHARED_FONT_TYPE_NULL, + SHARED_FONT_TYPE_STD, + SHARED_FONT_TYPE_CN, + SHARED_FONT_TYPE_KR, + SHARED_FONT_TYPE_TW +} SharedFontType; + +u32 g_uSharedFontType = SHARED_FONT_TYPE_NULL; + +typedef struct BinaryFileHeader +{ + u32 Signature; + u16 ByteOrder; + u16 HeaderSize; + u32 Version; + u32 FileSize; + u16 DataBlocks; + u16 Reserved; +} __attribute__((packed)) BinaryFileHeader; + +typedef struct BinaryBlockHeader +{ + u32 Kind; + u32 Size; +} __attribute__((packed)) BinaryBlockHeader; + +typedef struct CharWidths +{ + s8 Left; + u8 GlyphWidth; + s8 CharWidth; +} __attribute__((packed)) CharWidths; + +typedef struct FontInformation +{ + u8 FontType; + s8 Linefeed; + u16 AlterCharIndex; + CharWidths DefaultWidth; + u8 Encoding; + u32 PtrGlyph; + u32 PtrWidth; + u32 PtrMap; + u8 Height; + u8 Width; + u8 Ascent; + u8 Reserved; +} __attribute__((packed)) FontInformation; + +typedef struct FontTextureGlyph +{ + u8 CellWidth; + u8 CellHeight; + s8 BaselinePos; + u8 MaxCharWidth; + u32 SheetSize; + u16 SheetNum; + u16 SheetFormat; + u16 SheetRow; + u16 SheetLine; + u16 SheetWidth; + u16 SheetHeight; + u32 SheetImage; +} __attribute__((packed)) FontTextureGlyph; + +typedef struct FontCodeMap +{ + u16 CodeBegin; + u16 CodeEnd; + u16 MappingMethod; + u16 Reserved; + u32 PtrNext; +} __attribute__((packed)) FontCodeMap; + +u32 memoryProtect(Handle a_hDest, u32 a_uAddress, u32 a_uSize) +{ + for (u32 i = 0; i < a_uSize; i += 0x1000) + { + u32 uRet = svcControlProcessMemory(a_hDest, a_uAddress + i, a_uAddress + i, 0x1000, 6, 7); + if (uRet != 0 && uRet != 0xD900060C) + { + return uRet; + } + } + return 0; +} + +u32 memoryCopy(Handle a_hDest, void* a_pDest, Handle a_hSrc, void* a_pSrc, u32 a_uSize) +{ + u32 uRet = ext_svcFlushProcessDataCache(a_hSrc, (u32)a_pSrc, a_uSize); + if (uRet != 0) + { + return uRet; + } + uRet = ext_svcFlushProcessDataCache(a_hDest, (u32)a_pDest, a_uSize); + if (uRet != 0) + { + return uRet; + } + u32 hDma = 0; + u32 uDmaConfig[20] = {}; + uRet = ext_svcStartInterProcessDma(&hDma, a_hDest, a_pDest, a_hSrc, a_pSrc, a_uSize, uDmaConfig); + if (uRet != 0) + { + return uRet; + } + u32 uState = 0; + static u32 uInterProcessDmaFinishState = 0; + if (uInterProcessDmaFinishState == 0) + { + uRet = ext_svcGetDmaState(&uState, hDma); + svcSleepThread(1000000000); + uRet = ext_svcGetDmaState(&uState, hDma); + uInterProcessDmaFinishState = uState; + printf("InterProcessDmaFinishState: %08x\n", uState); + } + else + { + u32 i = 0; + for (i = 0; i < 10000; i++) + { + uState = 0; + uRet = ext_svcGetDmaState(&uState, hDma); + if (uState == uInterProcessDmaFinishState) + { + break; + } + svcSleepThread(1000000); + } + if (i >= 10000) + { + printf("memoryCopy time out %08x\n", uState); + return 1; + } + } + svcCloseHandle(hDma); + return ext_svcInvalidateProcessDataCache(a_hDest, (u32)a_pDest, a_uSize); +} + +void clearOutput() +{ + static const char* c_pLine = " "; + for (int i = 13; i < 25; i++) + { + printf("\E[%d;0H%s", i, c_pLine); + } + printf("\E[13;0H"); +} + +u32 initSharedFontType() +{ + clearOutput(); + Handle hHomeMenu = 0; + u32 uRet = svcOpenProcess(&hHomeMenu, 0xf); + if (uRet != 0) + { + printf("OpenProcess error: 0x%08X\n", uRet); + return uRet; + } + else + { + printf("OpenProcess ok\n"); + } + //uRet = svcControlProcessMemory(hHomeMenu, g_uAddress, g_uAddress, 0x332000, 6, 7); + uRet = memoryProtect(hHomeMenu, g_uAddress, 0x1000); + if (uRet != 0) + { + svcCloseHandle(hHomeMenu); + printf("ControlProcessMemory error: 0x%08X\n", uRet); + return uRet; + } + else + { + printf("ControlProcessMemory ok\n"); + } + uRet = memoryCopy(CURRENT_PROCESS_HANDLE, &g_uSharedFontType, hHomeMenu, (void*)(g_uAddress + 4), 4); + if (uRet != 0) + { + svcCloseHandle(hHomeMenu); + printf("memoryCopy error: 0x%08X\n", uRet); + return uRet; + } + svcCloseHandle(hHomeMenu); + clearOutput(); + return 0; +} + +u32 font2runtime(u8* a_pFont) +{ + BinaryFileHeader* pBinaryFileHeader = (BinaryFileHeader*)(a_pFont); + if (pBinaryFileHeader->Signature != BinFileSigFONT) + { + return 1; + } + BinaryBlockHeader* pBinaryBlockHeader = (BinaryBlockHeader*)(pBinaryFileHeader + 1); + if (pBinaryBlockHeader->Kind != BinBlockSigFINF) + { + return 1; + } + FontInformation* pFontInformation = (FontInformation*)(pBinaryBlockHeader + 1); + FontTextureGlyph *pFontTextureGlyph = (FontTextureGlyph*)(a_pFont + pFontInformation->PtrGlyph); + pFontTextureGlyph->SheetImage += g_uAddress + 0x80; + u32 uOffset = pFontInformation->PtrMap; + while (uOffset != 0) + { + FontCodeMap* pFontCodeMap = (FontCodeMap*)(a_pFont + uOffset); + uOffset = pFontCodeMap->PtrNext; + if (uOffset != 0) + { + pFontCodeMap->PtrNext += g_uAddress + 0x80; + } + } + pFontInformation->PtrGlyph += g_uAddress + 0x80; + pFontInformation->PtrWidth += g_uAddress + 0x80; + pFontInformation->PtrMap += g_uAddress + 0x80; + pBinaryFileHeader->Signature = BinRuntimeSigFONT; + return 0; +} + +u32 changeSharedFont(SharedFontType a_eType) +{ + u32 uRet = 0; + static const char* c_kPath[] = { "", "font/std/cbf_std.bcfnt", "font/cn/cbf_zh-Hans-CN.bcfnt", "font/kr/cbf_ko-Hang-KR.bcfnt", "font/tw/cbf_zh-Hant-TW.bcfnt" }; + if (a_eType <= SHARED_FONT_TYPE_NULL || a_eType > SHARED_FONT_TYPE_TW) + { + return 1; + } + clearOutput(); + static int c_nTextColor = 0; + if (c_nTextColor == 32) + { + printf("\E[0;%dm", c_nTextColor); + c_nTextColor = 0; + } + else + { + printf("\E[0m"); + c_nTextColor = 32; + } + printf("Start change shared font %d\n", a_eType); + FILE* fp = fopen(c_kPath[a_eType], "rb"); + if (fp == NULL) + { + printf("open %s error\n", c_kPath[a_eType]); + return 1; + } + fseek(fp, 0, SEEK_END); + u32 uFileSize = ftell(fp); + printf("font size 0x%X\n", uFileSize); + if (uFileSize > 0x332000 - 0x80) + { + fclose(fp); + printf("font size 0x%X > 0x%08X\n", uFileSize, 0x332000 - 0x80); + return 1; + } + fseek(fp, 0, SEEK_SET); + static u32 c_uFontAddress = 0; + if (c_uFontAddress == 0) + { + uRet = svcControlMemory(&c_uFontAddress, 0, 0, 0x332000, 0x10003, 3); + if (uRet != 0) + { + fclose(fp); + printf("ControlMemory error: 0x%08X\n", uRet); + return uRet; + } + else + { + printf("ControlMemory ok\n"); + printf("font address %X\n", c_uFontAddress); + for (int i = 0xC; i < 0x80; i += 4) + { + *(u32*)(c_uFontAddress + i) = 0; + } + *(u32*)c_uFontAddress = 2; + *(u32*)(c_uFontAddress + 4) = g_uSharedFontType; + } + } + *(u32*)(c_uFontAddress + 8) = uFileSize; + fread((void*)(c_uFontAddress + 0x80), 1, uFileSize, fp); + fclose(fp); + uRet = font2runtime((u8*)(c_uFontAddress + 0x80)); + if (uRet != 0) + { + return uRet; + } + Handle hHomeMenu = 0; + uRet = svcOpenProcess(&hHomeMenu, 0xf); + if (uRet != 0) + { + printf("OpenProcess error: 0x%08X\n", uRet); + return uRet; + } + else + { + printf("OpenProcess ok\n"); + } + uRet = memoryProtect(hHomeMenu, g_uAddress, 0x332000); + if (uRet != 0) + { + svcCloseHandle(hHomeMenu); + printf("ControlProcessMemory error: 0x%08X\n", uRet); + return uRet; + } + else + { + printf("ControlProcessMemory ok\n"); + } + uRet = memoryCopy(hHomeMenu, (void*)g_uAddress, CURRENT_PROCESS_HANDLE, (void*)c_uFontAddress, uFileSize + 0x80); + if (uRet != 0) + { + svcCloseHandle(hHomeMenu); + printf("memoryCopy error: 0x%08X\n", uRet); + return uRet; + } + svcCloseHandle(hHomeMenu); + printf("change font ok\n"); + return 0; +} + +int main(int argc, char* argv[]) +{ + gfxInitDefault(); + consoleInit(GFX_BOTTOM, NULL); + printf("\E[1;0H"); + printf(" Shared Font Tool v1.1\n"); + printf("\n"); + printf("Press START : exit\n"); + u32 uKernelVersion = 0; + uKernelVersion = osGetKernelVersion(); + if (uKernelVersion > SYSTEM_VERSION(2, 44, 6)) + { + u8 uOut; + Result ret = APT_CheckNew3DS(0, &uOut); + if (ret == 0) + { + if (uOut != 0) + { + g_bNew3DS = true; + } + } + } + printf("\E[10;0H"); + printf("New3DS: %s\n", g_bNew3DS ? "true" : "false"); + if (g_bNew3DS) + { + g_uAddress = 0x1bc00000; + } + if (initSharedFontType() != 0) + { + g_uSharedFontType = SHARED_FONT_TYPE_STD; + printf("\E[11;0H"); + printf("Get shared font type failed\n"); + } + else + { + printf("\E[11;0H"); + printf("SharedFontType: "); + switch (g_uSharedFontType) + { + case SHARED_FONT_TYPE_NULL: + printf("null"); + break; + case SHARED_FONT_TYPE_STD: + printf("std"); + break; + case SHARED_FONT_TYPE_CN: + printf("cn"); + break; + case SHARED_FONT_TYPE_KR: + printf("kr"); + break; + case SHARED_FONT_TYPE_TW: + printf("tw"); + break; + default: + printf("unknown"); + break; + } + printf("\n"); + } + bool bCanRecover = false; + bool bCanChangeToCN = false; + bool bCanChangeToTW = false; + bool bCanChangeToSTD = false; + bool bCanChangeToKR = false; + if (g_uSharedFontType > SHARED_FONT_TYPE_NULL) + { + bCanRecover = true; + printf("\E[4;0H"); + printf("Press SELECT: recover font\n"); + if (g_uSharedFontType != SHARED_FONT_TYPE_KR) + { + printf("Press RIGHT : change font to cn (C)\n"); + bCanChangeToCN = true; + } + if (g_uSharedFontType != SHARED_FONT_TYPE_KR && g_uSharedFontType != SHARED_FONT_TYPE_CN && g_uSharedFontType != SHARED_FONT_TYPE_STD) + { + printf("Press LEFT : change font to tw (T)\n"); + bCanChangeToTW = true; + } + if (g_uSharedFontType != SHARED_FONT_TYPE_KR && g_uSharedFontType != SHARED_FONT_TYPE_CN) + { + printf("Press UP : change font to std(J/U/E)\n"); + bCanChangeToSTD = true; + } + if (true) + { + printf("Press DOWN : change font to kr (K)\n"); + bCanChangeToKR = true; + } + } + while (aptMainLoop()) + { + gspWaitForVBlank(); + hidScanInput(); + u32 kDown = hidKeysDown(); + if ((kDown & KEY_START) != 0) + { + break; + } + else if ((kDown & KEY_SELECT) != 0 && bCanRecover) + { + changeSharedFont(g_uSharedFontType); + } + else if ((kDown & KEY_DRIGHT) != 0 && bCanChangeToCN) + { + changeSharedFont(SHARED_FONT_TYPE_CN); + } + else if ((kDown & KEY_DLEFT) != 0) + { + changeSharedFont(SHARED_FONT_TYPE_TW && bCanChangeToTW); + } + else if ((kDown & KEY_DUP) != 0) + { + changeSharedFont(SHARED_FONT_TYPE_STD && bCanChangeToSTD); + } + else if ((kDown & KEY_DDOWN) != 0) + { + changeSharedFont(SHARED_FONT_TYPE_KR && bCanChangeToKR); + } + //else if (kDown != 0) + //{ + // printf("\E[25;0H\E[0m%-10u\n", kDown); + //} + gfxFlushBuffers(); + gfxSwapBuffers(); + } + gfxExit(); + return 0; +} diff --git a/template-3ds.rsf b/template-3ds.rsf new file mode 100644 index 0000000..cbb9fb9 --- /dev/null +++ b/template-3ds.rsf @@ -0,0 +1,273 @@ +BasicInfo: + Title : "$(APP_TITLE)" + CompanyCode : "00" + ProductCode : "$(APP_PRODUCT_CODE)" + ContentType : Application + Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem + +TitleInfo: + UniqueId : $(APP_UNIQUE_ID) + Category : Application + +CardInfo: + MediaSize : 128MB # 128MB / 256MB / 512MB / 1GB / 2GB / 4GB / 8GB / 16GB / 32GB + MediaType : Card1 # Card1 / Card2 + CardDevice : None # NorFlash(Pick this if you use savedata) / None + +Option: + UseOnSD : false # true if App is to be installed to SD + FreeProductCode : true # Removes limitations on ProductCode + MediaFootPadding : false # If true CCI files are created with padding + EnableCrypt : true # Enables encryption for NCCH and CIA + EnableCompress : true # Compresses exefs code + +ExeFs: # these are the program segments from the ELF, check your elf for the appropriate segment names + ReadOnly: + - .rodata + - RO + ReadWrite: + - .data + - RO + Text: + - .init + - .text + - STUP_ENTRY + +PlainRegion: # only used with SDK ELFs + #- .module_id + +#Rom: + # Specifies the root path of the file system to include in the ROM. + # HostRoot : "romfs" + +AccessControlInfo: + # UseOtherVariationSaveData : true + # UseExtSaveData : true + # ExtSaveDataId: 0xffffffff + # SystemSaveDataId1: 0x220 + # SystemSaveDataId2: 0x00040010 + # OtherUserSaveDataId1: 0x220 + # OtherUserSaveDataId2: 0x330 + # OtherUserSaveDataId3: 0x440 + # UseExtendedSaveDataAccessControl: true + # AccessibleSaveDataIds: [0x101, 0x202, 0x303, 0x404, 0x505, 0x606] + FileSystemAccess: + # - CategorySystemApplication + # - CategoryHardwareCheck + - CategoryFileSystemTool + - Debug + # - TwlCardBackup + # - TwlNandData + # - Boss + - DirectSdmc + # - Core + # - CtrNandRo + # - CtrNandRw + # - CtrNandRoWrite + # - CategorySystemSettings + # - CardBoard + # - ExportImportIvs + - DirectSdmcWrite + # - SwitchCleanup + # - SaveDataMove + # - Shop + # - Shell + # - CategoryHomeMenu + IoAccessControl: + # - FsMountNand + # - FsMountNandRoWrite + # - FsMountTwln + # - FsMountWnand + # - FsMountCardSpi + # - UseSdif3 + # - CreateSeed + # - UseCardSpi + + IdealProcessor : 0 + AffinityMask : 1 + + Priority : 16 + + MaxCpu : 0x9E # Default + + # DisableDebug : true + # EnableForceDebug : false + # CanWriteSharedPage : true + # CanUsePrivilegedPriority : false + # CanUseNonAlphabetAndNumber : true + # PermitMainFunctionArgument : true + # CanShareDeviceMemory : true + # RunnableOnSleep : false + # SpecialMemoryArrange : true + + CoreVersion : 2 + DescVersion : 2 + + ReleaseKernelMajor : "02" + ReleaseKernelMinor : "33" + MemoryType : Application # Application / System / Base + HandleTableSize: 512 + IORegisterMapping: + - 1ff50000-1ff57fff + - 1ff70000-1ff77fff + MemoryMapping: + - 1f000000-1f5fffff:r + SystemCallAccess: + ArbitrateAddress: 34 + Break: 60 + CancelTimer: 28 + ClearEvent: 25 + ClearTimer: 29 + CloseHandle: 35 + ConnectToPort: 45 + ControlMemory: 1 + CreateAddressArbiter: 33 + CreateEvent: 23 + CreateMemoryBlock: 30 + CreateMutex: 19 + CreateSemaphore: 21 + CreateThread: 8 + CreateTimer: 26 + DuplicateHandle: 39 + ExitProcess: 3 + ExitThread: 9 + GetCurrentProcessorNumber: 17 + GetHandleInfo: 41 + GetProcessId: 53 + GetProcessIdOfThread: 54 + GetProcessIdealProcessor: 6 + GetProcessInfo: 43 + GetResourceLimit: 56 + GetResourceLimitCurrentValues: 58 + GetResourceLimitLimitValues: 57 + GetSystemInfo: 42 + GetSystemTick: 40 + GetThreadContext: 59 + GetThreadId: 55 + GetThreadIdealProcessor: 15 + GetThreadInfo: 44 + GetThreadPriority: 11 + MapMemoryBlock: 31 + OutputDebugString: 61 + QueryMemory: 2 + ReleaseMutex: 20 + ReleaseSemaphore: 22 + SendSyncRequest1: 46 + SendSyncRequest2: 47 + SendSyncRequest3: 48 + SendSyncRequest4: 49 + SendSyncRequest: 50 + SetThreadPriority: 12 + SetTimer: 27 + SignalEvent: 24 + SleepThread: 10 + UnmapMemoryBlock: 32 + WaitSynchronization1: 36 + WaitSynchronizationN: 37 + controlProcessMemory: 112 + InterruptNumbers: + ServiceAccessControl: + - APT:U + - $hioFIO + - $hostio0 + - $hostio1 + - ac:u + - boss:U + - cam:u + - cecd:u + - cfg:u + - dlp:FKCL + - dlp:SRVR + - dsp::DSP + - frd:u + - fs:USER + - gsp::Gpu + - hid:USER + - http:C + - ir:u + - mic:u + - ndm:u + - news:u + - nwm::UDS + - ptm:u + - pxi:dev + - soc:U + - ssl:C + - y2r:u + - am:u + - cfg:nor + - csnd:SND + +SystemControlInfo: + SaveDataSize: 0KB # It doesn't use any save data. + RemasterVersion: 2 + StackSize: 0x40000 + # JumpId: 0 + Dependency: + ac: 0x0004013000002402L + am: 0x0004013000001502L + boss: 0x0004013000003402L + camera: 0x0004013000001602L + cecd: 0x0004013000002602L + cfg: 0x0004013000001702L + codec: 0x0004013000001802L + csnd: 0x0004013000002702L + dlp: 0x0004013000002802L + dsp: 0x0004013000001a02L + friends: 0x0004013000003202L + gpio: 0x0004013000001b02L + gsp: 0x0004013000001c02L + hid: 0x0004013000001d02L + http: 0x0004013000002902L + i2c: 0x0004013000001e02L + ir: 0x0004013000003302L + mcu: 0x0004013000001f02L + mic: 0x0004013000002002L + ndm: 0x0004013000002b02L + news: 0x0004013000003502L + nim: 0x0004013000002c02L + nwm: 0x0004013000002d02L + pdn: 0x0004013000002102L + ps: 0x0004013000003102L + ptm: 0x0004013000002202L + ro: 0x0004013000003702L + socket: 0x0004013000002e02L + spi: 0x0004013000002302L + ssl: 0x0004013000002f02L +CommonHeaderKey: + D: | + jL2yO86eUQnYbXIrzgFVMm7FVze0LglZ2f5g+c42hWoEdnb5BOotaMQPBfqt + aUyAEmzQPaoi/4l4V+hTJRXQfthVRqIEx27B84l8LA6Tl5Fy9PaQaQ+4yRfP + g6ylH2l0EikrIVjy2uMlFgl0QJCrG+QGKHftxhaGCifdAwFNmiZuyJ/TmktZ + 0RCb66lYcr2h/p2G7SnpKUliS9h9KnpmG+UEgVYQUK+4SCfByUa9PxYGpT0E + nw1UcRz0gsBmdOqcgzwnAd9vVqgb42hVn6uQZyAl+j1RKiMWywZarazIR/k5 + Lmr4+groimSEa+3ajyoIho9WaWTDmFU3mkhA2tUDIQ== + Exponent: | + AQAB + Modulus: | + zwCcsyCgMkdlieCgQMVXA6X2jmb1ICjup0Q+jk/AydPkOgsx7I/MjUymFEkU + vgXBtCKtzh3NKXtFFuW51tJ60GPOabLKuG0Qm5li+UXALrWhzWuvd5vv2FZI + dTQCbrq/MFS/M02xNtwqzWiBjE/LwqIdbrDAAvX4HGy0ydaQJ1DKYeQeph5D + lAGBw2nQ4izXhhuLaU3w8VQkIJHdhxIKI5gJY/20AGkG0vHD553Mh5kBINrWp + CRYmmJS8DCYbAiQtKbkeUfzHViGTZuj6PwaY8Mv39PGO47a++pt45IUyCEs4/ + LjMS72cyfo8tU4twRGp76SFGYejYj3wGC1f/POQw== + Signature: | + BOPR0jL0BOV5Zx502BuPbOvi/hvOq5ID8Dz1MQfOjkey6FKP/6cb4f9YXpm6c + ZCHAZLo0GduKdMepiKPUq1rsbbAxkRdQdjOOusEWoxNA58x3E4373tCAhlqM2 + DvuQERrIIQ/XnYLV9C3uw4efZwhFqog1jvVyoEHpuvs8xnYtGbsKQ8FrgLwXv + pOZYy9cSgq+jqLy2D9IxiowPcbq2cRlbW9d2xlUfpq0AohyuXQhpxn7d9RUor + 9veoARRAdxRJK12EpcSoEM1LhTRYdJnSRCY3x3p6YIV3c+l1sWvaQwKt0sZ/U + 8TTDx2gb9g7r/+U9icneu/zlqUpSkexCS009Q== + Descriptor: | + AP///wAABAACAAAAAAAFGJ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjIAAAAAAAABBUFQ6VQAAACRoaW + 9GSU8AJGhvc3RpbzAkaG9zdGlvMWFjOnUAAAAAYm9zczpVAABjYW06dQAAAGN + lY2Q6dQAAY2ZnOnUAAABkbHA6RktDTGRscDpTUlZSZHNwOjpEU1BmcmQ6dQAA + AGZzOlVTRVIAZ3NwOjpHcHVoaWQ6VVNFUmh0dHA6QwAAaXI6dQAAAABtaWM6d + QAAAG5kbTp1AAAAbmV3czp1AABud206OlVEU3B0bTp1AAAAcHhpOmRldgBzb2 + M6VQAAAHNzbDpDAAAAeTJyOnUAAABhbTp1AAAAAGNmZzpub3IAY3NuZDpTTkQ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABOn/rw/7//8ec/APIA8JH/APaR/1D/gf9Y/4H/cP+B/3j/gf8BAQD/AAIA/ + iECAPz/////////////////////////////////////////////////////// + //////////////////////////////AAAAAAAAAAAAAAAAAAAAAAADAAAAAAA + AAAAAAAAAAAI= diff --git a/template-cia.rsf b/template-cia.rsf new file mode 100644 index 0000000..ab2c12e --- /dev/null +++ b/template-cia.rsf @@ -0,0 +1,241 @@ +BasicInfo: + Title : "$(APP_TITLE)" + CompanyCode : "00" + ProductCode : "$(APP_PRODUCT_CODE)" + ContentType : Application + Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem + +TitleInfo: + UniqueId : $(APP_UNIQUE_ID) + Category : Application + +CardInfo: + MediaSize : 128MB # 128MB / 256MB / 512MB / 1GB / 2GB / 4GB / 8GB / 16GB / 32GB + MediaType : Card1 # Card1 / Card2 + CardDevice : None # NorFlash(Pick this if you use savedata) / None + +Option: + UseOnSD : true # true if App is to be installed to SD + FreeProductCode : true # Removes limitations on ProductCode + MediaFootPadding : false # If true CCI files are created with padding + EnableCrypt : false # Enables encryption for NCCH and CIA + EnableCompress : true # Compresses exefs code + +ExeFs: # these are the program segments from the ELF, check your elf for the appropriate segment names + ReadOnly: + - .rodata + - RO + ReadWrite: + - .data + - RO + Text: + - .init + - .text + - STUP_ENTRY + +PlainRegion: # only used with SDK ELFs + #- .module_id + +#Rom: + # Specifies the root path of the file system to include in the ROM. + # HostRoot : "romfs" + +AccessControlInfo: + # UseOtherVariationSaveData : true + # UseExtSaveData : true + # ExtSaveDataId: 0xffffffff + # SystemSaveDataId1: 0x220 + # SystemSaveDataId2: 0x00040010 + # OtherUserSaveDataId1: 0x220 + # OtherUserSaveDataId2: 0x330 + # OtherUserSaveDataId3: 0x440 + # UseExtendedSaveDataAccessControl: true + # AccessibleSaveDataIds: [0x101, 0x202, 0x303, 0x404, 0x505, 0x606] + FileSystemAccess: + # - CategorySystemApplication + # - CategoryHardwareCheck + - CategoryFileSystemTool + - Debug + # - TwlCardBackup + # - TwlNandData + # - Boss + - DirectSdmc + # - Core + # - CtrNandRo + # - CtrNandRw + # - CtrNandRoWrite + # - CategorySystemSettings + # - CardBoard + # - ExportImportIvs + - DirectSdmcWrite + # - SwitchCleanup + # - SaveDataMove + # - Shop + # - Shell + # - CategoryHomeMenu + IoAccessControl: + # - FsMountNand + # - FsMountNandRoWrite + # - FsMountTwln + # - FsMountWnand + # - FsMountCardSpi + # - UseSdif3 + # - CreateSeed + # - UseCardSpi + + IdealProcessor : 0 + AffinityMask : 1 + + Priority : 16 + + MaxCpu : 0x9E # Default + + DisableDebug : true + EnableForceDebug : false + CanWriteSharedPage : true + CanUsePrivilegedPriority : false + CanUseNonAlphabetAndNumber : true + PermitMainFunctionArgument : true + CanShareDeviceMemory : true + RunnableOnSleep : false + SpecialMemoryArrange : true + + CoreVersion : 2 + DescVersion : 2 + + ReleaseKernelMajor : "02" + ReleaseKernelMinor : "33" + MemoryType : Application # Application / System / Base + HandleTableSize: 512 + IORegisterMapping: + - 1ff50000-1ff57fff + - 1ff70000-1ff77fff + MemoryMapping: + - 1f000000-1f5fffff:r + SystemCallAccess: + ArbitrateAddress: 34 + Break: 60 + CancelTimer: 28 + ClearEvent: 25 + ClearTimer: 29 + CloseHandle: 35 + ConnectToPort: 45 + ControlMemory: 1 + CreateAddressArbiter: 33 + CreateEvent: 23 + CreateMemoryBlock: 30 + CreateMutex: 19 + CreateSemaphore: 21 + CreateThread: 8 + CreateTimer: 26 + DuplicateHandle: 39 + ExitProcess: 3 + ExitThread: 9 + GetCurrentProcessorNumber: 17 + GetHandleInfo: 41 + GetProcessId: 53 + GetProcessIdOfThread: 54 + GetProcessIdealProcessor: 6 + GetProcessInfo: 43 + GetResourceLimit: 56 + GetResourceLimitCurrentValues: 58 + GetResourceLimitLimitValues: 57 + GetSystemInfo: 42 + GetSystemTick: 40 + GetThreadContext: 59 + GetThreadId: 55 + GetThreadIdealProcessor: 15 + GetThreadInfo: 44 + GetThreadPriority: 11 + MapMemoryBlock: 31 + OutputDebugString: 61 + QueryMemory: 2 + ReleaseMutex: 20 + ReleaseSemaphore: 22 + SendSyncRequest1: 46 + SendSyncRequest2: 47 + SendSyncRequest3: 48 + SendSyncRequest4: 49 + SendSyncRequest: 50 + SetThreadPriority: 12 + SetTimer: 27 + SignalEvent: 24 + SleepThread: 10 + UnmapMemoryBlock: 32 + WaitSynchronization1: 36 + WaitSynchronizationN: 37 + OpenProcess: 51 + InvalidateProcessDataCache: 82 + FlushProcessDataCache: 84 + StartInterProcessDma: 85 + GetDmaState: 87 + ControlProcessMemory: 112 + InterruptNumbers: + ServiceAccessControl: + - APT:U + - $hioFIO + - $hostio0 + - $hostio1 + - ac:u + - boss:U + - cam:u + - cecd:u + - cfg:u + - dlp:FKCL + - dlp:SRVR + - dsp::DSP + - frd:u + - fs:USER + - gsp::Gpu + - hid:USER + - http:C + - ir:u + - mic:u + - ndm:u + - news:u + - nwm::UDS + - ptm:u + - pxi:dev + - soc:U + - ssl:C + - y2r:u + - am:u + - cfg:nor + - csnd:SND + +SystemControlInfo: + SaveDataSize: 0KB # It doesn't use any save data. + RemasterVersion: 2 + StackSize: 0x40000 + # JumpId: 0 + Dependency: + ac: 0x0004013000002402L + am: 0x0004013000001502L + boss: 0x0004013000003402L + camera: 0x0004013000001602L + cecd: 0x0004013000002602L + cfg: 0x0004013000001702L + codec: 0x0004013000001802L + csnd: 0x0004013000002702L + dlp: 0x0004013000002802L + dsp: 0x0004013000001a02L + friends: 0x0004013000003202L + gpio: 0x0004013000001b02L + gsp: 0x0004013000001c02L + hid: 0x0004013000001d02L + http: 0x0004013000002902L + i2c: 0x0004013000001e02L + ir: 0x0004013000003302L + mcu: 0x0004013000001f02L + mic: 0x0004013000002002L + ndm: 0x0004013000002b02L + news: 0x0004013000003502L + nim: 0x0004013000002c02L + nwm: 0x0004013000002d02L + pdn: 0x0004013000002102L + ps: 0x0004013000003102L + ptm: 0x0004013000002202L + ro: 0x0004013000003702L + socket: 0x0004013000002e02L + spi: 0x0004013000002302L + ssl: 0x0004013000002f02L