-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Also now uses a shared font to display text.
- Loading branch information
Showing
5 changed files
with
155 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
# SharedFontDumper | ||
Dumps the Switch's shared fonts to individual .ttfs or dumps the entire memory region to .bin for use in Ryujinx and yuzu. | ||
Dumps the Switch's shared fonts to individual .ttfs, or dumps the entire memory region to .bin for use in Ryujinx and yuzu. | ||
|
||
Huge thanks to shchmue for her help with text rendering. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,115 +1,102 @@ | ||
#include <malloc.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/stat.h> | ||
#include "text.h" | ||
|
||
#include <switch.h> | ||
|
||
#define MEMSIZE 0x1100000 | ||
#define DIRNAME "fonts" | ||
#define SUCCESS "\n\nSuccessfully dumped shared fonts!\n\n\n\nPress + to exit." | ||
#define IOERROR "Error: Failed to open file for writing.\n" | ||
|
||
int DumpMem(void) { | ||
void DumpMem() { | ||
FILE *outFile; | ||
u8 *buf = malloc(MEMSIZE); | ||
|
||
if (!(outFile = fopen("fonts/shared_font.bin", "wb"))) { | ||
fputs(IOERROR, stderr); | ||
draw_text(0x10, 0x60, RED, IOERROR); | ||
goto exit; | ||
} | ||
|
||
puts("\nDumping shared font memory...\n"); | ||
draw_text(0x10, 0x60, SKYBLUE, "Dumping shared font memory..."); | ||
text_update(); | ||
|
||
memcpy(buf, plGetSharedmemAddr(), MEMSIZE); | ||
|
||
fwrite(buf, MEMSIZE, 1, outFile); | ||
fwrite(buf, sizeof(u8), MEMSIZE, outFile); | ||
free(buf); | ||
|
||
exit: | ||
fclose(outFile); | ||
|
||
gfxFlushBuffers(); | ||
gfxSwapBuffers(); | ||
gfxWaitForVsync(); | ||
|
||
return 0; | ||
} | ||
|
||
int DumpFont(PlSharedFontType type, char *name) { | ||
int Dumped = 0; | ||
|
||
void DumpFont(PlSharedFontType type, char *name) { | ||
FILE *outFile; | ||
char *newName = malloc(strlen(DIRNAME) + strlen(name) + 1); | ||
|
||
char *newName = malloc(strlen(DIRNAME) + strlen(name) + 2), | ||
*str = malloc(strlen(name) + 0x10); | ||
|
||
PlFontData font; | ||
|
||
sprintf(newName, "%s/%s", DIRNAME, name); | ||
printf("Dumping %s...\n", name); | ||
|
||
|
||
if (!(outFile = fopen(newName, "wb"))) { | ||
fputs(IOERROR, stderr); | ||
draw_text(0x10, 0x60, RED, IOERROR); | ||
goto exit; | ||
} | ||
|
||
|
||
sprintf(str, "Dumping %s...\n", name); | ||
|
||
draw_text(0x10, 0x60 + 0x20 * Dumped++, SKYBLUE, str); | ||
text_update(); | ||
|
||
plGetSharedFontByType(&font, type); | ||
|
||
u8 *buf = malloc(font.size); | ||
|
||
memcpy(buf, font.address, font.size); | ||
|
||
fwrite(buf, font.size, 1, outFile); | ||
fwrite(buf, sizeof(u8), font.size, outFile); | ||
free(buf); | ||
|
||
exit: | ||
free(newName); | ||
free(str); | ||
fclose(outFile); | ||
|
||
gfxFlushBuffers(); | ||
gfxSwapBuffers(); | ||
gfxWaitForVsync(); | ||
|
||
return 0; | ||
} | ||
|
||
int main(void) { | ||
void main() { | ||
int kDown, isDone = 0; | ||
struct stat *sb = memalign(0x1000, sizeof *sb); | ||
|
||
gfxInitDefault(); | ||
consoleInit(NULL); | ||
plInitialize(); | ||
plInitialize(); | ||
text_init(); | ||
|
||
puts("Press A to dump fonts as ttf, or press X to dump the shared font memory.\n\n"); | ||
|
||
if (stat(DIRNAME, sb)) | ||
mkdir(DIRNAME, 0777); | ||
|
||
draw_text(0x10, 0x20, WHITE, "Press A to dump fonts as ttf, or press X to dump the shared font memory."); | ||
text_update(); | ||
|
||
while (appletMainLoop()) { | ||
hidScanInput(); | ||
kDown = hidKeysDown(CONTROLLER_P1_AUTO); | ||
|
||
if (kDown & KEY_A && !isDone++) { | ||
DumpFont(PlSharedFontType_Standard, "FontStandard.ttf"); | ||
DumpFont(PlSharedFontType_Standard, "FontStandard.ttf"); | ||
DumpFont(PlSharedFontType_ChineseSimplified, "FontChineseSimplified.ttf"); | ||
DumpFont(PlSharedFontType_ExtChineseSimplified, "FontExtendedChineseSimplified.ttf"); | ||
DumpFont(PlSharedFontType_ChineseTraditional, "FontChineseTraditional.ttf"); | ||
DumpFont(PlSharedFontType_KO, "FontKorean.ttf"); | ||
DumpFont(PlSharedFontType_NintendoExt, "FontNintendoExtended.ttf"); | ||
puts(SUCCESS); | ||
DumpFont(PlSharedFontType_KO, "FontKorean.ttf"); | ||
DumpFont(PlSharedFontType_NintendoExt, "FontNintendoExtended.ttf"); | ||
draw_text(0x10, 0x80 + 0x20 * Dumped, GREEN, SUCCESS); | ||
} | ||
|
||
if (kDown & KEY_X && !isDone++) { | ||
DumpMem(); | ||
puts(SUCCESS); | ||
draw_text(0x10, 0xa0, GREEN, SUCCESS); | ||
} | ||
|
||
if (kDown & KEY_PLUS) break; | ||
|
||
gfxFlushBuffers(); | ||
gfxSwapBuffers(); | ||
gfxWaitForVsync(); | ||
text_update(); | ||
} | ||
|
||
gfxExit(); | ||
|
||
free(sb); | ||
|
||
text_exit(); | ||
plExit(); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* All code in this document was adapted from shchmue's Lockpick! */ | ||
|
||
#include "text.h" | ||
|
||
static u32 framebuf_width = 0; | ||
static u32 stride; | ||
static u32 *framebuf; | ||
static Framebuffer fb; | ||
static FT_Library library; | ||
static FT_Face face; | ||
|
||
void draw_glyph(FT_Bitmap *bitmap, u32 x, u32 y, u32 color) { | ||
u32 framex, framey; | ||
u8* imageptr = bitmap->buffer; | ||
|
||
for (u32 tmpy = 0; tmpy < bitmap->rows; tmpy++) { | ||
for (u32 tmpx = 0; tmpx < bitmap->width; tmpx++) { | ||
framex = x + tmpx; | ||
framey = y + tmpy; | ||
|
||
framebuf[framey * framebuf_width + framex] = RGBA8_MAXALPHA(imageptr[tmpx], imageptr[tmpx], imageptr[tmpx]) & color; | ||
} | ||
|
||
imageptr += bitmap->pitch; | ||
} | ||
} | ||
|
||
void draw_text(u32 x, u32 y, u32 color, const char *str) { | ||
u32 tmpx = x; | ||
FT_UInt glyph_index; | ||
FT_GlyphSlot slot = face->glyph; | ||
|
||
for (size_t i = 0; i < strlen(str); i++) { | ||
if (str[i] == '\n') { | ||
tmpx = x; | ||
y += face->size->metrics.height >> 6; | ||
continue; | ||
} | ||
|
||
glyph_index = FT_Get_Char_Index(face, (FT_ULong)str[i]); | ||
|
||
if (R_FAILED(FT_Load_Glyph(face, glyph_index, FT_LOAD_COLOR) || | ||
FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL) != 0)) | ||
return; | ||
|
||
draw_glyph(&slot->bitmap, tmpx + slot->bitmap_left, y - slot->bitmap_top, color); | ||
|
||
tmpx += slot->advance.x >> 6; | ||
y += slot->advance.y >> 6; | ||
} | ||
} | ||
|
||
void text_init() { | ||
PlFontData font; | ||
plGetSharedFontByType(&font, PlSharedFontType_Standard); | ||
|
||
FT_Init_FreeType(&library); | ||
FT_New_Memory_Face(library, font.address, font.size, 0, &face); | ||
FT_Set_Char_Size(face, 0, 6*64, 300, 300); | ||
|
||
framebufferCreate(&fb, nwindowGetDefault(), 1280, 720, PIXEL_FORMAT_RGBA_8888, 2); | ||
framebufferMakeLinear(&fb); | ||
framebuf = (u32 *)framebufferBegin(&fb, &stride); | ||
framebuf_width = stride / sizeof(u32); | ||
memset(framebuf, 0, stride*720); | ||
framebufferEnd(&fb); | ||
} | ||
|
||
void text_update() { | ||
framebufferBegin(&fb, &stride); | ||
framebufferEnd(&fb); | ||
} | ||
|
||
void text_exit() { | ||
framebufferClose(&fb); | ||
|
||
FT_Done_Face(face); | ||
FT_Done_FreeType(library); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#include <malloc.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/stat.h> | ||
|
||
#include <switch.h> | ||
#include <ft2build.h> | ||
|
||
#include FT_FREETYPE_H | ||
|
||
#define MEMSIZE 0x1100000 | ||
|
||
#define RED RGBA8_MAXALPHA(0xff, 0, 0) | ||
#define GREEN RGBA8_MAXALPHA(0, 0xff, 0) | ||
#define WHITE RGBA8_MAXALPHA(0xff, 0xff, 0xff) | ||
#define SKYBLUE RGBA8_MAXALPHA(0xa0, 0xff, 0xff) | ||
|
||
#define DIRNAME "fonts" | ||
#define SUCCESS "Successfully dumped shared fonts!\n\nPress + to exit." | ||
#define IOERROR "Error: Failed to open file for writing.\n" | ||
|
||
void draw_glyph(FT_Bitmap *bitmap, u32 x, u32 y, u32 color); | ||
void draw_text(u32 x, u32 y, u32 color, const char *str); | ||
void text_init(); | ||
void text_update(); | ||
void text_exit(); |