From d46428592be8aa34b6aed47e48db6e5756a085fd Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Fri, 19 Jan 2024 15:52:39 -0600 Subject: [PATCH 01/14] initial dual-screen support for 3DS --- src/Core.h | 1 + src/Graphics.h | 3 +++ src/Graphics_3DS.c | 26 ++++++++++++++++----- src/Gui.c | 4 ++++ src/LScreens.c | 12 ++++++++++ src/Launcher.c | 5 +++++ src/Menus.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ src/Platform_3DS.c | 6 ++++- src/Screens.c | 21 +++++++++++++++++ src/Window.h | 10 +++++++++ src/Window_3DS.c | 36 ++++++++++++++++++++++++++--- 11 files changed, 170 insertions(+), 10 deletions(-) diff --git a/src/Core.h b/src/Core.h index bc00131cc..ab6b1d62a 100644 --- a/src/Core.h +++ b/src/Core.h @@ -287,6 +287,7 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_BEARSSL #define CC_BUILD_LOWMEM #define CC_BUILD_CONSOLE + #define CC_BUILD_TOUCH #undef CC_BUILD_FREETYPE #elif defined GEKKO #define CC_BUILD_GCWII diff --git a/src/Graphics.h b/src/Graphics.h index f0513fe50..16af4c859 100644 --- a/src/Graphics.h +++ b/src/Graphics.h @@ -238,6 +238,9 @@ void Gfx_OnWindowResize(void); /* NOTE: Each line is separated by \n */ void Gfx_GetApiInfo(cc_string* info); +void Gfx_3DS_DrawToTopScreen(void); +void Gfx_3DS_DrawToBottomScreen(void); + /* Raises ContextLost event and updates state for lost contexts */ void Gfx_LoseContext(const char* reason); /* Raises ContextRecreated event and restores internal state */ diff --git a/src/Graphics_3DS.c b/src/Graphics_3DS.c index 8ed090fc4..976b5948a 100644 --- a/src/Graphics_3DS.c +++ b/src/Graphics_3DS.c @@ -102,7 +102,8 @@ static void SwitchProgram(void) { /*########################################################################################################################* *---------------------------------------------------------General---------------------------------------------------------* *#########################################################################################################################*/ -static C3D_RenderTarget* target; +static C3D_RenderTarget* topTarget; +static C3D_RenderTarget* bottomTarget; static void AllocShaders(void) { Shader_Alloc(&shaders[0], coloured_shbin, coloured_shbin_size); @@ -124,8 +125,12 @@ static void SetDefaultState(void) { } static void InitCitro3D(void) { C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); - target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); - C3D_RenderTargetSetOutput(target, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); + + topTarget = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); + C3D_RenderTargetSetOutput(topTarget, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); + + bottomTarget = C3D_RenderTargetCreate(240, 400 /* uhh... not correct, but it works */, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); + C3D_RenderTargetSetOutput(bottomTarget, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); SetDefaultState(); AllocShaders(); @@ -168,6 +173,14 @@ void Gfx_FreeState(void) { Gfx_DeleteTexture(&white_square); } +void Gfx_3DS_DrawToTopScreen(void) { + C3D_FrameDrawOn(topTarget); +} + +void Gfx_3DS_DrawToBottomScreen(void) { + C3D_FrameDrawOn(bottomTarget); +} + /*########################################################################################################################* *---------------------------------------------------------Textures--------------------------------------------------------* *#########################################################################################################################*/ @@ -350,11 +363,12 @@ void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) { void Gfx_BeginFrame(void) { int flags = gfx_vsync ? C3D_FRAME_SYNCDRAW : 0; C3D_FrameBegin(flags); + C3D_FrameDrawOn(topTarget); } void Gfx_Clear(void) { - C3D_RenderTargetClear(target, C3D_CLEAR_ALL, clear_color, 0); - C3D_FrameDrawOn(target); + C3D_RenderTargetClear(topTarget, C3D_CLEAR_ALL, clear_color, 0); + C3D_RenderTargetClear(bottomTarget, C3D_CLEAR_ALL, 0, 0); } void Gfx_EndFrame(void) { @@ -705,4 +719,4 @@ void Gfx_Draw2DTexture(const struct Texture* tex, PackedCol color) { C3D_ImmSendAttrib(v[0].U, v[0].V, 0.0f, 0.0f); C3D_ImmDrawEnd(); } -#endif \ No newline at end of file +#endif diff --git a/src/Gui.c b/src/Gui.c index 5feab28ee..3b815e273 100644 --- a/src/Gui.c +++ b/src/Gui.c @@ -32,10 +32,14 @@ static CC_NOINLINE int GetWindowScale(void) { /* Use larger UI scaling on mobile */ /* TODO move this DPI scaling elsewhere.,. */ +#ifndef __3DS__ if (!Input_TouchMode) { +#endif widthScale /= DisplayInfo.ScaleX; heightScale /= DisplayInfo.ScaleY; +#ifndef __3DS__ } +#endif return 1 + (int)(min(widthScale, heightScale)); } diff --git a/src/LScreens.c b/src/LScreens.c index 02d4502f8..2acf1ba44 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -118,6 +118,18 @@ static void LScreen_MouseUp(struct LScreen* s, int idx) { } static void LScreen_MouseWheel(struct LScreen* s, float delta) { } static void LScreen_DrawBackground(struct LScreen* s, struct Context2D* ctx) { + // I don't know of a good place to do this, so I'm sticking it here +#ifdef __3DS__ + enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN); + + // Draw top screen background + Launcher_DrawBackgroundAll(ctx); + Rect2D r = { 0, 0, WindowInfo.Width, WindowInfo.Height }; + Window_DrawFramebuffer(r); + + Window_3DS_SetRenderScreen(scr); +#endif + if (!s->title) { Launcher_DrawBackground(ctx, 0, 0, ctx->width, ctx->height); return; diff --git a/src/Launcher.c b/src/Launcher.c index fa90ab531..12d2e6fce 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -114,6 +114,7 @@ cc_bool Launcher_StartGame(const cc_string* user, const cc_string* mppass, const if (res) { Logger_SysWarn(res, "starting game"); return false; } Launcher_ShouldExit = Platform_SingleProcess || Options_GetBool(LOPT_AUTO_CLOSE, false); + return true; } @@ -235,6 +236,8 @@ void Launcher_Run(void) { } #endif + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + Drawer2D_Component.Init(); SystemFonts_Component.Init(); Drawer2D.BitmappedText = false; @@ -295,6 +298,8 @@ void Launcher_Run(void) { if (WindowInfo.Exists) Window_RequestClose(); #endif + + Window_3DS_SetRenderScreen(scr); } diff --git a/src/Menus.c b/src/Menus.c index c5664f203..763d52bbb 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -483,8 +483,12 @@ void ListScreen_Show(void) { *--------------------------------------------------------MenuScreen-------------------------------------------------------* *#########################################################################################################################*/ static void MenuScreen_Render2(void* screen, double delta) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + Menu_RenderBounds(); Screen_Render2Widgets(screen, delta); + + Window_3DS_SetRenderScreen(scr); } @@ -551,11 +555,15 @@ static void PauseScreen_ContextRecreated(void* screen) { } static void PauseScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct PauseScreen* s = (struct PauseScreen*)screen; Menu_LayoutButtons(s->btns, s->descs, s->descsCount); Menu_LayoutBack(&s->back); Widget_SetLocation(&s->quit, ANCHOR_MAX, ANCHOR_MAX, 5, 5); Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -100); + + Window_3DS_SetRenderScreen(scr); } static void PauseScreen_Init(void* screen) { @@ -620,10 +628,14 @@ static void ClassicPauseScreen_ContextRecreated(void* screen) { } static void ClassicPauseScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct PauseScreen* s = (struct PauseScreen*)screen; Menu_LayoutButtons(s->btns, s->descs, s->descsCount); Widget_SetLocation(&s->back, ANCHOR_CENTRE, ANCHOR_MAX, 0, Game_ClassicMode ? 80 : 25); Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -150); + + Window_3DS_SetRenderScreen(scr); } static void ClassicPauseScreen_Init(void* screen) { @@ -739,10 +751,14 @@ static void OptionsGroupScreen_ContextRecreated(void* screen) { } static void OptionsGroupScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct OptionsGroupScreen* s = (struct OptionsGroupScreen*)screen; Menu_LayoutButtons(s->btns, optsGroup_btns, 8); Widget_SetLocation(&s->desc, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 100); Menu_LayoutBack(&s->done); + + Window_3DS_SetRenderScreen(scr); } static void OptionsGroupScreen_Init(void* screen) { @@ -992,6 +1008,8 @@ static void EditHotkeyScreen_Update(void* screen, double delta) { } static void EditHotkeyScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen; s->barWidth = Display_ScaleX(500); s->barX = Gui_CalcPos(ANCHOR_CENTRE, 0, s->barWidth, WindowInfo.Width); @@ -1009,6 +1027,8 @@ static void EditHotkeyScreen_Layout(void* screen) { Widget_SetLocation(&s->btns[4], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 130); Widget_SetLocation(&s->input, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -35); Menu_LayoutBack(&s->cancel); + + Window_3DS_SetRenderScreen(scr); } static void EditHotkeyScreen_Init(void* screen) { @@ -1232,6 +1252,8 @@ static void GenLevelScreen_Update(void* screen, double delta) { } static void GenLevelScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct GenLevelScreen* s = (struct GenLevelScreen*)screen; int i, y; for (i = 0; i < 4; i++) { @@ -1244,6 +1266,8 @@ static void GenLevelScreen_Layout(void* screen) { Widget_SetLocation(&s->flatgrass, ANCHOR_CENTRE, ANCHOR_CENTRE, -120, 100); Widget_SetLocation(&s->vanilla, ANCHOR_CENTRE, ANCHOR_CENTRE, 120, 100); Menu_LayoutBack(&s->cancel); + + Window_3DS_SetRenderScreen(scr); } static void GenLevelScreen_Init(void* screen) { @@ -1325,12 +1349,16 @@ static void ClassicGenScreen_ContextRecreated(void* screen) { } static void ClassicGenScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct ClassicGenScreen* s = (struct ClassicGenScreen*)screen; Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -150); Widget_SetLocation(&s->btns[0], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -100); Widget_SetLocation(&s->btns[1], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -50); Widget_SetLocation(&s->btns[2], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 0); Widget_SetLocation(&s->cancel, ANCHOR_CENTRE, ANCHOR_MAX, 0, 80); + + Window_3DS_SetRenderScreen(scr); } static void ClassicGenScreen_Init(void* screen) { @@ -1538,6 +1566,8 @@ static void SaveLevelScreen_Update(void* screen, double delta) { } static void SaveLevelScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen; Widget_SetLocation(&s->input, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -30); Widget_SetLocation(&s->save, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 20); @@ -1545,6 +1575,8 @@ static void SaveLevelScreen_Layout(void* screen) { Widget_SetLocation(&s->file, ANCHOR_CENTRE, ANCHOR_MAX, 0, 70); Menu_LayoutBack(&s->cancel); + + Window_3DS_SetRenderScreen(scr); } static void SaveLevelScreen_Init(void* screen) { @@ -1877,10 +1909,14 @@ static void BindsSourceScreen_ContextRecreated(void* screen) { } static void BindsSourceScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct BindsSourceScreen* s = (struct BindsSourceScreen*)screen; Widget_SetLocation(&s->btns[0], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -25); Widget_SetLocation(&s->btns[1], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 25); Menu_LayoutBack(&s->cancel); + + Window_3DS_SetRenderScreen(scr); } static void BindsSourceScreen_Init(void* screen) { @@ -2028,6 +2064,8 @@ static void KeyBindsScreen_ContextRecreated(void* screen) { } static void KeyBindsScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct KeyBindsScreen* s = (struct KeyBindsScreen*)screen; int i, x, y, xDir, leftLen; x = s->btnWidth / 2 + 5; @@ -2048,6 +2086,8 @@ static void KeyBindsScreen_Layout(void* screen) { Widget_SetLocation(&s->left, ANCHOR_CENTRE, ANCHOR_CENTRE, -s->btnWidth - 35, s->arrowsY); Widget_SetLocation(&s->right, ANCHOR_CENTRE, ANCHOR_CENTRE, s->btnWidth + 35, s->arrowsY); + + Window_3DS_SetRenderScreen(scr); } static void KeyBindsScreen_Init(void* screen) { @@ -2329,6 +2369,8 @@ static void MenuInputOverlay_Free(void* screen) { } static void MenuInputOverlay_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct MenuInputOverlay* s = (struct MenuInputOverlay*)screen; if (!Input_TouchMode) { Widget_SetLocation(&s->input, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 110); @@ -2343,6 +2385,8 @@ static void MenuInputOverlay_Layout(void* screen) { Widget_SetLocation(&s->ok, ANCHOR_CENTRE, ANCHOR_CENTRE, 120, 150); Widget_SetLocation(&s->Default, ANCHOR_CENTRE, ANCHOR_CENTRE, -120, 150); } + + Window_3DS_SetRenderScreen(scr); } static void MenuInputOverlay_ContextLost(void* screen) { @@ -2644,10 +2688,14 @@ static void MenuOptionsScreen_Free(void* screen) { } static void MenuOptionsScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen; Screen_Layout(s); Menu_LayoutBack(&s->done); MenuOptionsScreen_LayoutExtHelp(s); + + Window_3DS_SetRenderScreen(scr); } static void MenuOptionsScreen_ContextLost(void* screen) { @@ -3337,11 +3385,15 @@ static void NostalgiaMenuScreen_ContextRecreated(void* screen) { } static void NostalgiaMenuScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct NostalgiaMenuScreen* s = (struct NostalgiaMenuScreen*)screen; Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -100); Widget_SetLocation(&s->btnA, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -25); Widget_SetLocation(&s->btnF, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 25); Menu_LayoutBack(&s->done); + + Window_3DS_SetRenderScreen(scr); } static void NostalgiaMenuScreen_Init(void* screen) { @@ -4364,9 +4416,13 @@ static void TouchMoreScreen_ContextRecreated(void* screen) { } static void TouchMoreScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct TouchMoreScreen* s = (struct TouchMoreScreen*)screen; Menu_LayoutButtons(s->btns, touchMore_btns, TOUCHMORE_BTNS); Menu_LayoutBack(&s->back); + + Window_3DS_SetRenderScreen(scr); } static void TouchMoreScreen_Init(void* screen) { diff --git a/src/Platform_3DS.c b/src/Platform_3DS.c index 478564704..ad8b9c67d 100644 --- a/src/Platform_3DS.c +++ b/src/Platform_3DS.c @@ -56,6 +56,10 @@ void Platform_Log(const char* msg, int len) { write(STDOUT_FILENO, msg, len); write(STDOUT_FILENO, "\n", 1); + + // output to debug service (visible in Citra with log level set to "*:Debug", or on console via remote gdb) + svcOutputDebugString(msg, len); + svcOutputDebugString("\n", 1); } #define UnixTime_TotalMS(time) ((cc_uint64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000)) @@ -462,4 +466,4 @@ static cc_result GetMachineID(cc_uint32* key) { psInit(); return PS_GetDeviceId(key); } -#endif \ No newline at end of file +#endif diff --git a/src/Screens.c b/src/Screens.c index 630f8d071..5c886f723 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -202,9 +202,14 @@ static void HUDScreen_ContextRecreated(void* screen) { } static int HUDScreen_LayoutHotbar(void) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct HUDScreen* s = &HUDScreen_Instance; s->hotbar.scale = Gui_GetHotbarScale(); Widget_Layout(&s->hotbar); + + Window_3DS_SetRenderScreen(scr); + return s->hotbar.height; } @@ -383,6 +388,9 @@ static void HUDScreen_Render(void* screen, double delta) { } if (Gui_GetBlocksWorld()) return; + + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + Gfx_BindDynamicVb(s->vb); Widget_Render2(&s->hotbar, 12); @@ -391,6 +399,8 @@ static void HUDScreen_Render(void* screen, double delta) { Gfx_BindDynamicVb(s->vb); /* Have to rebind for mobile right now... */ Gfx_DrawVb_IndexedTris(4); } + + Window_3DS_SetRenderScreen(scr); } static const struct ScreenVTABLE HUDScreen_VTABLE = { @@ -2308,7 +2318,10 @@ static void TouchScreen_ContextRecreated(void* screen) { static void TouchScreen_Render(void* screen, double delta) { if (Gui.InputGrab) return; + + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); Screen_Render2Widgets(screen, delta); + Window_3DS_SetRenderScreen(scr); } static int TouchScreen_PointerDown(void* screen, int id, int x, int y) { @@ -2353,6 +2366,8 @@ static void TouchScreen_PointerUp(void* screen, int id, int x, int y) { } static void TouchScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct TouchScreen* s = (struct TouchScreen*)screen; const struct TouchButtonDesc* desc; float scale = Gui.RawTouchScale; @@ -2389,6 +2404,8 @@ static void TouchScreen_Layout(void* screen) { s->thumbstick.yOffset += height; s->thumbstick.scale = scale; Widget_Layout(&s->thumbstick); + + Window_3DS_SetRenderScreen(scr); } struct LocalPlayerInput touchInput; @@ -2397,6 +2414,8 @@ static void TouchScreen_GetMovement(float* xMoving, float* zMoving) { } static void TouchScreen_Init(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct TouchScreen* s = (struct TouchScreen*)screen; s->widgets = touch_widgets; @@ -2412,6 +2431,8 @@ static void TouchScreen_Init(void* screen) { ThumbstickWidget_Init(&s->thumbstick); touchInput.GetMovement = TouchScreen_GetMovement; LocalPlayer_Instance.input.next = &touchInput; + + Window_3DS_SetRenderScreen(scr); } static void TouchScreen_Free(void* s) { diff --git a/src/Window.h b/src/Window.h index c506c1989..e985a66c5 100644 --- a/src/Window.h +++ b/src/Window.h @@ -227,4 +227,14 @@ void GLContext_SetFpsLimit(cc_bool vsync, float minFrameMs); /* Gets OpenGL context specific graphics information. */ void GLContext_GetApiInfo(cc_string* info); #endif + +enum Screen3DS { TOP_SCREEN, BOTTOM_SCREEN }; +#ifdef __3DS__ +/* Selects which screen on the 3DS to render to. Returns the previous screen */ +enum Screen3DS Window_3DS_SetRenderScreen(enum Screen3DS screen); +#else +static inline +enum Screen3DS Window_3DS_SetRenderScreen(enum Screen3DS screen) { return TOP_SCREEN; } +#endif + #endif diff --git a/src/Window_3DS.c b/src/Window_3DS.c index b9836bec8..f04e6beb7 100644 --- a/src/Window_3DS.c +++ b/src/Window_3DS.c @@ -15,6 +15,7 @@ static int touchActive, touchBegX, touchBegY; static cc_bool launcherMode; static Result irrst_result; +static enum Screen3DS renderScreen = TOP_SCREEN; struct _DisplayData DisplayInfo; struct _WinData WindowInfo; @@ -31,7 +32,7 @@ void Window_Init(void) { gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, false); //gfxInit(GSP_RGBA8_OES,GSP_RGBA8_OES,false); - consoleInit(GFX_BOTTOM, NULL); + //consoleInit(GFX_BOTTOM, NULL); u16 width, height; gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &width, &height); @@ -47,12 +48,28 @@ void Window_Init(void) { WindowInfo.Focused = true; WindowInfo.Exists = true; + Input_SetTouchMode(true); Input.Sources = INPUT_SOURCE_GAMEPAD; irrst_result = irrstInit(); } void Window_Free(void) { irrstExit(); } +enum Screen3DS Window_3DS_SetRenderScreen(enum Screen3DS screen) { + enum Screen3DS prev = renderScreen; + if (screen != prev) + { + renderScreen = screen; + DisplayInfo.Width = (screen == TOP_SCREEN) ? 400 : 320; + WindowInfo.Width = DisplayInfo.Width; + if (screen == TOP_SCREEN) + Gfx_3DS_DrawToTopScreen(); + else + Gfx_3DS_DrawToBottomScreen(); + } + return prev; +} + void Window_Create2D(int width, int height) { launcherMode = true; } void Window_Create3D(int width, int height) { launcherMode = false; } @@ -94,6 +111,9 @@ static void HandleButtons(u32 mods) { Input_SetNonRepeatable(CCPAD_ZL, mods & KEY_ZL); Input_SetNonRepeatable(CCPAD_ZR, mods & KEY_ZR); + + if (mods == (KEY_A|KEY_B|KEY_START|KEY_SELECT)) + Process_Exit(0); } static void ProcessJoystickInput(circlePosition* pos, double delta) { @@ -117,10 +137,19 @@ static void ProcessTouchInput(int mods) { int y = touch.py; Pointer_SetPosition(0, x, y); } + int x = touch.px; + int y = touch.py; + // Set starting position for camera movement if (hidKeysDown() & KEY_TOUCH) { + //Platform_Log2("touch down: %i,%i", &x, &y); touchBegX = touch.px; touchBegY = touch.py; + Input_AddTouch(1, touch.px, touch.py); + } + if (hidKeysUp() & KEY_TOUCH) { + //Platform_Log2("touch up: %i,%i", &x, &y); + Input_RemoveTouch(1, touch.px, touch.py); // TODO: coordinates are 0 } } @@ -182,8 +211,9 @@ void Window_AllocFramebuffer(struct Bitmap* bmp) { void Window_DrawFramebuffer(Rect2D r) { u16 width, height; - gfxSetDoubleBuffering(GFX_TOP, false); - u8* fb = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &width, &height); + gfxScreen_t screen = (renderScreen == TOP_SCREEN) ? GFX_TOP : GFX_BOTTOM; + gfxSetDoubleBuffering(screen, false); + u8* fb = gfxGetFramebuffer(screen, GFX_LEFT, &width, &height); // SRC y = 0 to 240 // SRC x = 0 to 400 From 96c098bd433de4f63cfd10ae956757edc759cc8f Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Fri, 19 Jan 2024 16:32:58 -0600 Subject: [PATCH 02/14] fix layout of some more menus, and put crosshair back on top screen --- src/Menus.c | 12 ++++++++++++ src/Screens.c | 4 ---- src/Widgets.c | 13 +++++++++---- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Menus.c b/src/Menus.c index 763d52bbb..e52a2a422 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -261,6 +261,8 @@ static struct Widget* list_widgets[] = { #define LISTSCREEN_EMPTY "-" static void ListScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct ListScreen* s = (struct ListScreen*)screen; int i; @@ -280,6 +282,8 @@ static void ListScreen_Layout(void* screen) { Widget_SetLocation(&s->left, ANCHOR_CENTRE, ANCHOR_CENTRE, -220, 0); Widget_SetLocation(&s->right, ANCHOR_CENTRE, ANCHOR_CENTRE, 220, 0); Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -155); + + Window_3DS_SetRenderScreen(scr); } static STRING_REF cc_string ListScreen_UNSAFE_Get(struct ListScreen* s, int index) { @@ -4145,11 +4149,15 @@ static void TouchOnscreenScreen_ContextRecreated(void* screen) { } static void TouchOnscreenScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; Menu_LayoutButtons(s->btns, s->btnDescs, ONSCREEN_PAGE_BTNS); Menu_LayoutBack(&s->back); Widget_SetLocation(&s->left, ANCHOR_CENTRE, ANCHOR_CENTRE, -260, 0); Widget_SetLocation(&s->right, ANCHOR_CENTRE, ANCHOR_CENTRE, 260, 0); + + Window_3DS_SetRenderScreen(scr); } static void TouchOnscreenScreen_Init(void* screen) { @@ -4322,9 +4330,13 @@ static void TouchCtrlsScreen_ContextRecreated(void* screen) { } static void TouchCtrlsScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; Menu_LayoutButtons(s->btns, touchCtrls_btns, TOUCHCTRLS_BTNS); Menu_LayoutBack(&s->back); + + Window_3DS_SetRenderScreen(scr); } static void TouchCtrlsScreen_Init(void* screen) { diff --git a/src/Screens.c b/src/Screens.c index 5c886f723..d4b2eb9b9 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -389,8 +389,6 @@ static void HUDScreen_Render(void* screen, double delta) { if (Gui_GetBlocksWorld()) return; - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - Gfx_BindDynamicVb(s->vb); Widget_Render2(&s->hotbar, 12); @@ -399,8 +397,6 @@ static void HUDScreen_Render(void* screen, double delta) { Gfx_BindDynamicVb(s->vb); /* Have to rebind for mobile right now... */ Gfx_DrawVb_IndexedTris(4); } - - Window_3DS_SetRenderScreen(scr); } static const struct ScreenVTABLE HUDScreen_VTABLE = { diff --git a/src/Widgets.c b/src/Widgets.c index 5917ad675..c79781b81 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -447,16 +447,21 @@ static void HotbarWidget_RenderEntries(struct HotbarWidget* w, int offset) { } static int HotbarWidget_Render2(void* widget, int offset) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + struct HotbarWidget* w = (struct HotbarWidget*)widget; HotbarWidget_RenderOutline(w, offset ); HotbarWidget_RenderEntries(w, offset + 8); #ifdef CC_BUILD_TOUCH - if (!Input_TouchMode) return HOTBAR_MAX_VERTICES; - w->ellipsisTex.x = HotbarWidget_TileX(w, HOTBAR_MAX_INDEX) - w->ellipsisTex.Width / 2; - w->ellipsisTex.y = w->y + (w->height / 2) - w->ellipsisTex.Height / 2; - Texture_Render(&w->ellipsisTex); + if (Input_TouchMode) { + w->ellipsisTex.x = HotbarWidget_TileX(w, HOTBAR_MAX_INDEX) - w->ellipsisTex.Width / 2; + w->ellipsisTex.y = w->y + (w->height / 2) - w->ellipsisTex.Height / 2; + Texture_Render(&w->ellipsisTex); + } #endif + + Window_3DS_SetRenderScreen(scr); return HOTBAR_MAX_VERTICES; } From aaeac485a4d1a8a836ebde98d5f165f0382fde0b Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Fri, 19 Jan 2024 21:44:28 -0600 Subject: [PATCH 03/14] make screens go on 3DS bottom screen by default --- src/Gui.c | 16 ++++++++++++ src/Menus.c | 68 --------------------------------------------------- src/Screens.c | 54 ++++++++++++++++++++-------------------- 3 files changed, 43 insertions(+), 95 deletions(-) diff --git a/src/Gui.c b/src/Gui.c index 3b815e273..d7d96056b 100644 --- a/src/Gui.c +++ b/src/Gui.c @@ -141,12 +141,16 @@ void Gui_LayoutAll(void) { struct Screen* s; int i; + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + for (i = 0; i < Gui.ScreensCount; i++) { s = Gui_Screens[i]; s->VTABLE->Layout(s); s->dirty = true; } + + Window_3DS_SetRenderScreen(scr); } void Gui_RefreshAll(void) { @@ -156,10 +160,14 @@ void Gui_RefreshAll(void) { } void Gui_Refresh(struct Screen* s) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + s->VTABLE->ContextLost(s); s->VTABLE->ContextRecreated(s); s->VTABLE->Layout(s); s->dirty = true; + + Window_3DS_SetRenderScreen(scr); } static void Gui_AddCore(struct Screen* s, int priority) { @@ -183,6 +191,8 @@ static void Gui_AddCore(struct Screen* s, int priority) { priorities[i] = priority; Gui.ScreensCount++; + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + s->dirty = true; s->VTABLE->Init(s); s->VTABLE->ContextRecreated(s); @@ -193,6 +203,8 @@ static void Gui_AddCore(struct Screen* s, int priority) { { s->VTABLE->HandlesPointerMove(s, i, Pointers[i].x, Pointers[i].y); } + + Window_3DS_SetRenderScreen(scr); } /* Returns index of the given screen in the screens list, -1 if not */ @@ -287,6 +299,8 @@ void Gui_RenderGui(double delta) { struct Screen* s; int i; + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); + /* Draw back to front so highest priority screen is on top */ for (i = Gui.ScreensCount - 1; i >= 0; i--) { @@ -296,6 +310,8 @@ void Gui_RenderGui(double delta) { if (s->dirty) { s->VTABLE->BuildMesh(s); s->dirty = false; } s->VTABLE->Render(s, delta); } + + Window_3DS_SetRenderScreen(scr); } diff --git a/src/Menus.c b/src/Menus.c index e52a2a422..c5664f203 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -261,8 +261,6 @@ static struct Widget* list_widgets[] = { #define LISTSCREEN_EMPTY "-" static void ListScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct ListScreen* s = (struct ListScreen*)screen; int i; @@ -282,8 +280,6 @@ static void ListScreen_Layout(void* screen) { Widget_SetLocation(&s->left, ANCHOR_CENTRE, ANCHOR_CENTRE, -220, 0); Widget_SetLocation(&s->right, ANCHOR_CENTRE, ANCHOR_CENTRE, 220, 0); Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -155); - - Window_3DS_SetRenderScreen(scr); } static STRING_REF cc_string ListScreen_UNSAFE_Get(struct ListScreen* s, int index) { @@ -487,12 +483,8 @@ void ListScreen_Show(void) { *--------------------------------------------------------MenuScreen-------------------------------------------------------* *#########################################################################################################################*/ static void MenuScreen_Render2(void* screen, double delta) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - Menu_RenderBounds(); Screen_Render2Widgets(screen, delta); - - Window_3DS_SetRenderScreen(scr); } @@ -559,15 +551,11 @@ static void PauseScreen_ContextRecreated(void* screen) { } static void PauseScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct PauseScreen* s = (struct PauseScreen*)screen; Menu_LayoutButtons(s->btns, s->descs, s->descsCount); Menu_LayoutBack(&s->back); Widget_SetLocation(&s->quit, ANCHOR_MAX, ANCHOR_MAX, 5, 5); Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -100); - - Window_3DS_SetRenderScreen(scr); } static void PauseScreen_Init(void* screen) { @@ -632,14 +620,10 @@ static void ClassicPauseScreen_ContextRecreated(void* screen) { } static void ClassicPauseScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct PauseScreen* s = (struct PauseScreen*)screen; Menu_LayoutButtons(s->btns, s->descs, s->descsCount); Widget_SetLocation(&s->back, ANCHOR_CENTRE, ANCHOR_MAX, 0, Game_ClassicMode ? 80 : 25); Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -150); - - Window_3DS_SetRenderScreen(scr); } static void ClassicPauseScreen_Init(void* screen) { @@ -755,14 +739,10 @@ static void OptionsGroupScreen_ContextRecreated(void* screen) { } static void OptionsGroupScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct OptionsGroupScreen* s = (struct OptionsGroupScreen*)screen; Menu_LayoutButtons(s->btns, optsGroup_btns, 8); Widget_SetLocation(&s->desc, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 100); Menu_LayoutBack(&s->done); - - Window_3DS_SetRenderScreen(scr); } static void OptionsGroupScreen_Init(void* screen) { @@ -1012,8 +992,6 @@ static void EditHotkeyScreen_Update(void* screen, double delta) { } static void EditHotkeyScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen; s->barWidth = Display_ScaleX(500); s->barX = Gui_CalcPos(ANCHOR_CENTRE, 0, s->barWidth, WindowInfo.Width); @@ -1031,8 +1009,6 @@ static void EditHotkeyScreen_Layout(void* screen) { Widget_SetLocation(&s->btns[4], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 130); Widget_SetLocation(&s->input, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -35); Menu_LayoutBack(&s->cancel); - - Window_3DS_SetRenderScreen(scr); } static void EditHotkeyScreen_Init(void* screen) { @@ -1256,8 +1232,6 @@ static void GenLevelScreen_Update(void* screen, double delta) { } static void GenLevelScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct GenLevelScreen* s = (struct GenLevelScreen*)screen; int i, y; for (i = 0; i < 4; i++) { @@ -1270,8 +1244,6 @@ static void GenLevelScreen_Layout(void* screen) { Widget_SetLocation(&s->flatgrass, ANCHOR_CENTRE, ANCHOR_CENTRE, -120, 100); Widget_SetLocation(&s->vanilla, ANCHOR_CENTRE, ANCHOR_CENTRE, 120, 100); Menu_LayoutBack(&s->cancel); - - Window_3DS_SetRenderScreen(scr); } static void GenLevelScreen_Init(void* screen) { @@ -1353,16 +1325,12 @@ static void ClassicGenScreen_ContextRecreated(void* screen) { } static void ClassicGenScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct ClassicGenScreen* s = (struct ClassicGenScreen*)screen; Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -150); Widget_SetLocation(&s->btns[0], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -100); Widget_SetLocation(&s->btns[1], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -50); Widget_SetLocation(&s->btns[2], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 0); Widget_SetLocation(&s->cancel, ANCHOR_CENTRE, ANCHOR_MAX, 0, 80); - - Window_3DS_SetRenderScreen(scr); } static void ClassicGenScreen_Init(void* screen) { @@ -1570,8 +1538,6 @@ static void SaveLevelScreen_Update(void* screen, double delta) { } static void SaveLevelScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen; Widget_SetLocation(&s->input, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -30); Widget_SetLocation(&s->save, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 20); @@ -1579,8 +1545,6 @@ static void SaveLevelScreen_Layout(void* screen) { Widget_SetLocation(&s->file, ANCHOR_CENTRE, ANCHOR_MAX, 0, 70); Menu_LayoutBack(&s->cancel); - - Window_3DS_SetRenderScreen(scr); } static void SaveLevelScreen_Init(void* screen) { @@ -1913,14 +1877,10 @@ static void BindsSourceScreen_ContextRecreated(void* screen) { } static void BindsSourceScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct BindsSourceScreen* s = (struct BindsSourceScreen*)screen; Widget_SetLocation(&s->btns[0], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -25); Widget_SetLocation(&s->btns[1], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 25); Menu_LayoutBack(&s->cancel); - - Window_3DS_SetRenderScreen(scr); } static void BindsSourceScreen_Init(void* screen) { @@ -2068,8 +2028,6 @@ static void KeyBindsScreen_ContextRecreated(void* screen) { } static void KeyBindsScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct KeyBindsScreen* s = (struct KeyBindsScreen*)screen; int i, x, y, xDir, leftLen; x = s->btnWidth / 2 + 5; @@ -2090,8 +2048,6 @@ static void KeyBindsScreen_Layout(void* screen) { Widget_SetLocation(&s->left, ANCHOR_CENTRE, ANCHOR_CENTRE, -s->btnWidth - 35, s->arrowsY); Widget_SetLocation(&s->right, ANCHOR_CENTRE, ANCHOR_CENTRE, s->btnWidth + 35, s->arrowsY); - - Window_3DS_SetRenderScreen(scr); } static void KeyBindsScreen_Init(void* screen) { @@ -2373,8 +2329,6 @@ static void MenuInputOverlay_Free(void* screen) { } static void MenuInputOverlay_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct MenuInputOverlay* s = (struct MenuInputOverlay*)screen; if (!Input_TouchMode) { Widget_SetLocation(&s->input, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 110); @@ -2389,8 +2343,6 @@ static void MenuInputOverlay_Layout(void* screen) { Widget_SetLocation(&s->ok, ANCHOR_CENTRE, ANCHOR_CENTRE, 120, 150); Widget_SetLocation(&s->Default, ANCHOR_CENTRE, ANCHOR_CENTRE, -120, 150); } - - Window_3DS_SetRenderScreen(scr); } static void MenuInputOverlay_ContextLost(void* screen) { @@ -2692,14 +2644,10 @@ static void MenuOptionsScreen_Free(void* screen) { } static void MenuOptionsScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen; Screen_Layout(s); Menu_LayoutBack(&s->done); MenuOptionsScreen_LayoutExtHelp(s); - - Window_3DS_SetRenderScreen(scr); } static void MenuOptionsScreen_ContextLost(void* screen) { @@ -3389,15 +3337,11 @@ static void NostalgiaMenuScreen_ContextRecreated(void* screen) { } static void NostalgiaMenuScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct NostalgiaMenuScreen* s = (struct NostalgiaMenuScreen*)screen; Widget_SetLocation(&s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -100); Widget_SetLocation(&s->btnA, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -25); Widget_SetLocation(&s->btnF, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 25); Menu_LayoutBack(&s->done); - - Window_3DS_SetRenderScreen(scr); } static void NostalgiaMenuScreen_Init(void* screen) { @@ -4149,15 +4093,11 @@ static void TouchOnscreenScreen_ContextRecreated(void* screen) { } static void TouchOnscreenScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; Menu_LayoutButtons(s->btns, s->btnDescs, ONSCREEN_PAGE_BTNS); Menu_LayoutBack(&s->back); Widget_SetLocation(&s->left, ANCHOR_CENTRE, ANCHOR_CENTRE, -260, 0); Widget_SetLocation(&s->right, ANCHOR_CENTRE, ANCHOR_CENTRE, 260, 0); - - Window_3DS_SetRenderScreen(scr); } static void TouchOnscreenScreen_Init(void* screen) { @@ -4330,13 +4270,9 @@ static void TouchCtrlsScreen_ContextRecreated(void* screen) { } static void TouchCtrlsScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; Menu_LayoutButtons(s->btns, touchCtrls_btns, TOUCHCTRLS_BTNS); Menu_LayoutBack(&s->back); - - Window_3DS_SetRenderScreen(scr); } static void TouchCtrlsScreen_Init(void* screen) { @@ -4428,13 +4364,9 @@ static void TouchMoreScreen_ContextRecreated(void* screen) { } static void TouchMoreScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct TouchMoreScreen* s = (struct TouchMoreScreen*)screen; Menu_LayoutButtons(s->btns, touchMore_btns, TOUCHMORE_BTNS); Menu_LayoutBack(&s->back); - - Window_3DS_SetRenderScreen(scr); } static void TouchMoreScreen_Init(void* screen) { diff --git a/src/Screens.c b/src/Screens.c index d4b2eb9b9..a85f8a3c0 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -203,13 +203,10 @@ static void HUDScreen_ContextRecreated(void* screen) { static int HUDScreen_LayoutHotbar(void) { enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct HUDScreen* s = &HUDScreen_Instance; s->hotbar.scale = Gui_GetHotbarScale(); Widget_Layout(&s->hotbar); - Window_3DS_SetRenderScreen(scr); - return s->hotbar.height; } @@ -342,6 +339,8 @@ static void HUDScreen_BuildCrosshairsMesh(struct VertexTextured** ptr) { static struct Texture tex = { 0, Tex_Rect(0,0,0,0), Tex_UV(0.0f,0.0f, 15/256.0f,15/256.0f) }; int extent; + enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN); + extent = (int)(CH_EXTENT * Gui_Scale(WindowInfo.Height / 480.0f)); tex.ID = Gui.IconsTex; tex.x = (WindowInfo.Width / 2) - extent; @@ -350,6 +349,8 @@ static void HUDScreen_BuildCrosshairsMesh(struct VertexTextured** ptr) { tex.Width = extent * 2; tex.Height = extent * 2; Gfx_Make2DQuad(&tex, PACKEDCOL_WHITE, ptr); + + Window_3DS_SetRenderScreen(scr); } static void HUDScreen_BuildMesh(void* screen) { @@ -374,6 +375,8 @@ static void HUDScreen_Render(void* screen, double delta) { struct HUDScreen* s = (struct HUDScreen*)screen; if (Game_HideGui) return; + enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN); + Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED); Gfx_BindDynamicVb(s->vb); if (Gui.ShowFPS) Widget_Render2(&s->line1, 4); @@ -387,16 +390,18 @@ static void HUDScreen_Render(void* screen, double delta) { /* TODO swap these two lines back */ } - if (Gui_GetBlocksWorld()) return; + if (!Gui_GetBlocksWorld()) { + Gfx_BindDynamicVb(s->vb); + Widget_Render2(&s->hotbar, 12); - Gfx_BindDynamicVb(s->vb); - Widget_Render2(&s->hotbar, 12); - - if (Gui.IconsTex && !tablist_active) { - Gfx_BindTexture(Gui.IconsTex); - Gfx_BindDynamicVb(s->vb); /* Have to rebind for mobile right now... */ - Gfx_DrawVb_IndexedTris(4); + if (Gui.IconsTex && !tablist_active) { + Gfx_BindTexture(Gui.IconsTex); + Gfx_BindDynamicVb(s->vb); /* Have to rebind for mobile right now... */ + Gfx_DrawVb_IndexedTris(4); + } } + + Window_3DS_SetRenderScreen(scr); } static const struct ScreenVTABLE HUDScreen_VTABLE = { @@ -1224,6 +1229,8 @@ static void ChatScreen_BuildMesh(void* screen) { } static void ChatScreen_Layout(void* screen) { + enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN); + struct ChatScreen* s = (struct ChatScreen*)screen; if (ChatScreen_ChatUpdateFont(s)) ChatScreen_Redraw(s); @@ -1265,6 +1272,8 @@ static void ChatScreen_Layout(void* screen) { Widget_SetLocation(&s->more, ANCHOR_MAX, ANCHOR_MIN, 10, 110); } #endif + + Window_3DS_SetRenderScreen(scr); } static int ChatScreen_KeyPress(void* screen, char keyChar) { @@ -1462,17 +1471,19 @@ static void ChatScreen_Init(void* screen) { static void ChatScreen_Render(void* screen, double delta) { struct ChatScreen* s = (struct ChatScreen*)screen; + enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN); if (Game_HideGui && s->grabsInput) { Elem_Render(&s->input.base, delta); } - if (Game_HideGui) return; + if (!Game_HideGui) { + if (s->grabsInput && !Gui.ClassicChat) { + ChatScreen_DrawChatBackground(s); + } - if (s->grabsInput && !Gui.ClassicChat) { - ChatScreen_DrawChatBackground(s); + ChatScreen_DrawChat(s, delta); } - - ChatScreen_DrawChat(s, delta); + Window_3DS_SetRenderScreen(scr); } static void ChatScreen_Free(void* screen) { @@ -2314,10 +2325,7 @@ static void TouchScreen_ContextRecreated(void* screen) { static void TouchScreen_Render(void* screen, double delta) { if (Gui.InputGrab) return; - - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); Screen_Render2Widgets(screen, delta); - Window_3DS_SetRenderScreen(scr); } static int TouchScreen_PointerDown(void* screen, int id, int x, int y) { @@ -2362,8 +2370,6 @@ static void TouchScreen_PointerUp(void* screen, int id, int x, int y) { } static void TouchScreen_Layout(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct TouchScreen* s = (struct TouchScreen*)screen; const struct TouchButtonDesc* desc; float scale = Gui.RawTouchScale; @@ -2400,8 +2406,6 @@ static void TouchScreen_Layout(void* screen) { s->thumbstick.yOffset += height; s->thumbstick.scale = scale; Widget_Layout(&s->thumbstick); - - Window_3DS_SetRenderScreen(scr); } struct LocalPlayerInput touchInput; @@ -2410,8 +2414,6 @@ static void TouchScreen_GetMovement(float* xMoving, float* zMoving) { } static void TouchScreen_Init(void* screen) { - enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); - struct TouchScreen* s = (struct TouchScreen*)screen; s->widgets = touch_widgets; @@ -2427,8 +2429,6 @@ static void TouchScreen_Init(void* screen) { ThumbstickWidget_Init(&s->thumbstick); touchInput.GetMovement = TouchScreen_GetMovement; LocalPlayer_Instance.input.next = &touchInput; - - Window_3DS_SetRenderScreen(scr); } static void TouchScreen_Free(void* s) { From 4e53ea0ab5372a82783ba2fe29eaf674bdb09325 Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Mon, 22 Jan 2024 16:41:40 -0600 Subject: [PATCH 04/14] put Tablist on top screen --- src/Screens.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Screens.c b/src/Screens.c index 8b2a51ee7..445f0b2dc 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -504,6 +504,8 @@ static void TabListOverlay_Layout(void* screen) { int i, x, y, width = 0, height = 0; int columns = Math_CeilDiv(s->usedCount, LIST_NAMES_PER_COLUMN); + enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN); + for (i = 0; i < columns; i++) { width += TabListOverlay_GetColumnWidth(s, i); @@ -540,6 +542,8 @@ static void TabListOverlay_Layout(void* screen) { s->title.horAnchor = ANCHOR_CENTRE; s->title.yOffset = s->y + paddingY / 2; Widget_Layout(&s->title); + + Window_3DS_SetRenderScreen(scr); } static void TabListOverlay_AddName(struct TabListOverlay* s, EntityID id, int index) { @@ -814,6 +818,9 @@ static void TabListOverlay_Render(void* screen, double delta) { PackedCol bottomCol = PackedCol_Make(50, 50, 50, 205); if (Game_HideGui || !IsOnlyChatActive()) return; + + enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN); + Gfx_Draw2DGradient(s->x, s->y, s->width, s->height, topCol, bottomCol); Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED); @@ -828,6 +835,8 @@ static void TabListOverlay_Render(void* screen, double delta) { Gfx_DrawVb_IndexedTris_Range(4, offset); offset += 4; } + + Window_3DS_SetRenderScreen(scr); } static void TabListOverlay_Free(void* screen) { From e66e99c048fb68dfea1e39375449010027ee325d Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Wed, 24 Jan 2024 10:04:24 -0600 Subject: [PATCH 05/14] don't emulate a mouse click with the 3DS touch. doing so causes unintentional block removal when touch screen buttons are clicked --- src/Window_3DS.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Window_3DS.c b/src/Window_3DS.c index f53bd9cf1..cde7e79af 100644 --- a/src/Window_3DS.c +++ b/src/Window_3DS.c @@ -170,8 +170,7 @@ void Window_ProcessEvents(double delta) { u32 mods = hidKeysDown() | hidKeysHeld(); HandleButtons(mods); - - Input_SetNonRepeatable(CCMOUSE_L, mods & KEY_TOUCH); + ProcessTouchInput(mods); if (Input.RawMode) { From c1adccb0aa8b32ed6a804e69b0d4db2ed196e564 Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Wed, 24 Jan 2024 10:50:27 -0600 Subject: [PATCH 06/14] simplify 3DS touch handling and make it behave more like the Android port --- src/Window_3DS.c | 47 +++++++++++++---------------------------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/src/Window_3DS.c b/src/Window_3DS.c index cde7e79af..9c96527c7 100644 --- a/src/Window_3DS.c +++ b/src/Window_3DS.c @@ -12,7 +12,6 @@ #include "ExtMath.h" #include <3ds.h> -static int touchActive, touchBegX, touchBegY; static cc_bool launcherMode; static Result irrst_result; static enum Screen3DS renderScreen = TOP_SCREEN; @@ -132,36 +131,27 @@ static void ProcessJoystickInput(circlePosition* pos, double delta) { } static void ProcessTouchInput(int mods) { + static int currX, currY; // current touch position touchPosition touch; hidTouchRead(&touch); - touchActive = mods & KEY_TOUCH; - - if (touchActive) { - // rescale X from [0, bottom_FB_width) to [0, top_FB_width) - int x = touch.px * Window_Main.Width / GSP_SCREEN_HEIGHT_BOTTOM; - int y = touch.py; - Pointer_SetPosition(0, x, y); + if (hidKeysDown() & KEY_TOUCH) { // stylus went down + currX = touch.px; + currY = touch.py; + Input_AddTouch(0, currX, currY); } - int x = touch.px; - int y = touch.py; - - // Set starting position for camera movement - if (hidKeysDown() & KEY_TOUCH) { - //Platform_Log2("touch down: %i,%i", &x, &y); - touchBegX = touch.px; - touchBegY = touch.py; - Input_AddTouch(1, touch.px, touch.py); + else if (mods & KEY_TOUCH) { // stylus is down + currX = touch.px; + currY = touch.py; + Input_UpdateTouch(0, currX, currY); } - if (hidKeysUp() & KEY_TOUCH) { - //Platform_Log2("touch up: %i,%i", &x, &y); - Input_RemoveTouch(1, touch.px, touch.py); // TODO: coordinates are 0 + else if (hidKeysUp() & KEY_TOUCH) { // stylus was lifted + Input_RemoveTouch(0, currX, currY); } } void Window_ProcessEvents(double delta) { hidScanInput(); - /* TODO implement */ - + if (!aptMainLoop()) { Window_Main.Exists = false; Window_RequestClose(); @@ -191,18 +181,7 @@ void Cursor_SetPosition(int x, int y) { } // Makes no sense for 3DS void Window_EnableRawMouse(void) { Input.RawMode = true; } void Window_DisableRawMouse(void) { Input.RawMode = false; } -void Window_UpdateRawMouse(void) { - if (!touchActive) return; - - touchPosition touch; - hidTouchRead(&touch); - - Event_RaiseRawMove(&PointerEvents.RawMoved, - touch.px - touchBegX, touch.py - touchBegY); - touchBegX = touch.px; - touchBegY = touch.py; -} - +void Window_UpdateRawMouse(void) { } /*########################################################################################################################* *------------------------------------------------------Framebuffer--------------------------------------------------------* From 5b8a8bc091f36fbb95e730c9d578cf098a48310f Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Wed, 24 Jan 2024 11:28:27 -0600 Subject: [PATCH 07/14] fix positioning of highlighted buttons --- src/Gui.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Gui.c b/src/Gui.c index df20c0942..9fde8f9dc 100644 --- a/src/Gui.c +++ b/src/Gui.c @@ -469,22 +469,26 @@ int Screen_DoPointerDown(void* screen, int id, int x, int y) { struct Screen* s = (struct Screen*)screen; struct Widget** widgets = s->widgets; int i, count = s->numWidgets; + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); /* iterate backwards (because last elements rendered are shown over others) */ for (i = count - 1; i >= 0; i--) { struct Widget* w = widgets[i]; if (!w || !Widget_Contains(w, x, y)) continue; - if (w->flags & WIDGET_FLAG_DISABLED) return i; + if (w->flags & WIDGET_FLAG_DISABLED) break; if (w->MenuClick) { w->MenuClick(s, w); } else { Elem_HandlesPointerDown(w, id, x, y); } - return i; + break; } - return -1; + + Window_3DS_SetRenderScreen(scr); + + return i; } int Screen_Index(void* screen, void* widget) { From 77e9ac632078ff84457aa038ca18932504d93cdb Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Wed, 24 Jan 2024 11:28:53 -0600 Subject: [PATCH 08/14] put chat buttons on bottom screen --- src/Screens.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Screens.c b/src/Screens.c index 445f0b2dc..343391c86 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -1171,9 +1171,11 @@ static void ChatScreen_DrawChat(struct ChatScreen* s, double delta) { #ifdef CC_BUILD_TOUCH if (!Input_TouchMode) return; + enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); Elem_Render(&s->more, delta); Elem_Render(&s->send, delta); Elem_Render(&s->cancel, delta); + Window_3DS_SetRenderScreen(scr); #endif } } @@ -1269,6 +1271,8 @@ static void ChatScreen_Layout(void* screen) { s->smallAnnouncement.yOffset = Window_Main.Height / 20; Widget_Layout(&s->smallAnnouncement); + Window_3DS_SetRenderScreen(scr); + #ifdef CC_BUILD_TOUCH if (Window_Main.SoftKeyboard == SOFT_KEYBOARD_SHIFT) { Widget_SetLocation(&s->send, ANCHOR_MAX, ANCHOR_MAX, 10, 60); @@ -1280,8 +1284,6 @@ static void ChatScreen_Layout(void* screen) { Widget_SetLocation(&s->more, ANCHOR_MAX, ANCHOR_MIN, 10, 110); } #endif - - Window_3DS_SetRenderScreen(scr); } static int ChatScreen_KeyPress(void* screen, char keyChar) { From f0f7da8a165f49bfcd6eb1af64ca6039d94de520 Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Wed, 24 Jan 2024 11:51:30 -0600 Subject: [PATCH 09/14] clarify comment about screen width --- src/Graphics_3DS.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Graphics_3DS.c b/src/Graphics_3DS.c index 976b5948a..f88a9edf5 100644 --- a/src/Graphics_3DS.c +++ b/src/Graphics_3DS.c @@ -129,7 +129,9 @@ static void InitCitro3D(void) { topTarget = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetSetOutput(topTarget, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); - bottomTarget = C3D_RenderTargetCreate(240, 400 /* uhh... not correct, but it works */, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); + // Even though the bottom screen is 320 pixels wide, we use 400 here so that the same ortho matrix + // can be used for both screens. The output is clipped to the actual screen width, anyway. + bottomTarget = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetSetOutput(bottomTarget, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); SetDefaultState(); From 18adec02952f41b172b6ee78aca063f30f10e102 Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Wed, 24 Jan 2024 15:10:27 -0600 Subject: [PATCH 10/14] put launcher titles on 3DS bottom screen --- src/LScreens.c | 12 ------------ src/Launcher.c | 19 +++++++++++++++++++ src/Window_3DS.c | 16 ++++++++++++---- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/LScreens.c b/src/LScreens.c index e793b3cd8..ea611bf06 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -118,18 +118,6 @@ static void LScreen_MouseUp(struct LScreen* s, int idx) { } static void LScreen_MouseWheel(struct LScreen* s, float delta) { } static void LScreen_DrawBackground(struct LScreen* s, struct Context2D* ctx) { - // I don't know of a good place to do this, so I'm sticking it here -#ifdef __3DS__ - enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN); - - // Draw top screen background - Launcher_DrawBackgroundAll(ctx); - Rect2D r = { 0, 0, WindowInfo.Width, WindowInfo.Height }; - Window_DrawFramebuffer(r); - - Window_3DS_SetRenderScreen(scr); -#endif - if (!s->title) { Launcher_DrawBackground(ctx, 0, 0, ctx->width, ctx->height); return; diff --git a/src/Launcher.c b/src/Launcher.c index 528a5eb9b..cf7108ce7 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -536,6 +536,20 @@ void Launcher_DrawTitle(struct FontDesc* font, const char* text, struct Context2 /* Skip dragging logo when very small window to save space */ if (Window_Main.Height < 240) return; +#ifdef __3DS__ + /* Put title on top screen */ + enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN); + struct Bitmap bmp; + struct Context2D topCtx; + + ctx = &topCtx; + bmp.width = max(Window_Main.Width, 1); + bmp.height = max(Window_Main.Height, 1); + Window_AllocFramebuffer(&bmp); + Context2D_Wrap(ctx, &bmp); + Launcher_DrawBackgroundAll(ctx); +#endif + DrawTextArgs_Make(&args, &title, font, false); x = ctx->width / 2 - Drawer2D_TextWidth(&args) / 2; @@ -543,6 +557,11 @@ void Launcher_DrawTitle(struct FontDesc* font, const char* text, struct Context2 Context2D_DrawText(ctx, &args, x + Display_ScaleX(4), Display_ScaleY(4)); Drawer2D.Colors['f'] = BITMAPCOLOR_WHITE; Context2D_DrawText(ctx, &args, x, 0); + +#ifdef __3DS__ + Window_DrawFramebuffer((Rect2D){ 0, 0, bmp.width, bmp.height }); + Window_3DS_SetRenderScreen(scr); +#endif } void Launcher_MakeTitleFont(struct FontDesc* font) { diff --git a/src/Window_3DS.c b/src/Window_3DS.c index 9c96527c7..ed669ba68 100644 --- a/src/Window_3DS.c +++ b/src/Window_3DS.c @@ -186,10 +186,16 @@ void Window_UpdateRawMouse(void) { } /*########################################################################################################################* *------------------------------------------------------Framebuffer--------------------------------------------------------* *#########################################################################################################################*/ -static struct Bitmap fb_bmp; +static struct Bitmap top_fb_bmp; +static struct Bitmap bottom_fb_bmp; void Window_AllocFramebuffer(struct Bitmap* bmp) { bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels"); - fb_bmp = *bmp; + if (renderScreen == TOP_SCREEN) { + top_fb_bmp = *bmp; + } + else { + bottom_fb_bmp = *bmp; + } } void Window_DrawFramebuffer(Rect2D r) { @@ -197,7 +203,7 @@ void Window_DrawFramebuffer(Rect2D r) { gfxScreen_t screen = (renderScreen == TOP_SCREEN) ? GFX_TOP : GFX_BOTTOM; gfxSetDoubleBuffering(screen, false); u8* fb = gfxGetFramebuffer(screen, GFX_LEFT, &width, &height); - + struct Bitmap *bmp = (renderScreen == TOP_SCREEN) ? &top_fb_bmp : &bottom_fb_bmp; // SRC y = 0 to 240 // SRC x = 0 to 400 // DST X = 0 to 240 @@ -206,7 +212,7 @@ void Window_DrawFramebuffer(Rect2D r) { for (int y = r.y; y < r.y + r.Height; y++) for (int x = r.x; x < r.x + r.Width; x++) { - BitmapCol color = Bitmap_GetPixel(&fb_bmp, x, y); + BitmapCol color = Bitmap_GetPixel(bmp, x, y); int addr = (width - 1 - y + x * width) * 3; // TODO -1 or not fb[addr+0] = BitmapCol_B(color); fb[addr+1] = BitmapCol_G(color); @@ -217,10 +223,12 @@ void Window_DrawFramebuffer(Rect2D r) { gfxFlushBuffers(); //gfxSwapBuffers(); // TODO: tearing?? + /* gfxSetDoubleBuffering(GFX_TOP, false); gfxScreenSwapBuffers(GFX_TOP, true); gfxSetDoubleBuffering(GFX_TOP, true); gfxScreenSwapBuffers(GFX_BOTTOM, true); + */ } void Window_FreeFramebuffer(struct Bitmap* bmp) { From a05ac59cc52c0794127d3b33ccb9092200fe2d62 Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Wed, 24 Jan 2024 16:24:58 -0600 Subject: [PATCH 11/14] add an ugly brown background to the touch screen --- src/Gui.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Gui.c b/src/Gui.c index 9fde8f9dc..4824c5039 100644 --- a/src/Gui.c +++ b/src/Gui.c @@ -21,7 +21,9 @@ struct _GuiData Gui; struct Screen* Gui_Screens[GUI_MAX_SCREENS]; static cc_uint8 priorities[GUI_MAX_SCREENS]; - +#ifdef __3DS__ +static struct Texture touchBgTex; +#endif /*########################################################################################################################* *----------------------------------------------------------Gui------------------------------------------------------------* @@ -301,6 +303,10 @@ void Gui_RenderGui(double delta) { enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN); +#ifdef __3DS__ + Texture_Render(&touchBgTex); +#endif + /* Draw back to front so highest priority screen is on top */ for (i = Gui.ScreensCount - 1; i >= 0; i--) { @@ -592,7 +598,6 @@ static void TouchPngProcess(struct Stream* stream, const cc_string* name) { } static struct TextureEntry touch_entry = { "touch.png", TouchPngProcess }; - static void OnFontChanged(void* obj) { Gui_RefreshAll(); } static void OnKeyPress(void* obj, int cp) { @@ -636,6 +641,19 @@ static void OnInit(void) { TextureEntry_Register(&icons_entry); TextureEntry_Register(&touch_entry); +#ifdef __3DS__ + struct Context2D ctx; + Context2D_Alloc(&ctx, 32, 32); + Gradient_Noise(&ctx, BitmapColor_RGB(0x40, 0x30, 0x20), 6, 0, 0, ctx.width, ctx.height); + Context2D_MakeTexture(&touchBgTex, &ctx); + Context2D_Free(&ctx); + // Tile the texture to fill the entire screen + int tilesX = (320 + ctx.width - 1) / ctx.width; + int tilesY = (240 + ctx.height - 1) / ctx.height; + touchBgTex.Width *= tilesX; touchBgTex.Height *= tilesY; + touchBgTex.uv.U2 *= tilesX; touchBgTex.uv.V2 *= tilesY; +#endif + Event_Register_(&ChatEvents.FontChanged, NULL, OnFontChanged); Event_Register_(&GfxEvents.ContextLost, NULL, OnContextLost); Event_Register_(&GfxEvents.ContextRecreated, NULL, OnContextRecreated); From c27c0bd63982e81e60170a5c02a755dd650e7137 Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Wed, 24 Jan 2024 16:37:57 -0600 Subject: [PATCH 12/14] vertically center the title on 3DS --- src/Launcher.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Launcher.c b/src/Launcher.c index cf7108ce7..335ccde6e 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -532,6 +532,7 @@ void Launcher_DrawTitle(struct FontDesc* font, const char* text, struct Context2 cc_string title = String_FromReadonly(text); struct DrawTextArgs args; int x; + int y; /* Skip dragging logo when very small window to save space */ if (Window_Main.Height < 240) return; @@ -552,11 +553,17 @@ void Launcher_DrawTitle(struct FontDesc* font, const char* text, struct Context2 DrawTextArgs_Make(&args, &title, font, false); x = ctx->width / 2 - Drawer2D_TextWidth(&args) / 2; + y = 0; + +#ifdef __3DS__ + // vertically center the title + y = ctx->height / 2 - Drawer2D_TextHeight(&args) / 2; +#endif Drawer2D.Colors['f'] = BITMAPCOLOR_BLACK; - Context2D_DrawText(ctx, &args, x + Display_ScaleX(4), Display_ScaleY(4)); + Context2D_DrawText(ctx, &args, x + Display_ScaleX(4), y + Display_ScaleY(4)); Drawer2D.Colors['f'] = BITMAPCOLOR_WHITE; - Context2D_DrawText(ctx, &args, x, 0); + Context2D_DrawText(ctx, &args, x, y); #ifdef __3DS__ Window_DrawFramebuffer((Rect2D){ 0, 0, bmp.width, bmp.height }); From cdab26b0a5723950631c10c5a1e7f28f2dce56cb Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Wed, 24 Jan 2024 17:23:08 -0600 Subject: [PATCH 13/14] enable double buffering on top screen to fix tearing --- src/Graphics_3DS.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Graphics_3DS.c b/src/Graphics_3DS.c index f88a9edf5..deacd0864 100644 --- a/src/Graphics_3DS.c +++ b/src/Graphics_3DS.c @@ -134,6 +134,7 @@ static void InitCitro3D(void) { bottomTarget = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetSetOutput(bottomTarget, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); + gfxSetDoubleBuffering(GFX_TOP, true); SetDefaultState(); AllocShaders(); } From 8cd740f0543b550ff15ea63e3e0ece06bcca7e69 Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Fri, 26 Jan 2024 19:51:13 -0600 Subject: [PATCH 14/14] remove 3DS exit button combo that I used for debugging --- src/Window_3DS.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Window_3DS.c b/src/Window_3DS.c index ed669ba68..7c49c0855 100644 --- a/src/Window_3DS.c +++ b/src/Window_3DS.c @@ -115,9 +115,6 @@ static void HandleButtons(u32 mods) { Input_SetNonRepeatable(CCPAD_ZL, mods & KEY_ZL); Input_SetNonRepeatable(CCPAD_ZR, mods & KEY_ZR); - - if (mods == (KEY_A|KEY_B|KEY_START|KEY_SELECT)) - Process_Exit(0); } static void ProcessJoystickInput(circlePosition* pos, double delta) {