From 21ed92647234cc6f9148c336c1b63172e9203297 Mon Sep 17 00:00:00 2001 From: ELY M Date: Sat, 19 Dec 2020 20:27:37 -0600 Subject: [PATCH] update to 3.4.0 --- .gitignore | 2 + Makefile | 2 +- Makefile.nx | 4 +- common/common.h | 1 + common/font.c | 14 +++- common/language.c | 2 + common/menu-entry.c | 71 +++++++++++++----- common/menu-list.c | 2 + common/menu.c | 40 ++++++++-- common/menu.h | 3 +- common/netloader.c | 10 ++- common/theme.c | 2 +- nx_main/loaders/builtin.c | 2 +- nx_main/main.c | 89 +++++++++++------------ nx_main/nx_graphics.c | 141 ++++++++++++++++++++++++++++++++++++ nx_main/nx_graphics.h | 9 +++ nx_main/nx_touch.c | 52 ++++++------- nx_main/nx_touch.h | 6 +- resources/eth_none_icon.png | Bin 0 -> 481 bytes settings.cfg | 4 + 20 files changed, 348 insertions(+), 108 deletions(-) create mode 100644 nx_main/nx_graphics.c create mode 100644 nx_main/nx_graphics.h create mode 100644 resources/eth_none_icon.png create mode 100644 settings.cfg diff --git a/.gitignore b/.gitignore index c31d98d..793748d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.*/ *~ *.exe *.o @@ -13,3 +14,4 @@ build *.nro test.* switch +nx-hbmenu* diff --git a/Makefile b/Makefile index ffb6561..8e70875 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -export APP_VERSION := 3.2.0 +export APP_VERSION := 3.4.0-elys-mod ifeq ($(RELEASE),) export APP_VERSION := $(APP_VERSION)-$(shell git describe --dirty --always) diff --git a/Makefile.nx b/Makefile.nx index fc7005e..6968c54 100644 --- a/Makefile.nx +++ b/Makefile.nx @@ -46,7 +46,7 @@ ROMFS := romfs DIST_PATH := $(TARGET)_v$(APP_VERSION) -APP_AUTHOR := switchbrew +APP_AUTHOR := switchbrew - modded by ELY M. #--------------------------------------------------------------------------------- # options for code generation @@ -63,7 +63,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions ASFLAGS := -g $(ARCH) LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) -LIBS := -lminizip `freetype-config --libs` -lconfig -lturbojpeg -lpng +LIBS := -ldeko3d -lminizip `freetype-config --libs` -lconfig -lturbojpeg -lpng #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/common/common.h b/common/common.h index c373932..1ebd67d 100644 --- a/common/common.h +++ b/common/common.h @@ -21,6 +21,7 @@ #include typedef uint8_t u8; +typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; typedef int8_t s8; diff --git a/common/font.c b/common/font.c index a4c4e39..42a5b8b 100644 --- a/common/font.c +++ b/common/font.c @@ -9,6 +9,10 @@ #define FONT_FACES_MAX 2 #endif +#ifdef __SWITCH__ +static bool s_plinited; +#endif + static FT_Error s_font_libret=1, s_font_facesret[FONT_FACES_MAX]; static FT_Library s_font_library; @@ -364,7 +368,11 @@ bool fontInitialize(void) PlFontData fonts[PlSharedFontType_Total]; Result rc=0; - rc = plGetSharedFont(textGetLanguageCode(), fonts, FONT_FACES_MAX, &s_font_faces_total); + rc = plInitialize(PlServiceType_User); + if (R_SUCCEEDED(rc)) { + s_plinited = true; + rc = plGetSharedFont(textGetLanguageCode(), fonts, FONT_FACES_MAX, &s_font_faces_total); + } if (R_FAILED(rc)) return false; for (i=0; ipath)) return false; @@ -504,9 +504,28 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_ // Initialize the argument data argData_s* ad = &me->args; + argData_s* ad_assoc = &fileassoc_me->args; + char *arg_src = (char*)&ad_assoc->buf[1]; + bool ftoken_found=0; ad->dst = (char*)&ad->buf[1]; - launchAddArg(ad, fileassoc_me->path); - launchAddArg(ad, me->path); + + for (u32 argi=0; argibuf[0]; argi++, arg_src+= strlen(arg_src)+1) { + if (argi) { + strptr = strchr(arg_src, '%'); + if (strptr && strptr[0] && strptr[1] && (strptr == arg_src || strptr[-1] != '\\')) { + if (strptr[1] == 'f') { + memset(tempbuf, 0, sizeof(tempbuf)); + snprintf(tempbuf, sizeof(tempbuf)-1, "%.*s%s%s", (int)((uintptr_t)strptr-(uintptr_t)arg_src), arg_src, me->path, &strptr[2]); + launchAddArg(ad, tempbuf); + ftoken_found = 1; + continue; + } + } + } + + launchAddArg(ad, arg_src); + } + if (!ftoken_found) launchAddArg(ad, me->path); strncpy(me->path, fileassoc_me->path, sizeof(me->path)); me->path[sizeof(me->path)-1] = 0; @@ -527,12 +546,12 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut, bool check_ } void menuEntryFileassocLoad(const char* filepath) { - bool success=0, success2=0; + bool success=0, iconLoaded=0; menuEntry_s* me = NULL; - config_setting_t *fileassoc = NULL, *targets = NULL, *target = NULL; + config_setting_t *fileassoc = NULL, *targets = NULL, *target = NULL, *app_args = NULL, *target_args = NULL; config_t cfg = {0}; - int targets_len=0, i; + int targets_len=0, args_len=0, i; const char *strptr = NULL; char app_path[PATH_MAX+8]; @@ -541,8 +560,8 @@ void menuEntryFileassocLoad(const char* filepath) { char target_file_extension[PATH_MAX+1]; char target_filename[PATH_MAX+1]; - char app_author[ENTRY_AUTHORLENGTH+1]; - char app_version[ENTRY_VERLENGTH+1]; + char app_author[ENTRY_AUTHORLENGTH+2]; + char app_version[ENTRY_VERLENGTH+2]; uint8_t *app_icon_gfx = NULL; uint8_t *app_icon_gfx_small = NULL; @@ -564,7 +583,8 @@ void menuEntryFileassocLoad(const char* filepath) { snprintf(app_path, sizeof(app_path)-1, "%s%s", menuGetRootBasePath(), strptr); if (config_setting_lookup_string(fileassoc, "icon_path", &strptr)) snprintf(main_icon_path, sizeof(main_icon_path)-1, "%s%s", menuGetRootBasePath(), strptr); - targets = config_setting_get_member(fileassoc, "targets"); + app_args = config_setting_lookup(fileassoc, "app_args"); + targets = config_setting_lookup(fileassoc, "targets"); if (app_path[0] && targets) { targets_len = config_setting_length(targets); @@ -610,12 +630,13 @@ void menuEntryFileassocLoad(const char* filepath) { strncpy(target_file_extension, strptr, sizeof(target_file_extension)-1); if (config_setting_lookup_string(target, "filename", &strptr)) strncpy(target_filename, strptr, sizeof(target_filename)-1); + target_args = config_setting_lookup(target, "app_args"); //string_is_set for target_file_extension and target_filename must differ: only 1 can be set, not both set or both not set. if ((target_file_extension[0]!=0) == (target_filename[0]!=0)) continue; me = menuCreateEntry(ENTRY_TYPE_FILEASSOC); - success2 = 0; + iconLoaded = 0; if (me) { strncpy(me->path, app_path, sizeof(me->path)); @@ -634,22 +655,32 @@ void menuEntryFileassocLoad(const char* filepath) { } me->fileassoc_str[sizeof(me->fileassoc_str)-1] = 0; - if (target_icon_path[0]) success2 = menuEntryLoadExternalIcon(me, target_icon_path); - if (!success2 && main_icon_path[0]) success2 = menuEntryLoadExternalIcon(me, main_icon_path); + if (target_icon_path[0]) iconLoaded = menuEntryLoadExternalIcon(me, target_icon_path); + if (!iconLoaded && main_icon_path[0]) iconLoaded = menuEntryLoadExternalIcon(me, main_icon_path); - if (success2) { + if (iconLoaded) { menuEntryParseIcon(me); } else { - success2 = menuEntryImportIconGfx(me, app_icon_gfx, app_icon_gfx_small); + iconLoaded = menuEntryImportIconGfx(me, app_icon_gfx, app_icon_gfx_small); + } + + argData_s* ad = &me->args; + ad->dst = (char*)&ad->buf[1]; + launchAddArg(ad, me->path); + + config_setting_t *config_args = target_args ? target_args : app_args; + if (config_args) { + args_len = config_setting_length(config_args); + for (int argi=0; argilastEntry = me; } m->xPos = 0; + m->slideSpeed = 0; m->nEntries ++; } @@ -59,6 +60,7 @@ static void menuAddEntryToFront(menuEntry_s* me) { m->lastEntry = me; } m->xPos = 0; + m->slideSpeed = 0; m->nEntries ++; } diff --git a/common/menu.c b/common/menu.c index fe9c3f3..9c8543c 100644 --- a/common/menu.c +++ b/common/menu.c @@ -6,6 +6,8 @@ #include "switch/runtime/nxlink.h" #endif +double menuTimer; + char rootPathBase[PATH_MAX]; char rootPath[PATH_MAX+8]; @@ -764,8 +766,11 @@ void menuLoop(void) { menuCloseMsgBox(); menuMsgBoxSetNetloaderState(0, NULL, 0, 0); + } - if (netloader_state.errormsg[0]) menuCreateMsgBox(780,300, netloader_state.errormsg); + if (netloader_state.errormsg[0]) { + menuCloseMsgBox(); + menuCreateMsgBox(780,300, netloader_state.errormsg); } if(hbmenu_state == HBMENU_NETLOADER_ACTIVE) { @@ -796,14 +801,35 @@ void menuLoop(void) { int entries_count = layoutobj->posEnd[0]; layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList]; - if (menu->nEntries > entries_count) { - int wanted_x = clamp(-menu->curEntry * layoutobj->posEnd[0], -(menu->nEntries - entries_count) * layoutobj->posEnd[0], 0); - menu->xPos += v; - v += (wanted_x - menu->xPos) / 3; - v /= 2; + // Gentle Realign only when not manually moving + if (menu->slideSpeed == 0) { + if (menu->nEntries > entries_count) { + int wanted_x = clamp(-menu->curEntry * layoutobj->posEnd[0], -(menu->nEntries - entries_count) * layoutobj->posEnd[0], 0); + menu->xPos += v; + v += (wanted_x - menu->xPos) / 3; + v /= 2; + } + else { + menu->xPos = v = 0; + } } else { - menu->xPos = v = 0; + menu->xPos += menu->slideSpeed; + + if (abs(menu->slideSpeed) > 2) { + // Slow down way faster when outside the normal bounds + if (menu->xPos > 0 || menu->xPos < -(menu->nEntries) * layoutobj->posEnd[0]) { + menu->slideSpeed *= .5f; + } + else { + menu->slideSpeed *= .9f; + } + } + else { + menu->slideSpeed = 0; + } + + menu->curEntry = clamp(roundf(-((float) menu->xPos / layoutobj->posEnd[0])), 0, menu->nEntries); } menuEntry_s *active_entry = NULL; diff --git a/common/menu.h b/common/menu.h index 7ac6aa2..e7ae396 100644 --- a/common/menu.h +++ b/common/menu.h @@ -33,6 +33,7 @@ struct menu_s_tag int nEntries; int curEntry; int xPos; + int slideSpeed; char dirname[PATH_MAX+1]; }; @@ -77,7 +78,7 @@ typedef enum IMAGE_MODE_RGBA32 } ImageMode; -double menuTimer; +extern double menuTimer; #ifdef __cplusplus extern "C" { diff --git a/common/netloader.c b/common/netloader.c index aa5a09a..039d718 100644 --- a/common/netloader.c +++ b/common/netloader.c @@ -567,7 +567,15 @@ int netloader_activate(void) { return -1; } - int rc = bind(netloader_listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); + uint32_t tmpval=1; + int rc = setsockopt(netloader_listenfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&tmpval, sizeof(tmpval)); + if(rc != 0) + { + netloader_socket_error("setsockopt"); + return -1; + } + + rc = bind(netloader_listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if(rc != 0) { netloader_socket_error("bind"); diff --git a/common/theme.c b/common/theme.c index 25e12cb..108ff38 100644 --- a/common/theme.c +++ b/common/theme.c @@ -308,7 +308,7 @@ void themeStartup(ThemePreset preset) { [ThemeLayoutId_NetworkIcon] = { .visible = true, .posType = true, - .posStart = {0, 0 + 47 + 10 + 3}, + .posStart = {-63, 0 + 47 + 10 + 3}, }, [ThemeLayoutId_BatteryCharge] = { diff --git a/nx_main/loaders/builtin.c b/nx_main/loaders/builtin.c index 980f4a5..666444b 100644 --- a/nx_main/loaders/builtin.c +++ b/nx_main/loaders/builtin.c @@ -71,7 +71,7 @@ static void launchFile(const char* path, argData_s* args) Result rc = envSetNextLoad(path, argBuf); if(R_FAILED(rc)) { memset(msg, 0, sizeof(msg)); - snprintf(msg, sizeof(msg)-1, "%s\n0x%x", textGetString(StrId_AppLaunchError), rc); + snprintf(msg, sizeof(msg)-1, "%s\n2%03d-%04d", textGetString(StrId_AppLaunchError), R_MODULE(rc), R_DESCRIPTION(rc)); menuCreateMsgBox(780, 300, msg); } diff --git a/nx_main/main.c b/nx_main/main.c index a9c6277..b3a176e 100644 --- a/nx_main/main.c +++ b/nx_main/main.c @@ -3,17 +3,19 @@ #include #include "../common/common.h" +#include "nx_graphics.h" #include "nx_touch.h" // Define the desired framebuffer resolution (here we set it to 720p). #define FB_WIDTH 1280 #define FB_HEIGHT 720 -Framebuffer g_framebufObj; - uint8_t* g_framebuf; u32 g_framebuf_width; +PadState g_pad; +PadRepeater g_pad_repeater; + bool menuUpdateErrorScreen(void); #ifdef PERF_LOG @@ -39,26 +41,28 @@ int main(int argc, char **argv) u64 start_tick=0; #endif + padConfigureInput(8, HidNpadStyleSet_NpadStandard); + padInitializeAny(&g_pad); + padRepeaterInitialize(&g_pad_repeater, 20, 10); + hidSetNpadHandheldActivationMode(HidNpadHandheldActivationMode_Single); + touchInit(); + memset(errormsg, 0, sizeof(errormsg)); appletLockExit(); appletSetScreenShotPermission(AppletScreenShotPermission_Enable); - ColorSetId theme; + ColorSetId theme = ColorSetId_Light; rc = setsysInitialize(); - if (R_FAILED(rc)) snprintf(errormsg, sizeof(errormsg)-1, "Error: setsysInitialize() failed: 0x%x.", rc); - - if (R_SUCCEEDED(rc)) setsysGetColorSetId(&theme); - if (R_SUCCEEDED(rc)) { - rc = plInitialize(); - if (R_FAILED(rc)) snprintf(errormsg, sizeof(errormsg)-1, "Error: plInitialize() failed: 0x%x.", rc); + setsysGetColorSetId(&theme); + setsysExit(); } if (R_SUCCEEDED(rc)) { rc = textInit(); if (R_FAILED(rc)) { - snprintf(errormsg, sizeof(errormsg)-1, "Error: textInit() failed: 0x%x.", rc); + snprintf(errormsg, sizeof(errormsg)-1, "Error: textInit() failed: 2%03d-%04d", R_MODULE(rc), R_DESCRIPTION(rc)); } } @@ -67,7 +71,7 @@ int main(int argc, char **argv) if (R_SUCCEEDED(rc)) { rc = assetsInit(); if (R_FAILED(rc)) { - snprintf(errormsg, sizeof(errormsg)-1, "Error: assetsInit() failed: 0x%x.", rc); + snprintf(errormsg, sizeof(errormsg)-1, "Error: assetsInit() failed: 2%03d-%04d", R_MODULE(rc), R_DESCRIPTION(rc)); } } @@ -78,7 +82,7 @@ int main(int argc, char **argv) if (R_SUCCEEDED(rc)) { rc = netloaderInit(); if (R_FAILED(rc)) { - snprintf(errormsg, sizeof(errormsg)-1, "Error: netloaderInit() failed: 0x%x.", rc); + snprintf(errormsg, sizeof(errormsg)-1, "Error: netloaderInit() failed: 2%03d-%04d", R_MODULE(rc), R_DESCRIPTION(rc)); } } @@ -115,7 +119,7 @@ int main(int argc, char **argv) if (R_FAILED(lastret)) { memset(msg, 0, sizeof(msg)); - snprintf(msg, sizeof(msg)-1, "%s\n0x%x", textGetString(StrId_LastLoadResult), lastret); + snprintf(msg, sizeof(msg)-1, "%s\n2%03d-%04d", textGetString(StrId_LastLoadResult), R_MODULE(lastret), R_DESCRIPTION(lastret)); menuCreateMsgBox(780, 300, msg); } @@ -124,8 +128,7 @@ int main(int argc, char **argv) if (errormsg[0]) error_screen = 1; if (!error_screen) { - framebufferCreate(&g_framebufObj, nwindowGetDefault(), FB_WIDTH, FB_HEIGHT, PIXEL_FORMAT_RGBA_8888, 2); - framebufferMakeLinear(&g_framebufObj); + graphicsInit(FB_WIDTH, FB_HEIGHT); } else { consoleInit(NULL); @@ -135,16 +138,17 @@ int main(int argc, char **argv) while (appletMainLoop()) { - - - //Scan all the inputs. This should be done once for each frame - hidScanInput(); + // Scan the gamepad. This should be done once for each frame + padUpdate(&g_pad); + padRepeaterUpdate(&g_pad_repeater, padGetButtons(&g_pad) & ( + HidNpadButton_AnyLeft | HidNpadButton_AnyUp | HidNpadButton_AnyRight | HidNpadButton_AnyDown + )); if (!error_screen) { if (!uiUpdate()) break; - g_framebuf = framebufferBegin(&g_framebufObj, &g_framebuf_width); + g_framebuf = graphicsFrameBegin(&g_framebuf_width); #ifdef PERF_LOG - start_tick = svcGetSystemTick(); + start_tick = armGetSystemTick(); #endif memset(g_framebuf, 237, g_framebuf_width * FB_HEIGHT); menuLoop(); @@ -154,10 +158,10 @@ int main(int argc, char **argv) } if (!error_screen) { - framebufferEnd(&g_framebufObj); + graphicsFrameEnd(); #ifdef PERF_LOG - g_tickdiff_frame = svcGetSystemTick() - start_tick; + g_tickdiff_frame = armGetSystemTick() - start_tick; #endif } else { @@ -166,7 +170,7 @@ int main(int argc, char **argv) } if (!error_screen) { - framebufferClose(&g_framebufObj); + graphicsExit(); } else { consoleExit(NULL); @@ -185,8 +189,6 @@ int main(int argc, char **argv) netloaderExit(); powerExit(); assetsExit(); - plExit(); - setsysExit(); appletUnlockExit(); @@ -194,14 +196,9 @@ int main(int argc, char **argv) } u64 menuGetKeysDown(void) { - u64 down = 0; - - for (u32 controller=0; controller<8; controller++) { - if (hidIsControllerConnected(controller)) down |= hidKeysDown(controller); - } - if (hidIsControllerConnected(CONTROLLER_HANDHELD)) down |= hidKeysDown(CONTROLLER_HANDHELD); - - return down; + u64 keys = padGetButtonsDown(&g_pad); + keys |= padRepeaterGetButtons(&g_pad_repeater); + return keys; } //This is implemented here due to the hid code. @@ -211,29 +208,29 @@ bool menuUpdate(void) { u64 down = menuGetKeysDown(); ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles]; int entries_count = layoutobj->posEnd[0]; - + handleTouch(menu); - if (down & KEY_Y) + if (down & HidNpadButton_Y) { launchMenuNetloaderTask(); } - else if (down & KEY_X) + else if (down & HidNpadButton_X) { menuHandleXButton(); } - else if (down & KEY_A) + else if (down & HidNpadButton_A) { menuHandleAButton(); } - else if (down & KEY_B) + else if (down & HidNpadButton_B) { launchMenuBackTask(); } - else if(down & KEY_MINUS){ + else if(down & HidNpadButton_Minus){ themeMenuStartup(); } - else if (down & KEY_PLUS) + else if (down & HidNpadButton_Plus) { exitflag = 1; } @@ -241,10 +238,10 @@ bool menuUpdate(void) { { int move = 0; - if (down & KEY_LEFT) move--; - if (down & KEY_RIGHT) move++; - if (down & KEY_DOWN) move-=entries_count; - if (down & KEY_UP) move+=entries_count; + if (down & HidNpadButton_AnyLeft) move--; + if (down & HidNpadButton_AnyRight) move++; + if (down & HidNpadButton_AnyDown) move-=entries_count; + if (down & HidNpadButton_AnyUp) move+=entries_count; int newEntry = menu->curEntry + move; if (newEntry < 0) newEntry = 0; @@ -259,7 +256,7 @@ bool menuUpdateErrorScreen(void) { bool exitflag = 0; u64 down = menuGetKeysDown(); - if (down & KEY_PLUS) + if (down & HidNpadButton_Plus) { exitflag = 1; } diff --git a/nx_main/nx_graphics.c b/nx_main/nx_graphics.c new file mode 100644 index 0000000..ce7e5f8 --- /dev/null +++ b/nx_main/nx_graphics.c @@ -0,0 +1,141 @@ +#include +#include + +#include "nx_graphics.h" + +#define FB_NUM 2 +#define CMDMEMSIZE 0x1000 + +static u32 s_fbWidth, s_fbHeight; + +static DkDevice s_device; +static DkMemBlock s_fbMemBlock, s_workMemBlock, s_cmdMemBlock; +static DkSwapchain s_swapchain; +static DkCmdBuf s_cmdBuf; +static DkCmdList s_cmdLists[FB_NUM]; +static DkFence s_fence; +static DkQueue s_queue; + +void graphicsInit(u32 width, u32 height) +{ + DkImageLayoutMaker imgLayoutMaker; + DkMemBlockMaker memBlockMaker; + + // Create the device, which is the root object + DkDeviceMaker deviceMaker; + dkDeviceMakerDefaults(&deviceMaker); + s_device = dkDeviceCreate(&deviceMaker); + + // Calculate layout for the framebuffers + DkImageLayout fbLayout; + dkImageLayoutMakerDefaults(&imgLayoutMaker, s_device); + imgLayoutMaker.flags = DkImageFlags_UsagePresent; + imgLayoutMaker.format = DkImageFormat_RGBA8_Unorm; + imgLayoutMaker.dimensions[0] = s_fbWidth = width; + imgLayoutMaker.dimensions[1] = s_fbHeight = height; + dkImageLayoutInitialize(&fbLayout, &imgLayoutMaker); + + // Retrieve necessary size and alignment for the framebuffers + uint32_t fbSize = dkImageLayoutGetSize(&fbLayout); + uint32_t fbAlign = dkImageLayoutGetAlignment(&fbLayout); + fbSize = (fbSize + fbAlign - 1) &~ (fbAlign - 1); + + // Create a memory block that will host the framebuffers + dkMemBlockMakerDefaults(&memBlockMaker, s_device, FB_NUM*fbSize); + memBlockMaker.flags = DkMemBlockFlags_GpuCached | DkMemBlockFlags_Image; + s_fbMemBlock = dkMemBlockCreate(&memBlockMaker); + + // Initialize the framebuffers with the layout and backing memory we've just created + DkImage fbImages[FB_NUM]; + DkImage const* swapchainImages[FB_NUM]; + for (unsigned i = 0; i < FB_NUM; i ++) + { + swapchainImages[i] = &fbImages[i]; + dkImageInitialize(&fbImages[i], &fbLayout, s_fbMemBlock, i*fbSize); + } + + // Create a swapchain out of the framebuffers we've just initialized + DkSwapchainMaker swapchainMaker; + dkSwapchainMakerDefaults(&swapchainMaker, s_device, nwindowGetDefault(), swapchainImages, FB_NUM); + s_swapchain = dkSwapchainCreate(&swapchainMaker); + + // Create a memory block for the linear framebuffer + dkMemBlockMakerDefaults(&memBlockMaker, s_device, width*height*4); + memBlockMaker.flags = DkMemBlockFlags_CpuCached | DkMemBlockFlags_GpuUncached; + s_workMemBlock = dkMemBlockCreate(&memBlockMaker); + + // Create a memory block for the command lists + dkMemBlockMakerDefaults(&memBlockMaker, s_device, CMDMEMSIZE); + memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached; + s_cmdMemBlock = dkMemBlockCreate(&memBlockMaker); + + // Create a command buffer + DkCmdBufMaker cmdBufMaker; + dkCmdBufMakerDefaults(&cmdBufMaker, s_device); + s_cmdBuf = dkCmdBufCreate(&cmdBufMaker); + dkCmdBufAddMemory(s_cmdBuf, s_cmdMemBlock, 0, CMDMEMSIZE); + + // Define source for linear framebuffer copies + const DkCopyBuf linearSrc = { + .addr = dkMemBlockGetGpuAddr(s_workMemBlock), + .rowLength = 0, + .imageHeight = 0, + }; + + // Define rectangle for the copies + const DkImageRect copyRect = { + .x = 0, .y = 0, .z = 0, + .width = width, .height = height, .depth = 1, + }; + + // Record command lists for the copies + for (unsigned i = 0; i < FB_NUM; i ++) { + DkImageView tiledDst; + dkImageViewDefaults(&tiledDst, &fbImages[i]); + dkCmdBufCopyBufferToImage(s_cmdBuf, &linearSrc, &tiledDst, ©Rect, 0); + dkCmdBufSignalFence(s_cmdBuf, &s_fence, false); + s_cmdLists[i] = dkCmdBufFinishList(s_cmdBuf); + } + + // Create a queue, to which we will submit our command lists + DkQueueMaker queueMaker; + dkQueueMakerDefaults(&queueMaker, s_device); + queueMaker.flags = 0; // we will only use this queue for transferring + s_queue = dkQueueCreate(&queueMaker); +} + +void graphicsExit(void) +{ + // Make sure the queue is idle before destroying anything + dkQueueWaitIdle(s_queue); + + // Destroy all the resources we've created + dkQueueDestroy(s_queue); + dkCmdBufDestroy(s_cmdBuf); + dkMemBlockDestroy(s_cmdMemBlock); + dkMemBlockDestroy(s_workMemBlock); + dkSwapchainDestroy(s_swapchain); + dkMemBlockDestroy(s_fbMemBlock); + dkDeviceDestroy(s_device); +} + +void* graphicsFrameBegin(u32* out_stride) +{ + // Ensure the GPU is not reading from the framebuffer + dkFenceWait(&s_fence, -1); + + // Return information + if (out_stride) *out_stride = s_fbWidth*4; + return dkMemBlockGetCpuAddr(s_workMemBlock); +} + +void graphicsFrameEnd(void) +{ + // Flush the linear framebuffer + dkMemBlockFlushCpuCache(s_workMemBlock, 0, s_fbWidth*s_fbHeight*4); + + // Present a frame + int slot = dkQueueAcquireImage(s_queue, s_swapchain); + dkQueueSubmitCommands(s_queue, s_cmdLists[slot]); + dkQueuePresentImage(s_queue, s_swapchain, slot); +} diff --git a/nx_main/nx_graphics.h b/nx_main/nx_graphics.h new file mode 100644 index 0000000..1ad5d4c --- /dev/null +++ b/nx_main/nx_graphics.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +void graphicsInit(u32 width, u32 height); +void graphicsExit(void); + +void* graphicsFrameBegin(u32* out_stride); +void graphicsFrameEnd(void); diff --git a/nx_main/nx_touch.c b/nx_main/nx_touch.c index ec38810..8f6e802 100644 --- a/nx_main/nx_touch.c +++ b/nx_main/nx_touch.c @@ -10,11 +10,13 @@ struct touchInfo_s touchInfo; -void touchInit() { +void touchInit(void) { touchInfo.gestureInProgress = false; touchInfo.isTap = true; touchInfo.initMenuXPos = 0; touchInfo.initMenuIndex = 0; + touchInfo.lastSlideSpeed = 0; + hidInitializeTouchScreen(); } void handleTappingOnApp(menu_s* menu, int px) { @@ -55,50 +57,50 @@ static inline bool checkInsideTextLayoutObject(ThemeLayoutId id, int x, int y) { void handleTouch(menu_s* menu) { ThemeLayoutObject *layoutobj = NULL; - touchPosition currentTouch; - u32 touches = hidTouchCount(); + HidTouchScreenState touch = {0}; + hidGetTouchScreenStates(&touch, 1); layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles]; int entries_count = layoutobj->posEnd[0]; layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList]; // On touch start. - if (touches == 1 && !touchInfo.gestureInProgress) { - hidTouchRead(¤tTouch, 0); - + if (touch.count == 1 && !touchInfo.gestureInProgress) { touchInfo.gestureInProgress = true; - touchInfo.firstTouch = currentTouch; - touchInfo.prevTouch = currentTouch; + touchInfo.firstTouch = touch.touches[0]; + touchInfo.prevTouch = touch.touches[0]; touchInfo.isTap = true; touchInfo.initMenuXPos = menu->xPos; touchInfo.initMenuIndex = menu->curEntry; + touchInfo.lastSlideSpeed = 0; + menu->slideSpeed = 0; } // On touch moving. - else if (touches >= 1 && touchInfo.gestureInProgress) { - hidTouchRead(¤tTouch, 0); + else if (touch.count >= 1 && touchInfo.gestureInProgress) { + touchInfo.lastSlideSpeed = ((int)(touch.touches[0].x - touchInfo.prevTouch.x)); - touchInfo.prevTouch = currentTouch; + touchInfo.prevTouch = touch.touches[0]; - if (touchInfo.isTap && (abs(touchInfo.firstTouch.px - currentTouch.px) > TAP_MOVEMENT_GAP || abs(touchInfo.firstTouch.py - currentTouch.py) > TAP_MOVEMENT_GAP)) { + if (touchInfo.isTap && (abs(touchInfo.firstTouch.x - touch.touches[0].x) > TAP_MOVEMENT_GAP || abs(touchInfo.firstTouch.y - touch.touches[0].y) > TAP_MOVEMENT_GAP)) { touchInfo.isTap = false; } - if (!menuIsMsgBoxOpen() && touchInfo.firstTouch.py > layoutobj->posStart[1] && touchInfo.firstTouch.py < layoutobj->posStart[1]+layoutobj->size[1] && !touchInfo.isTap && menu->nEntries > entries_count) { - menu->xPos = touchInfo.initMenuXPos + (currentTouch.px - touchInfo.firstTouch.px); - menu->curEntry = touchInfo.initMenuIndex + ((int) (touchInfo.firstTouch.px - currentTouch.px) / layoutobj->posEnd[0]); + if (!menuIsMsgBoxOpen() && touchInfo.firstTouch.y > layoutobj->posStart[1] && touchInfo.firstTouch.y < layoutobj->posStart[1]+layoutobj->size[1] && !touchInfo.isTap && menu->nEntries > entries_count) { - if (menu->curEntry < 0) - menu->curEntry = 0; - - if (menu->curEntry >= menu->nEntries - entries_count - 1) - menu->curEntry = menu->nEntries - entries_count; + if (!touchInfo.isTap) { + menu->slideSpeed = touchInfo.lastSlideSpeed; + } } } // On touch end. else if (touchInfo.gestureInProgress) { - int x1 = touchInfo.firstTouch.px; - int y1 = touchInfo.firstTouch.py; - int x2 = touchInfo.prevTouch.px; - int y2 = touchInfo.prevTouch.py; + int x1 = touchInfo.firstTouch.x; + int y1 = touchInfo.firstTouch.y; + int x2 = touchInfo.prevTouch.x; + int y2 = touchInfo.prevTouch.y; + + if (!touchInfo.isTap) { + menu->slideSpeed = touchInfo.lastSlideSpeed; + } bool netloader_active = menuIsNetloaderActive(); @@ -117,7 +119,7 @@ void handleTouch(menu_s* menu) { } else if (touchInfo.isTap && !netloader_active) { // App Icons if (y1 > layoutobj->posStart[1] && y1 < layoutobj->posStart[1]+layoutobj->size[1]) { - handleTappingOnApp(menu, touchInfo.prevTouch.px); + handleTappingOnApp(menu, touchInfo.prevTouch.x); } // Bottom Buttons else { diff --git a/nx_main/nx_touch.h b/nx_main/nx_touch.h index cea6010..49f915c 100644 --- a/nx_main/nx_touch.h +++ b/nx_main/nx_touch.h @@ -5,11 +5,13 @@ struct touchInfo_s { bool gestureInProgress; - touchPosition firstTouch; - touchPosition prevTouch; + HidTouchState firstTouch; + HidTouchState prevTouch; bool isTap; int initMenuXPos; int initMenuIndex; + int lastSlideSpeed; }; +void touchInit(void); void handleTouch(menu_s* menu); \ No newline at end of file diff --git a/resources/eth_none_icon.png b/resources/eth_none_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..aeaa484b66dabb181b23730b4fb0cf30a713c16c GIT binary patch literal 481 zcmV<70UrK|P)1=Jb*{%-&x z(if4U4SuXWT~+NnXa@9vuIrS*Kvk>Qi0cj_vFR09k-gAEzXcM<9XA5J`qg{DgZEIUn& zvZugaf?>&3%c7d~;hrCOFN~rY_LQRIGAYW#c@@tvkFZ?12GJ1A0$DA?R(YfKe7F1$ z?Oo#MD_|XXm>Vz4M&KS7iE&