diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index cee37671d..044fa9aa6 100644 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -408,7 +408,6 @@ int main(int argc, wchar* argv[]) #endif int get_mic_data(u8* buffer) { return 0; } -int push_vmu_screen(u8* buffer) { return 0; } void os_DebugBreak() { diff --git a/core/rend/gles/imgui_impl_opengl3.cpp b/core/rend/gles/imgui_impl_opengl3.cpp index 3fe069942..fce30f9fa 100644 --- a/core/rend/gles/imgui_impl_opengl3.cpp +++ b/core/rend/gles/imgui_impl_opengl3.cpp @@ -585,3 +585,20 @@ void ImGui_ImplOpenGL3_DrawBackground() glClear(GL_COLOR_BUFFER_BIT); } } + +ImTextureID ImGui_ImplOpenGL3_CreateVmuTexture(const unsigned int *data) +{ + GLuint tex_id; + glGenTextures(1, &tex_id); + glBindTexture(GL_TEXTURE_2D, tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 48, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + + return reinterpret_cast(tex_id); +} + +void ImGui_ImplOpenGL3_DeleteVmuTexture(ImTextureID tex_id) +{ + glDeleteTextures(1, &(GLuint &)tex_id); +} diff --git a/core/rend/gles/imgui_impl_opengl3.h b/core/rend/gles/imgui_impl_opengl3.h index f736563bb..a5146a6e2 100644 --- a/core/rend/gles/imgui_impl_opengl3.h +++ b/core/rend/gles/imgui_impl_opengl3.h @@ -34,6 +34,8 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_background = false); IMGUI_IMPL_API void ImGui_ImplOpenGL3_DrawBackground(); +IMGUI_IMPL_API ImTextureID ImGui_ImplOpenGL3_CreateVmuTexture(const unsigned int *); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_DeleteVmuTexture(ImTextureID); // Called by Init/NewFrame/Shutdown IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture(); diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index f16414182..e2e9ef357 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -64,6 +64,10 @@ GuiState gui_state = Main; static bool settings_opening; static bool touch_up; +static void display_vmus(); +static void reset_vmus(); +static void term_vmus(); + void gui_init() { if (inited) @@ -290,6 +294,8 @@ static void gui_display_commands() if (!settings_opening) ImGui_ImplOpenGL3_DrawBackground(); + display_vmus(); + ImGui::SetNextWindowPos(ImVec2(screen_width / 2.f, screen_height / 2.f), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); ImGui::SetNextWindowSize(ImVec2(330 * scaling, 0)); @@ -635,6 +641,7 @@ static void gui_display_settings() gui_state = Main; #if DC_PLATFORM == DC_PLATFORM_DREAMCAST maple_ReconnectDevices(); + reset_vmus(); #endif SaveSettings(); } @@ -1470,6 +1477,7 @@ void gui_open_onboarding() void gui_term() { inited = false; + term_vmus(); ImGui_ImplOpenGL3_Shutdown(); ImGui::DestroyContext(); } @@ -1495,3 +1503,93 @@ void gui_refresh_files() game_list_done = false; subfolders_read = false; } + +#define VMU_WIDTH (70 * 48 * scaling / 32) +#define VMU_HEIGHT (70 * scaling) +#define VMU_PADDING (8 * scaling) +static u32 vmu_lcd_data[8][48 * 32]; +static bool vmu_lcd_status[8]; +static ImTextureID vmu_lcd_tex_ids[8]; + +int push_vmu_screen(int vmu_id, u8* buffer) +{ + u32 *p = &vmu_lcd_data[vmu_id][0]; + for (int i = 0; i < ARRAY_SIZE(vmu_lcd_data[vmu_id]); i++, buffer++) + *p++ = *buffer != 0 ? 0xFFFFFFFFu : 0xFF000000u; + vmu_lcd_status[vmu_id] = true; + + return 0; +} + +static const int vmu_coords[8][2] = { + { 0 , 0 }, + { 0 , 0 }, + { 1 , 0 }, + { 1 , 0 }, + { 0 , 1 }, + { 0 , 1 }, + { 1 , 1 }, + { 1 , 1 }, +}; + +static void display_vmus() +{ + if (!game_started) + return; + ImGui::SetNextWindowBgAlpha(0); + ImGui::SetNextWindowPos(ImVec2(0, 0)); + ImGui::SetNextWindowSize(ImVec2(screen_width, screen_height)); + + ImGui::Begin("vmu-window", NULL, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoInputs + | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoFocusOnAppearing); + for (int i = 0; i < 8; i++) + { + if (!vmu_lcd_status[i]) + continue; + + if (vmu_lcd_tex_ids[i] != (ImTextureID)0) + ImGui_ImplOpenGL3_DeleteVmuTexture(vmu_lcd_tex_ids[i]); + vmu_lcd_tex_ids[i] = ImGui_ImplOpenGL3_CreateVmuTexture(vmu_lcd_data[i]); + + int x = vmu_coords[i][0]; + int y = vmu_coords[i][1]; + ImVec2 pos; + if (x == 0) + pos.x = VMU_PADDING; + else + pos.x = screen_width - VMU_WIDTH - VMU_PADDING; + if (y == 0) + { + pos.y = VMU_PADDING; + if (i & 1) + pos.y += VMU_HEIGHT + VMU_PADDING; + } + else + { + pos.y = screen_height - VMU_HEIGHT - VMU_PADDING; + if (i & 1) + pos.y -= VMU_HEIGHT + VMU_PADDING; + } + ImVec2 pos_b(pos.x + VMU_WIDTH, pos.y + VMU_HEIGHT); + ImGui::GetWindowDrawList()->AddImage(vmu_lcd_tex_ids[i], pos, pos_b, ImVec2(0, 1), ImVec2(1, 0), 0xC0ffffff); + } + ImGui::End(); +} + +static void reset_vmus() +{ + for (int i = 0; i < ARRAY_SIZE(vmu_lcd_status); i++) + vmu_lcd_status[i] = false; +} + +static void term_vmus() +{ + for (int i = 0; i < ARRAY_SIZE(vmu_lcd_status); i++) + { + if (vmu_lcd_tex_ids[i] != (ImTextureID)0) + { + ImGui_ImplOpenGL3_DeleteVmuTexture(vmu_lcd_tex_ids[i]); + vmu_lcd_tex_ids[i] = (ImTextureID)0; + } + } +} diff --git a/core/rend/gui_util.cpp b/core/rend/gui_util.cpp index d1c6ede53..f9e9ce91b 100644 --- a/core/rend/gui_util.cpp +++ b/core/rend/gui_util.cpp @@ -183,7 +183,7 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca } ImGui::Text("%s", error_message.empty() ? select_current_directory.c_str() : error_message.c_str()); - ImGui::BeginChild(ImGui::GetID("dir_list"), ImVec2(0, -ImGui::CalcTextSize("Cancel").y - ImGui::GetStyle().FramePadding. y * 2 - ImGui::GetStyle().ItemSpacing.y), true); + ImGui::BeginChild(ImGui::GetID("dir_list"), ImVec2(0, - 30 * scaling - ImGui::GetStyle().ItemSpacing.y), true); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8 * scaling, 20 * scaling)); // from 8, 4 @@ -245,14 +245,14 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca } ImGui::PopStyleVar(); ImGui::EndChild(); - if (ImGui::Button("Select Current Directory")) + if (ImGui::Button("Select Current Directory", ImVec2(0, 30 * scaling))) { subfolders_read = false; callback(false, select_current_directory); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); - if (ImGui::Button("Cancel")) + if (ImGui::Button("Cancel", ImVec2(0, 30 * scaling))) { subfolders_read = false; callback(true, ""); diff --git a/shell/android-studio/reicast/src/main/jni/src/Android.cpp b/shell/android-studio/reicast/src/main/jni/src/Android.cpp index 917586e8c..3ab96e5dd 100644 --- a/shell/android-studio/reicast/src/main/jni/src/Android.cpp +++ b/shell/android-studio/reicast/src/main/jni/src/Android.cpp @@ -315,10 +315,6 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_diskSwap(JNIEnv *env, //stuff for microphone jobject sipemu; jmethodID getmicdata; -//stuff for vmu lcd -jobject vmulcd = NULL; -jbyteArray jpix = NULL; -jmethodID updatevmuscreen; extern bool game_started; //stuff for audio @@ -333,12 +329,6 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupMic(JNIEnv *env, getmicdata = env->GetMethodID(env->GetObjectClass(sipemu),"getData","()[B"); } -JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupVmu(JNIEnv *env,jobject obj,jobject vmu) -{ - vmulcd = env->NewGlobalRef(vmu); - updatevmuscreen = env->GetMethodID(env->GetObjectClass(vmu),"updateBytes","([B)V"); -} - JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,jobject obj) { if (game_started) @@ -362,18 +352,6 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,j dc_term(); } -JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vmuSwap(JNIEnv *env,jobject obj) -{ - maple_device* olda = MapleDevices[0][0]; - maple_device* oldb = MapleDevices[0][1]; - MapleDevices[0][0] = NULL; - MapleDevices[0][1] = NULL; - usleep(50000);//50 ms, wait for host to detect disconnect - - MapleDevices[0][0] = oldb; - MapleDevices[0][1] = olda; -} - JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_send(JNIEnv *env,jobject obj,jint cmd, jint param) { if (cmd==0) @@ -584,19 +562,6 @@ int get_mic_data(u8* buffer) return 1; } -int push_vmu_screen(u8* buffer) -{ - if(vmulcd==NULL){ - return 0; - } - if(jpix==NULL){ - jpix = jvm_attacher.getEnv()->NewByteArray(1536); - } - jvm_attacher.getEnv()->SetByteArrayRegion(jpix, 0, 1536, (jbyte*)buffer); - jvm_attacher.getEnv()->CallVoidMethod(vmulcd, updatevmuscreen, jpix); - return 1; -} - void os_DebugBreak() { // TODO: notify the parent thread about it ...