From d20fc971c953e326ed55ec8084bb88f0e4a116ad Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 2 May 2021 11:31:44 +0200 Subject: [PATCH] android: display cutouts support. render last frame when editing vjoy render in display cutouts gl/vk: render last frame when editing virtual gamepad gl: Fix background handling gui: reset vmus when stopping game --- core/rend/gles/gles.cpp | 22 +++++----- core/rend/gles/imgui_impl_opengl3.cpp | 10 +++-- core/rend/gui.cpp | 44 ++++++++++--------- core/rend/gui.h | 1 + core/rend/gui_android.cpp | 4 +- core/rend/gui_android.h | 2 +- core/rend/gui_cheats.cpp | 3 -- core/rend/vulkan/imgui_impl_vulkan.cpp | 14 ++++-- core/rend/vulkan/vulkan_renderer.h | 1 + .../com/reicast/emulator/BaseGLActivity.java | 5 +++ .../java/com/reicast/emulator/emu/JNIdc.java | 1 + .../reicast/emulator/emu/NativeGLView.java | 14 +++++- .../flycast/src/main/jni/src/Android.cpp | 6 +++ 13 files changed, 81 insertions(+), 46 deletions(-) diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 94eabcaa9..e4b9ca205 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -907,12 +907,22 @@ void UpdatePaletteTexture(GLenum texture_slot) void OSD_DRAW(bool clear_screen) { + gui_display_osd(); #ifdef __ANDROID__ if (gl.OSD_SHADER.osd_tex == 0) gl_load_osd_resources(); if (gl.OSD_SHADER.osd_tex != 0) { - const std::vector& osdVertices = GetOSDVertices(); + glcache.Disable(GL_SCISSOR_TEST); + glViewport(0, 0, screen_width, screen_height); + + if (clear_screen) + { + glcache.ClearColor(0.7f, 0.7f, 0.7f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + render_output_framebuffer(); + glViewport(0, 0, screen_width, screen_height); + } #ifndef GLES2 if (gl.gl_major >= 3) @@ -940,6 +950,7 @@ void OSD_DRAW(bool clear_screen) glBindFramebuffer(GL_FRAMEBUFFER, 0); + const std::vector& osdVertices = GetOSDVertices(); glBufferData(GL_ARRAY_BUFFER, osdVertices.size() * sizeof(OSDVertex), osdVertices.data(), GL_STREAM_DRAW); glCheck(); glcache.Enable(GL_BLEND); @@ -950,14 +961,6 @@ void OSD_DRAW(bool clear_screen) glcache.DepthFunc(GL_ALWAYS); glcache.Disable(GL_CULL_FACE); - glcache.Disable(GL_SCISSOR_TEST); - glViewport(0, 0, screen_width, screen_height); - - if (clear_screen) - { - glcache.ClearColor(0.7f, 0.7f, 0.7f, 1.f); - glClear(GL_COLOR_BUFFER_BIT); - } int dfa = osdVertices.size() / 4; for (int i = 0; i < dfa; i++) @@ -966,7 +969,6 @@ void OSD_DRAW(bool clear_screen) glCheck(); } #endif - gui_display_osd(); } bool ProcessFrame(TA_context* ctx) diff --git a/core/rend/gles/imgui_impl_opengl3.cpp b/core/rend/gles/imgui_impl_opengl3.cpp index 8eb1c6bef..da0afec97 100644 --- a/core/rend/gles/imgui_impl_opengl3.cpp +++ b/core/rend/gles/imgui_impl_opengl3.cpp @@ -99,7 +99,6 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString)); strcpy(g_GlslVersionString, glsl_version); strcat(g_GlslVersionString, "\n"); - ImGui_ImplOpenGL3_DrawBackground(); return true; } @@ -113,8 +112,11 @@ void ImGui_ImplOpenGL3_NewFrame() { if (!g_FontTexture) ImGui_ImplOpenGL3_CreateDeviceObjects(); + ImGui_ImplOpenGL3_DrawBackground(); } +extern int insetLeft, insetTop; // Android notches + // OpenGL3 Render function. // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. @@ -155,7 +157,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) // Setup viewport, orthographic projection matrix // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps. - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glViewport(insetLeft, insetTop, (GLsizei)fb_width, (GLsizei)fb_height); float L = draw_data->DisplayPos.x; float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float T = draw_data->DisplayPos.y; @@ -220,9 +222,9 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) { // Apply scissor/clipping rectangle if (clip_origin_lower_left) - glcache.Scissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); + glcache.Scissor(insetLeft + (int)clip_rect.x, (int)(fb_height - clip_rect.w), insetTop + (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); else - glcache.Scissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) + glcache.Scissor(insetLeft + (int)clip_rect.x, (int)clip_rect.y, insetTop + (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) // Bind texture, Draw glcache.BindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index d24953cf5..a6e082d84 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -49,6 +49,7 @@ extern u8 kb_shift; // shift keys pressed (bitmask) extern u8 kb_key[6]; // normal keys pressed int screen_dpi = 96; +int insetLeft, insetRight, insetTop, insetBottom; static bool inited = false; float scaling = 1; @@ -266,8 +267,8 @@ static void ImGui_Impl_NewFrame() { if (config::RendererType.isOpenGL()) ImGui_ImplOpenGL3_NewFrame(); - ImGui::GetIO().DisplaySize.x = screen_width; - ImGui::GetIO().DisplaySize.y = screen_height; + ImGui::GetIO().DisplaySize.x = screen_width - insetLeft - insetRight; + ImGui::GetIO().DisplaySize.y = screen_height - insetTop - insetBottom; ImGuiIO& io = ImGui::GetIO(); @@ -288,7 +289,7 @@ static void ImGui_Impl_NewFrame() if (mo_x_phy < 0 || mo_x_phy >= screen_width || mo_y_phy < 0 || mo_y_phy >= screen_height) io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); else - io.MousePos = ImVec2(mo_x_phy, mo_y_phy); + io.MousePos = ImVec2(mo_x_phy - insetLeft, mo_y_phy - insetTop); #ifdef __ANDROID__ // Put the "mouse" outside the screen one frame after a touch up // This avoids buttons and the like to stay selected @@ -350,6 +351,14 @@ static void ImGui_Impl_NewFrame() } } +void gui_set_insets(int left, int right, int top, int bottom) +{ + insetLeft = left; + insetRight = right; + insetTop = top; + insetBottom = bottom; +} + #if 0 #include "oslib/timeseries.h" TimeSeries renderTimes; @@ -403,9 +412,6 @@ static void gui_display_commands() { dc_stop(); - if (config::RendererType.isOpenGL()) - ImGui_ImplOpenGL3_DrawBackground(); - display_vmus(); centerNextWindow(); @@ -477,6 +483,7 @@ static void gui_display_commands() gui_state = GuiState::Main; game_started = false; settings.imgread.ImagePath[0] = '\0'; + reset_vmus(); } else { @@ -660,11 +667,11 @@ static void detect_input_popup(int index, bool analog) static void controller_mapping_popup(const std::shared_ptr& gamepad) { ImGui::SetNextWindowPos(ImVec2(0, 0)); - ImGui::SetNextWindowSize(ImVec2(screen_width, screen_height)); + ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); if (ImGui::BeginPopupModal("Controller Mapping", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) { - const float width = screen_width / 2; + const float width = ImGui::GetIO().DisplaySize.x / 2; const float col_width = (width - ImGui::GetStyle().GrabMinSize - (0 + ImGui::GetStyle().ItemSpacing.x) @@ -887,7 +894,7 @@ static void gui_display_settings() RenderType pvr_rend = config::RendererType; bool vulkan = !config::RendererType.isOpenGL(); ImGui::SetNextWindowPos(ImVec2(0, 0)); - ImGui::SetNextWindowSize(ImVec2(screen_width, screen_height)); + ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); ImGui::Begin("Settings", NULL, /*ImGuiWindowFlags_AlwaysAutoResize |*/ ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); @@ -1682,7 +1689,7 @@ inline static void gui_display_demo() static void gui_display_content() { ImGui::SetNextWindowPos(ImVec2(0, 0)); - ImGui::SetNextWindowSize(ImVec2(screen_width, screen_height)); + ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0); @@ -1874,9 +1881,6 @@ static void gui_network_start() static void gui_display_loadscreen() { - if (config::RendererType.isOpenGL()) - ImGui_ImplOpenGL3_DrawBackground(); - centerNextWindow(); ImGui::SetNextWindowSize(ImVec2(330 * scaling, 180 * scaling)); @@ -1969,7 +1973,7 @@ void gui_display_ui() break; case GuiState::VJoyEditCommands: #ifdef __ANDROID__ - gui_display_vjoy_commands(screen_width, screen_height, scaling); + gui_display_vjoy_commands(scaling); #endif break; case GuiState::SelectDisk: @@ -2035,8 +2039,8 @@ void gui_display_osd() if (!message.empty()) { ImGui::SetNextWindowBgAlpha(0); - ImGui::SetNextWindowPos(ImVec2(0, screen_height), ImGuiCond_Always, ImVec2(0.f, 1.f)); // Lower left corner - ImGui::SetNextWindowSize(ImVec2(screen_width, 0)); + ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y), ImGuiCond_Always, ImVec2(0.f, 1.f)); // Lower left corner + ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x, 0)); ImGui::Begin("##osd", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground); @@ -2135,7 +2139,7 @@ static void display_vmus() return; ImGui::SetNextWindowBgAlpha(0); ImGui::SetNextWindowPos(ImVec2(0, 0)); - ImGui::SetNextWindowSize(ImVec2(screen_width, screen_height)); + ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize); ImGui::Begin("vmu-window", NULL, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoFocusOnAppearing); @@ -2154,7 +2158,7 @@ static void display_vmus() if (x == 0) pos.x = VMU_PADDING; else - pos.x = screen_width - VMU_WIDTH - VMU_PADDING; + pos.x = ImGui::GetIO().DisplaySize.x - VMU_WIDTH - VMU_PADDING; if (y == 0) { pos.y = VMU_PADDING; @@ -2163,7 +2167,7 @@ static void display_vmus() } else { - pos.y = screen_height - VMU_HEIGHT - VMU_PADDING; + pos.y = ImGui::GetIO().DisplaySize.y - VMU_HEIGHT - VMU_PADDING; if (i & 1) pos.y -= VMU_HEIGHT + VMU_PADDING; } @@ -2233,7 +2237,7 @@ static void displayCrosshairs() crosshairTexId = ImGui_ImplOpenGL3_CreateCrosshairTexture(getCrosshairTextureData()); ImGui::SetNextWindowBgAlpha(0); ImGui::SetNextWindowPos(ImVec2(0, 0)); - ImGui::SetNextWindowSize(ImVec2(screen_width, screen_height)); + ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize); ImGui::Begin("xhair-window", NULL, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoFocusOnAppearing); diff --git a/core/rend/gui.h b/core/rend/gui.h index c2f7649e2..bbaf7c741 100644 --- a/core/rend/gui.h +++ b/core/rend/gui.h @@ -29,6 +29,7 @@ void gui_open_onboarding(); void gui_term(); void gui_refresh_files(); void gui_cheats(); +void gui_set_insets(int left, int right, int top, int bottom); extern int screen_dpi; extern float scaling; diff --git a/core/rend/gui_android.cpp b/core/rend/gui_android.cpp index e06413508..1f3e358de 100644 --- a/core/rend/gui_android.cpp +++ b/core/rend/gui_android.cpp @@ -29,12 +29,12 @@ void vjoy_reset_editing(); void vjoy_stop_editing(bool canceled); -void gui_display_vjoy_commands(int screen_width, int screen_height, float scaling) +void gui_display_vjoy_commands(float scaling) { centerNextWindow(); ImGui::Begin("Virtual Joystick", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse - | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize); + | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar); if (ImGui::Button("Save", ImVec2(150 * scaling, 50 * scaling))) { diff --git a/core/rend/gui_android.h b/core/rend/gui_android.h index 89c9f90b0..bf8d5a2a3 100644 --- a/core/rend/gui_android.h +++ b/core/rend/gui_android.h @@ -18,5 +18,5 @@ */ #pragma once -void gui_display_vjoy_commands(int screen_width, int screen_height, float scaling); +void gui_display_vjoy_commands(float scaling); void vjoy_start_editing(); diff --git a/core/rend/gui_cheats.cpp b/core/rend/gui_cheats.cpp index 3562dac15..01d31cbd7 100644 --- a/core/rend/gui_cheats.cpp +++ b/core/rend/gui_cheats.cpp @@ -23,9 +23,6 @@ void gui_cheats() { - if (config::RendererType.isOpenGL()) - ImGui_ImplOpenGL3_DrawBackground(); - centerNextWindow(); ImGui::SetNextWindowSize(ImVec2(std::min(screen_width, 600 * scaling), std::min(screen_height, 400 * scaling))); diff --git a/core/rend/vulkan/imgui_impl_vulkan.cpp b/core/rend/vulkan/imgui_impl_vulkan.cpp index 83df6e62f..2148d3139 100644 --- a/core/rend/vulkan/imgui_impl_vulkan.cpp +++ b/core/rend/vulkan/imgui_impl_vulkan.cpp @@ -199,6 +199,8 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory p_buffer_size = new_size; } +extern int insetLeft, insetTop; // Android notches + // Render function // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer) @@ -265,8 +267,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm // Setup viewport: { VkViewport viewport; - viewport.x = 0; - viewport.y = 0; + viewport.x = insetLeft; + viewport.y = insetTop; viewport.width = draw_data->DisplaySize.x; viewport.height = draw_data->DisplaySize.y; viewport.minDepth = 0.0f; @@ -306,8 +308,12 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm // Apply scissor/clipping rectangle // FIXME: We could clamp width/height based on clamped min/max values. VkRect2D scissor; - scissor.offset.x = (int32_t)(pcmd->ClipRect.x - display_pos.x) > 0 ? (int32_t)(pcmd->ClipRect.x - display_pos.x) : 0; - scissor.offset.y = (int32_t)(pcmd->ClipRect.y - display_pos.y) > 0 ? (int32_t)(pcmd->ClipRect.y - display_pos.y) : 0; + scissor.offset.x = (int32_t)(pcmd->ClipRect.x - display_pos.x + insetLeft) > 0 + ? (int32_t)(pcmd->ClipRect.x - display_pos.x + insetLeft) + : 0; + scissor.offset.y = (int32_t)(pcmd->ClipRect.y - display_pos.y + insetTop) > 0 + ? (int32_t)(pcmd->ClipRect.y - display_pos.y + insetTop) + : 0; scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x); scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // FIXME: Why +1 here? vkCmdSetScissor(command_buffer, 0, 1, &scissor); diff --git a/core/rend/vulkan/vulkan_renderer.h b/core/rend/vulkan/vulkan_renderer.h index 5f26035fe..962cd230d 100644 --- a/core/rend/vulkan/vulkan_renderer.h +++ b/core/rend/vulkan/vulkan_renderer.h @@ -169,6 +169,7 @@ public: { GetContext()->NewFrame(); GetContext()->BeginRenderPass(); + GetContext()->PresentLastFrame(); } const float dc2s_scale_h = screen_height / 480.0f; const float sidebarWidth = (screen_width - dc2s_scale_h * 640.0f) / 2; diff --git a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/BaseGLActivity.java b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/BaseGLActivity.java index 025dbbadd..315b87187 100644 --- a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/BaseGLActivity.java +++ b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/BaseGLActivity.java @@ -23,6 +23,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.Window; +import android.view.WindowManager; import com.reicast.emulator.config.Config; import com.reicast.emulator.debug.GenerateLogs; @@ -71,6 +72,10 @@ public abstract class BaseGLActivity extends Activity implements ActivityCompat. window.setNavigationBarColor(0); window.getDecorView().setSystemUiVisibility(SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; + } + if (!getFilesDir().exists()) { getFilesDir().mkdir(); diff --git a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/JNIdc.java b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/JNIdc.java index f22e3cc07..b9e733249 100644 --- a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/JNIdc.java +++ b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/JNIdc.java @@ -37,6 +37,7 @@ public final class JNIdc public static native void guiOpenSettings(); public static native boolean guiIsOpen(); public static native boolean guiIsContentBrowser(); + public static native void guiSetInsets(int left, int right, int top, int bottom); public static void show_osd() { JNIdc.vjoy(14, 1, 0, 0, 0); diff --git a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/NativeGLView.java b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/NativeGLView.java index cfbbdbce6..0bcd29a3f 100644 --- a/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/NativeGLView.java +++ b/shell/android-studio/flycast/src/main/java/com/reicast/emulator/emu/NativeGLView.java @@ -4,15 +4,15 @@ import android.annotation.TargetApi; import android.content.Context; import android.content.SharedPreferences; import android.os.Build; -import android.os.Handler; -import android.os.SystemClock; import android.preference.PreferenceManager; import android.util.AttributeSet; import android.util.DisplayMetrics; +import android.view.DisplayCutout; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; +import android.view.WindowInsets; import com.reicast.emulator.Emulator; import com.reicast.emulator.NativeGLActivity; @@ -71,6 +71,16 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback { super.onLayout(changed, left, top, right, bottom); vjoyDelegate.layout(getWidth(), getHeight()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + // Get the display cutouts if any + WindowInsets insets = getRootWindowInsets(); + if (insets != null) { + DisplayCutout cutout = insets.getDisplayCutout(); + if (cutout != null) + JNIdc.guiSetInsets(cutout.getSafeInsetLeft(), cutout.getSafeInsetRight(), + cutout.getSafeInsetTop(), cutout.getSafeInsetBottom()); + } + } } public void resetEditMode() { diff --git a/shell/android-studio/flycast/src/main/jni/src/Android.cpp b/shell/android-studio/flycast/src/main/jni/src/Android.cpp index 44a480f40..d00dfdffa 100644 --- a/shell/android-studio/flycast/src/main/jni/src/Android.cpp +++ b/shell/android-studio/flycast/src/main/jni/src/Android.cpp @@ -116,6 +116,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_guiOpenSettings(JNIEn JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_guiIsOpen(JNIEnv *env,jobject obj) __attribute__((visibility("default"))); JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_guiIsContentBrowser(JNIEnv *env,jobject obj) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setButtons(JNIEnv *env, jobject obj, jbyteArray data) __attribute__((visibility("default"))); +JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_guiSetInsets(JNIEnv *env, jobject obj, jint left, jint right, jint top, jint bottom) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_init(JNIEnv *env, jobject obj) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_joystickAdded(JNIEnv *env, jobject obj, jint id, jstring name, jint maple_port, jstring junique_id) __attribute__((visibility("default"))); @@ -470,6 +471,11 @@ JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_guiIsContentBrows return gui_is_content_browser(); } +JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_guiSetInsets(JNIEnv *env, jobject obj, jint left, jint right, jint top, jint bottom) +{ + gui_set_insets(left, right, top, bottom); +} + // Audio Stuff static u32 androidaudio_push(const void* frame, u32 amt, bool wait) {