99% working. Only issues are: data aborts when installing a theme after viewing a preview, bgm only works when installed as part of a theme shuffle. Single themes are silent
This commit is contained in:
2
Makefile
2
Makefile
@@ -50,7 +50,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
|||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g $(ARCH)
|
||||||
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
|
|
||||||
LIBS := -lctru -lm -lz
|
LIBS := -lcitro3d -lctru -lm -lz
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
|||||||
224
source/main.c
224
source/main.c
@@ -6,16 +6,52 @@
|
|||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "splashes.h"
|
#include "splashes.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
#include "ui.h"
|
||||||
|
// Taken from: https://stackoverflow.com/questions/22582989/word-wrap-program-c
|
||||||
|
inline int wordlen(const char * str){
|
||||||
|
int tempindex=0;
|
||||||
|
while(str[tempindex]!=' ' && str[tempindex]!=0 && str[tempindex]!='\n'){
|
||||||
|
++tempindex;
|
||||||
|
}
|
||||||
|
return(tempindex);
|
||||||
|
}
|
||||||
|
void wrap(char * s, const int wrapline){
|
||||||
|
|
||||||
|
int index=0;
|
||||||
|
int curlinelen = 0;
|
||||||
|
while(s[index] != '\0'){
|
||||||
|
|
||||||
|
if(s[index] == '\n'){
|
||||||
|
curlinelen=0;
|
||||||
|
}
|
||||||
|
else if(s[index] == ' '){
|
||||||
|
|
||||||
|
if(curlinelen+wordlen(&s[index+1]) >= wrapline){
|
||||||
|
s[index] = '\n';
|
||||||
|
curlinelen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
curlinelen++;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
const u32 clear_color = RGBA8(255,255,255,255);
|
||||||
|
const u32 cornflower_blue = RGBA8(100,149,237,255);
|
||||||
|
const u32 select_gray = RGBA8(176,196,222,255);
|
||||||
|
const u32 text_color = RGBA8(32,32,32,255);
|
||||||
|
const u32 shuffle_green = RGBA8(152,251,152, 127);
|
||||||
gfxInitDefault();
|
gfxInitDefault();
|
||||||
cfguInit();
|
cfguInit();
|
||||||
srvInit();
|
srvInit();
|
||||||
hidInit();
|
hidInit();
|
||||||
fsInit();
|
fsInit();
|
||||||
ptmSysmInit();
|
ptmSysmInit();
|
||||||
consoleInit(GFX_TOP, NULL);
|
|
||||||
prepare_archives();
|
prepare_archives();
|
||||||
unzip_themes();
|
unzip_themes();
|
||||||
int theme_count = get_number_entries("/Themes");
|
int theme_count = get_number_entries("/Themes");
|
||||||
@@ -24,28 +60,192 @@ int main(void)
|
|||||||
int splash_count = get_number_entries("/Splashes");
|
int splash_count = get_number_entries("/Splashes");
|
||||||
u16 *splashes_list = calloc(splash_count, PATH_LENGTH);
|
u16 *splashes_list = calloc(splash_count, PATH_LENGTH);
|
||||||
prepare_splashes(splashes_list);
|
prepare_splashes(splashes_list);
|
||||||
printf("Theme count: %i\nSplash count: %i\n", theme_count, splash_count);
|
|
||||||
|
gfxInitDefault();
|
||||||
|
gfxSet3D(false);
|
||||||
|
screen_init();
|
||||||
|
|
||||||
|
int top = 0;
|
||||||
|
int pos = 0;
|
||||||
|
const int select_size = 50;
|
||||||
|
bool change = true;
|
||||||
|
u32 kDown = hidKeysDown();
|
||||||
|
int select_count = 0;
|
||||||
|
bool splash_mode = false;
|
||||||
|
|
||||||
while (aptMainLoop())
|
while (aptMainLoop())
|
||||||
{
|
{
|
||||||
hidScanInput();
|
hidScanInput();
|
||||||
u32 kDown = hidKeysDown();
|
kDown = hidKeysDown();
|
||||||
|
if (kDown & KEY_DOWN)
|
||||||
if (kDown & KEY_A) {
|
{
|
||||||
for (int iter = 0; iter < splash_count; iter++)
|
if (pos < 3) pos++;
|
||||||
{
|
else if (top + pos < theme_count - 1) top++;
|
||||||
printu(&splashes_list[iter * PATH_LENGTH/sizeof(u16)]);
|
change = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kDown & KEY_UP)
|
||||||
|
{
|
||||||
|
if (pos > 0) pos--;
|
||||||
|
else if (top > 0) top--;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kDown & KEY_A)
|
||||||
|
{
|
||||||
|
screen_begin_frame();
|
||||||
|
screen_select(GFX_TOP);
|
||||||
|
screen_clear(GFX_TOP, clear_color);
|
||||||
|
screen_draw_rect(20, 20, 360, 200, cornflower_blue);
|
||||||
|
if (!splash_mode) screen_draw_string(25, 25, 0.7f, 0.7f, text_color, "Installing theme(s)...");
|
||||||
|
else screen_draw_string(25, 25, 0.7f, 0.7f, text_color, "Installing splash...");
|
||||||
|
screen_end_frame();
|
||||||
|
if (splash_mode) install_splash(&splashes_list[(pos + top) * PATH_LENGTH/sizeof(u16)]);
|
||||||
|
else if (select_count > 0) shuffle_install(themes_list, theme_count); else themeInstall(*themes_list[pos + top]);
|
||||||
|
screen_begin_frame();
|
||||||
|
screen_select(GFX_TOP);
|
||||||
|
screen_clear(GFX_TOP, clear_color);
|
||||||
|
screen_draw_rect(20, 20, 360, 200, cornflower_blue);
|
||||||
|
if (!splash_mode) screen_draw_string(25, 25, 0.7f, 0.7f, text_color, "Installing theme(s)...");
|
||||||
|
else screen_draw_string(25, 25, 0.7f, 0.7f, text_color, "Installing splash...");
|
||||||
|
screen_draw_string(25, 50, 0.7f, 0.7f, text_color, "Done!");
|
||||||
|
screen_end_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kDown & KEY_X)
|
||||||
|
{
|
||||||
|
bool current_select = themes_list[top + pos]->selected;
|
||||||
|
if (current_select) select_count--;
|
||||||
|
if (!current_select) select_count++;
|
||||||
|
themes_list[top + pos]->selected = !current_select;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (kDown & KEY_Y)
|
||||||
|
// {
|
||||||
|
// screen_begin_frame();
|
||||||
|
// screen_select(GFX_TOP);
|
||||||
|
// char preview_path[524];
|
||||||
|
// strcpy(preview_path, "sdmc:");
|
||||||
|
// straucat(preview_path, themes_list[top + pos]->path);
|
||||||
|
// strcat(preview_path, "/Preview.png");
|
||||||
|
// screen_load_texture_file(THEME_PREVIEW_TEXT, preview_path, true);
|
||||||
|
// screen_draw_texture(THEME_PREVIEW_TEXT, 0, 0);
|
||||||
|
// screen_select(GFX_BOTTOM);
|
||||||
|
// screen_draw_texture(THEME_PREVIEW_TEXT, -40, -240);
|
||||||
|
// screen_end_frame();
|
||||||
|
// hidScanInput();
|
||||||
|
// kDown = hidKeysDown();
|
||||||
|
// while (!(kDown & KEY_B))
|
||||||
|
// {
|
||||||
|
// hidScanInput();
|
||||||
|
// kDown = hidKeysDown();
|
||||||
|
// }
|
||||||
|
// screen_unload_texture(THEME_PREVIEW_TEXT);
|
||||||
|
// change = true;
|
||||||
|
// }
|
||||||
|
|
||||||
if (kDown & KEY_START)
|
if (kDown & KEY_START)
|
||||||
{
|
{
|
||||||
closeThemeArchives();
|
closeThemeArchives();
|
||||||
PTMSYSM_ShutdownAsync(0);
|
PTMSYSM_ShutdownAsync(0);
|
||||||
ptmSysmExit();
|
ptmSysmExit();
|
||||||
}
|
}
|
||||||
gfxFlushBuffers();
|
|
||||||
gfxSwapBuffers();
|
if (kDown & KEY_L)
|
||||||
gspWaitForVBlank();
|
{
|
||||||
|
splash_mode = !splash_mode;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen_begin_frame();
|
||||||
|
if (!change) goto end;
|
||||||
|
if (splash_mode) goto splash;
|
||||||
|
screen_select(GFX_TOP);
|
||||||
|
screen_clear(GFX_TOP, clear_color);
|
||||||
|
screen_draw_rect(20, 20, 360, 200, cornflower_blue);
|
||||||
|
char title[87];
|
||||||
|
char theme_name[0x40] = {0};
|
||||||
|
wtoa(theme_name, themes_list[top + pos]->title);
|
||||||
|
sprintf(title, "Title: %s\n", theme_name);
|
||||||
|
wrap(title, 20);
|
||||||
|
int height = screen_get_string_height(title, 0.6f, 0.6f);
|
||||||
|
screen_draw_string(210, 23, 0.6f, 0.6f, text_color, title);
|
||||||
|
char description[0x80 + 6];
|
||||||
|
char theme_desc[0x80] = {0};
|
||||||
|
wtoa(theme_desc, themes_list[top + pos]->description);
|
||||||
|
sprintf(description, "Desc: %s\n", theme_desc);
|
||||||
|
wrap(description, 23);
|
||||||
|
screen_draw_string(210, 23 + height, 0.5f, 0.5f, text_color, description);
|
||||||
|
height += screen_get_string_height(description, 0.5f, 0.5f);
|
||||||
|
char author[0x40 + 6];
|
||||||
|
char theme_auth[0x40] = {0};
|
||||||
|
wtoa(theme_auth, themes_list[top + pos]->author);
|
||||||
|
sprintf(author, "Auth: %s", theme_auth);
|
||||||
|
wrap(author, 23);
|
||||||
|
screen_draw_string(210, 23 + height, 0.5f, 0.5f, text_color, author);
|
||||||
|
screen_draw_string(23, 23, 0.8f, 0.8f, text_color, "Press Y\nfor preview");
|
||||||
|
screen_select(GFX_BOTTOM);
|
||||||
|
screen_clear(GFX_BOTTOM, clear_color);
|
||||||
|
screen_draw_rect(20, 20, 280, 200, cornflower_blue);
|
||||||
|
screen_draw_rect(20, 20 + (select_size * pos), 280, select_size, select_gray);
|
||||||
|
int y_text_pos = 37;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (i + top == theme_count)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (themes_list[i + top]->selected) screen_draw_rect(20, 20 + (select_size * i), 280, select_size, shuffle_green);
|
||||||
|
char title[0x40] = {0};
|
||||||
|
char print_title[0x40] = {0};
|
||||||
|
wtoa(title, themes_list[i + top]->title);
|
||||||
|
float width = screen_get_string_width(title, 0.6f, 0.6f);
|
||||||
|
if (width > 210)
|
||||||
|
{
|
||||||
|
memcpy(print_title, title, 0x14);
|
||||||
|
strcat(print_title, "...");
|
||||||
|
|
||||||
|
} else strcpy(print_title, title);
|
||||||
|
screen_draw_string(70, y_text_pos, 0.6f, 0.6f, text_color, print_title);
|
||||||
|
y_text_pos += 50;
|
||||||
|
}
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
splash:
|
||||||
|
screen_select(GFX_TOP);
|
||||||
|
screen_clear(GFX_TOP, clear_color);
|
||||||
|
screen_draw_rect(20, 20, 360, 200, cornflower_blue);
|
||||||
|
|
||||||
|
screen_select(GFX_BOTTOM);
|
||||||
|
screen_clear(GFX_BOTTOM, clear_color);
|
||||||
|
screen_draw_rect(20, 20, 280, 200, cornflower_blue);
|
||||||
|
screen_draw_rect(20, 20 + (select_size * pos), 280, select_size, select_gray);
|
||||||
|
|
||||||
|
int y_text_pos_splash = 37;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (i + top == splash_count)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
char path[524] = {0};
|
||||||
|
char print_path[0x40] = {0};
|
||||||
|
wtoa(path, &splashes_list[(i + top) * PATH_LENGTH/sizeof(u16)]);
|
||||||
|
float width = screen_get_string_width(&path[10], 0.6f, 0.6f);
|
||||||
|
if (width > 210)
|
||||||
|
{
|
||||||
|
memcpy(print_path, &path[10], 0x14);
|
||||||
|
strcat(print_path, "...");
|
||||||
|
|
||||||
|
} else strcpy(print_path, &path[10]);
|
||||||
|
screen_draw_string(70, y_text_pos_splash, 0.6f, 0.6f, text_color, print_path);
|
||||||
|
y_text_pos_splash += 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
screen_end_frame();
|
||||||
|
change = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxExit();
|
gfxExit();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
#include "minizip/unzip.h"
|
#include "minizip/unzip.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
Result prepare_archives()
|
Result prepare_archives()
|
||||||
{
|
{
|
||||||
@@ -246,13 +247,7 @@ Result prepare_themes(theme_data** themes_list)
|
|||||||
atow(theme_path, "/Themes/");
|
atow(theme_path, "/Themes/");
|
||||||
strucat(theme_path, entry->name);
|
strucat(theme_path, entry->name);
|
||||||
parseSmdh(theme_info, theme_path);
|
parseSmdh(theme_info, theme_path);
|
||||||
/*
|
theme_info->selected = false;
|
||||||
FOR TESTING PURPOSES ONLY, REMOVE THIS LINE LATER!!!!
|
|
||||||
*/
|
|
||||||
theme_info->selected = true;
|
|
||||||
/*
|
|
||||||
FOR TESTING PURPOSES ONLY, REMOVE ABOVE LINE LATER!!!
|
|
||||||
*/
|
|
||||||
themes_list[iter++] = theme_info;
|
themes_list[iter++] = theme_info;
|
||||||
}
|
}
|
||||||
free(entry);
|
free(entry);
|
||||||
@@ -573,18 +568,17 @@ Result themeInstall(theme_data theme_to_install)
|
|||||||
|
|
||||||
Result shuffle_install(theme_data **themes, int len)
|
Result shuffle_install(theme_data **themes, int len)
|
||||||
{
|
{
|
||||||
|
|
||||||
u8 count = 0;
|
u8 count = 0;
|
||||||
theme_data *themes_to_be_shuffled[10] = {0};
|
theme_data *themes_to_be_shuffled[10] = {0};
|
||||||
u32 body_sizes[10] = {0};
|
u32 body_sizes[10] = {0};
|
||||||
u32 bgm_sizes[10] = {0};
|
u32 bgm_sizes[10] = {0};
|
||||||
|
|
||||||
// Load themes that are selected for shuffle
|
// Load themes that are selected for shuffle
|
||||||
for (int iter = 0; iter < len; iter++)
|
for (int iter = 0; iter < len; iter++)
|
||||||
{
|
{
|
||||||
if (themes[iter]->selected == true)
|
if (themes[iter]->selected) count++;
|
||||||
count++;
|
|
||||||
if (count > 10) return(MAKERESULT(RL_USAGE, RS_INVALIDARG, RM_COMMON, RD_INVALID_SELECTION));
|
if (count > 10) return(MAKERESULT(RL_USAGE, RS_INVALIDARG, RM_COMMON, RD_INVALID_SELECTION));
|
||||||
themes_to_be_shuffled[iter] = themes[iter];
|
if (themes[iter]->selected) themes_to_be_shuffled[count - 1] = themes[iter];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load and edit SaveData
|
// Load and edit SaveData
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ static void screen_set_blend(u32 color, bool rgb, bool alpha)
|
|||||||
C3D_TexEnvColor(env, color);
|
C3D_TexEnvColor(env, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void screen_clear(gfxScreen_t screen, u32 color)
|
void screen_clear(gfxScreen_t screen, u32 color)
|
||||||
{
|
{
|
||||||
C3D_FrameBufClear(screen == GFX_TOP ? &target_top->frameBuf : &target_bottom->frameBuf, C3D_CLEAR_ALL, color, 0);
|
C3D_FrameBufClear(screen == GFX_TOP ? &target_top->frameBuf : &target_bottom->frameBuf, C3D_CLEAR_ALL, color, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,7 @@
|
|||||||
|
|
||||||
#define MAX_TEXTURES 1024
|
#define MAX_TEXTURES 1024
|
||||||
|
|
||||||
#define TEXTURE_BOTTOM_SCREEN_BG 0
|
#define THEME_PREVIEW_TEXT 0
|
||||||
#define TEXTURE_TOP_SCREEN_BG 1
|
|
||||||
#define TEXTURE_ICON 2
|
|
||||||
#define TEXTURE_DRIVE_ICON 3
|
|
||||||
|
|
||||||
#define RGBA8(r, g, b, a) ((((a)&0xFF)<<24) | (((b)&0xFF)<<16) | (((g)&0xFF)<<8) | (((r)&0xFF)<<0))
|
#define RGBA8(r, g, b, a) ((((a)&0xFF)<<24) | (((b)&0xFF)<<16) | (((g)&0xFF)<<8) | (((r)&0xFF)<<0))
|
||||||
|
|
||||||
@@ -56,5 +53,6 @@ void screen_draw_string(float x, float y, float scaleX, float scaleY, u32 color,
|
|||||||
void screen_draw_stringf(float x, float y, float scaleX, float scaleY, u32 color, const char * text, ...);
|
void screen_draw_stringf(float x, float y, float scaleX, float scaleY, u32 color, const char * text, ...);
|
||||||
void screen_draw_string_wrap(float x, float y, float scaleX, float scaleY, u32 color, float wrapX, const char * text);
|
void screen_draw_string_wrap(float x, float y, float scaleX, float scaleY, u32 color, float wrapX, const char * text);
|
||||||
void screen_draw_rect(float x, float y, float width, float height, u32 color);
|
void screen_draw_rect(float x, float y, float width, float height, u32 color);
|
||||||
|
void screen_clear(gfxScreen_t screen, u32 color);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -128,6 +128,17 @@ u16 *struacat(u16 *destination, const char *source)
|
|||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *straucat(char *destination, const u16 *source)
|
||||||
|
{
|
||||||
|
ssize_t len = strlen(destination);
|
||||||
|
for (u16 i = len; i < strulen(source) + len; i++)
|
||||||
|
{
|
||||||
|
destination[i] = source[i - len];
|
||||||
|
}
|
||||||
|
destination[strulen(source) + len] = 0;
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
|
||||||
// Prints a u16* for debug purposes
|
// Prints a u16* for debug purposes
|
||||||
// Must be properly null-terminated
|
// Must be properly null-terminated
|
||||||
void printu(u16 *input)
|
void printu(u16 *input)
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ u16 *strucpy(u16*, const u16*);
|
|||||||
ssize_t strulen(const u16*);
|
ssize_t strulen(const u16*);
|
||||||
u16 *strucat(u16*, const u16*);
|
u16 *strucat(u16*, const u16*);
|
||||||
u16 *struacat(u16*, const char*);
|
u16 *struacat(u16*, const char*);
|
||||||
|
char *straucat(char *destination, const u16 *source);
|
||||||
void printu(u16*);
|
void printu(u16*);
|
||||||
Reference in New Issue
Block a user