diff --git a/pcsx2/ImGui/FullscreenUI.cpp b/pcsx2/ImGui/FullscreenUI.cpp index 0b210c1dd5b59..718b4d3f8c13e 100644 --- a/pcsx2/ImGui/FullscreenUI.cpp +++ b/pcsx2/ImGui/FullscreenUI.cpp @@ -4571,8 +4571,25 @@ static void DrawShadowedText( void FullscreenUI::DrawPauseMenu(MainWindowType type) { + + ImDrawList* dl = ImGui::GetBackgroundDrawList(); const ImVec2 display_size(ImGui::GetIO().DisplaySize); + + bool reduceSize = (EmuConfig.CurrentAspectRatio == AspectRatioType::R4_3 || EmuConfig.CurrentAspectRatio == AspectRatioType::RAuto4_3_3_2); + float minsize = 0.0f; + float aspectRatio = 1; + if (reduceSize) + { + aspectRatio = (4.0f / 3.0f); + if (EmuConfig.CurrentAspectRatio == AspectRatioType::RAuto4_3_3_2 && GSgetDisplayMode() == GSVideoMode::SDTV_480P) + { + aspectRatio = (3.0f / 2.0f); + } + minsize = (display_size.x - (display_size.y * aspectRatio)) / 2.0f; + } + + const ImU32 text_color = IM_COL32(UIBackgroundTextColor.x * 255, UIBackgroundTextColor.y * 255, UIBackgroundTextColor.z * 255, 255); dl->AddRectFilled( ImVec2(0.0f, 0.0f), display_size, IM_COL32(UIBackgroundColor.x * 255, UIBackgroundColor.y * 255, UIBackgroundColor.z * 255, 200)); @@ -4592,10 +4609,10 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type) g_medium_font->FontSize, std::numeric_limits::max(), -1.0f, s_current_game_subtitle.c_str())); ImVec2 title_pos( - display_size.x - LayoutScale(10.0f + image_width + 20.0f) - title_size.x, display_size.y - LayoutScale(10.0f + image_height)); - ImVec2 path_pos(display_size.x - LayoutScale(10.0f + image_width + 20.0f) - path_size.x, + display_size.x - LayoutScale(10.0f + image_width + 20.0f) - title_size.x -minsize, display_size.y - LayoutScale(10.0f + image_height)); + ImVec2 path_pos(display_size.x - LayoutScale(10.0f + image_width + 20.0f) - path_size.x - minsize, title_pos.y + g_large_font->FontSize + LayoutScale(4.0f)); - ImVec2 subtitle_pos(display_size.x - LayoutScale(10.0f + image_width + 20.0f) - subtitle_size.x, + ImVec2 subtitle_pos(display_size.x - LayoutScale(10.0f + image_width + 20.0f) - subtitle_size.x - minsize, (path_string.empty() ? title_pos.y + g_large_font->FontSize : path_pos.y + g_medium_font->FontSize) + LayoutScale(4.0f)); float rp_height = 0.0f; @@ -4633,7 +4650,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type) GSTexture* const cover = GetCoverForCurrentGame(); const ImVec2 image_min( - display_size.x - LayoutScale(10.0f + image_width), display_size.y - LayoutScale(10.0f + image_height) - rp_height); + display_size.x - LayoutScale(10.0f + image_width)- minsize, display_size.y - LayoutScale(10.0f + image_height) - rp_height); const ImVec2 image_max(image_min.x + LayoutScale(image_width), image_min.y + LayoutScale(image_height) + rp_height); const ImRect image_rect(CenterImage( ImRect(image_min, image_max), ImVec2(static_cast(cover->GetWidth()), static_cast(cover->GetHeight())))); @@ -4653,7 +4670,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type) std::strftime(buf, sizeof(buf), "%X", <ime); const ImVec2 time_size(g_large_font->CalcTextSizeA(g_large_font->FontSize, std::numeric_limits::max(), -1.0f, buf)); - const ImVec2 time_pos(display_size.x - LayoutScale(10.0f) - time_size.x, LayoutScale(10.0f)); + const ImVec2 time_pos(display_size.x - LayoutScale(10.0f) - time_size.x - minsize, LayoutScale(10.0f)); DrawShadowedText(dl, g_large_font, time_pos, text_color, buf); if (!s_current_disc_serial.empty()) @@ -4667,19 +4684,19 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type) buf.fmt(FSUI_FSTR("This Session: {}"), session_time_str); const ImVec2 session_size(g_medium_font->CalcTextSizeA(g_medium_font->FontSize, std::numeric_limits::max(), -1.0f, buf)); const ImVec2 session_pos( - display_size.x - LayoutScale(10.0f) - session_size.x, time_pos.y + g_large_font->FontSize + LayoutScale(4.0f)); + display_size.x - LayoutScale(10.0f) - session_size.x - minsize, time_pos.y + g_large_font->FontSize + LayoutScale(4.0f)); DrawShadowedText(dl, g_medium_font, session_pos, text_color, buf); buf.fmt(FSUI_FSTR("All Time: {}"), played_time_str); const ImVec2 total_size(g_medium_font->CalcTextSizeA(g_medium_font->FontSize, std::numeric_limits::max(), -1.0f, buf)); const ImVec2 total_pos( - display_size.x - LayoutScale(10.0f) - total_size.x, session_pos.y + g_medium_font->FontSize + LayoutScale(4.0f)); + display_size.x - LayoutScale(10.0f) - total_size.x - minsize, session_pos.y + g_medium_font->FontSize + LayoutScale(4.0f)); DrawShadowedText(dl, g_medium_font, total_pos, text_color, buf); } } const ImVec2 window_size(LayoutScale(500.0f, LAYOUT_SCREEN_HEIGHT)); - const ImVec2 window_pos(0.0f, display_size.y - window_size.y); + const ImVec2 window_pos(minsize, display_size.y - window_size.y); if (BeginFullscreenWindow( window_pos, window_size, "pause_menu", ImVec4(0.0f, 0.0f, 0.0f, 0.0f), 0.0f, 10.0f, ImGuiWindowFlags_NoBackground)) @@ -4943,6 +4960,19 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading) { ImGuiIO& io = ImGui::GetIO(); + bool reduceSize = (EmuConfig.CurrentAspectRatio == AspectRatioType::R4_3 || EmuConfig.CurrentAspectRatio == AspectRatioType::RAuto4_3_3_2); + float minsize = 0.0f; + float aspectRatio = 1; + if (reduceSize) + { + aspectRatio = (4.0f / 3.0f); + if (EmuConfig.CurrentAspectRatio == AspectRatioType::RAuto4_3_3_2 && GSgetDisplayMode() == GSVideoMode::SDTV_480P) + { + aspectRatio = (3.0f / 2.0f); + } + minsize = (io.DisplaySize.x - (io.DisplaySize.y * aspectRatio)) / 2.0f; + } + ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f)); ImGui::SetNextWindowSize(io.DisplaySize); @@ -5015,7 +5045,7 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading) const float item_height = (style.FramePadding.y * 2.0f) + image_height + title_spacing + g_large_font->FontSize + summary_spacing + g_medium_font->FontSize; const ImVec2 item_size(item_width, item_height); - const u32 grid_count_x = std::floor(ImGui::GetWindowWidth() / item_width_with_spacing); + const u32 grid_count_x = std::floor((ImGui::GetWindowWidth() - (minsize*2)) / item_width_with_spacing); const float start_x = (static_cast(ImGui::GetWindowWidth()) - (item_width_with_spacing * static_cast(grid_count_x))) * 0.5f; diff --git a/pcsx2/USB/usb-lightgun/guncon2.cpp b/pcsx2/USB/usb-lightgun/guncon2.cpp index a48bd27bd4c70..831e7fba95b8a 100644 --- a/pcsx2/USB/usb-lightgun/guncon2.cpp +++ b/pcsx2/USB/usb-lightgun/guncon2.cpp @@ -124,6 +124,7 @@ namespace usb_lightgun explicit GunCon2State(u32 port_); ~GunCon2State(); void SetTrigggerState(bool on); + void SendComMessage(const std::string& message); USBDevice dev{}; USBDesc desc{}; USBDescDevice desc_dev{}; @@ -186,6 +187,7 @@ namespace usb_lightgun int lastOther1 = 0; int lastOther2 = 0; bool fullAutoActive = false; + bool twoplayerfix = false; float m_gun4irComPort = 0; int gun4irComPort = 0; HANDLE serialPort; @@ -374,9 +376,27 @@ namespace usb_lightgun GunCon2State::~GunCon2State() { - active_game = ""; - quitThread = true; + if (myThread != nullptr) + { + if (serialPort != INVALID_HANDLE_VALUE) + { + GunCon2State::SendComMessage("E"); + CloseHandle(serialPort); + serialPort = INVALID_HANDLE_VALUE; + } + active_game = ""; + quitThread = true; + myThread->join(); + } + if (myThreadAutoConfigure != nullptr) + { + quitThread = true; + myThreadAutoConfigure->join(); + } + + Console.WriteLn("NIXX : GunCon2State -> Destroy"); + } void GunCon2State::SetTrigggerState(bool on) @@ -399,10 +419,72 @@ namespace usb_lightgun } } + void GunCon2State::SendComMessage(const std::string& message) + { + if (serialPort != INVALID_HANDLE_VALUE) + { + DWORD bytesWritten; + DWORD messageLength = static_cast(message.length()); + WriteFile(serialPort, message.c_str(), messageLength, &bytesWritten, NULL); + } + } + void GunCon2State::threadOutputs() { threadOutputLoaded = true; Console.WriteLn("THREAD : Thread Start"); + + if (active_game != "") + { + bool validcom = false; + if (gun4irComPort > 0) + { + validcom = true; + std::string serialPortName = "COM" + std::to_string(gun4irComPort); + if (gun4irComPort >= 10) + { + serialPortName = "\\\\.\\COM" + std::to_string(gun4irComPort); + } + serialPort = CreateFileA(serialPortName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (serialPort == INVALID_HANDLE_VALUE) + { + validcom = false; + } + if (validcom) + { + DCB dcbSerialParams = {0}; + dcbSerialParams.DCBlength = sizeof(dcbSerialParams); + + if (!GetCommState(serialPort, &dcbSerialParams)) + { + validcom = false; + } + if (validcom) + { + dcbSerialParams.BaudRate = 9600; + dcbSerialParams.ByteSize = 8; + dcbSerialParams.StopBits = ONESTOPBIT; + dcbSerialParams.Parity = NOPARITY; + } + if (!SetCommState(serialPort, &dcbSerialParams)) + { + validcom = false; + } + } + } + if (validcom) + { + GunCon2State::SendComMessage("S6"); + } + else + { + serialPort = INVALID_HANDLE_VALUE; + } + } + + while (VMManager::HasValidVM() && active_game != "" && !quitThread) { std::chrono::microseconds::rep timestamp = @@ -410,7 +492,8 @@ namespace usb_lightgun .count(); std::string output_signal = ""; - if (active_game == "SLES-50930") //Dino Stalker (E, English) + //Dino Stalker (E, English) + if (active_game == "SLES-50930") { bool valid_query = false; u8 ammoFirst = 0; @@ -435,7 +518,8 @@ namespace usb_lightgun } } - if (active_game == "SLES-51095") //Dino Stalker (E, French) + //Dino Stalker (E, French) + if (active_game == "SLES-51095") { bool valid_query = false; u8 ammoFirst = 0; @@ -459,7 +543,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - if (active_game == "SLUS-20485") //Dino Stalker (USA) + //Dino Stalker (USA) + if (active_game == "SLUS-20485") { bool valid_query = false; u8 ammoFirst = 0; @@ -483,7 +568,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - if (active_game == "SLUS-20389") //EndGame US + //EndGame US + if (active_game == "SLUS-20389") { bool valid_query = false; u32 PointerAmmo = 0; @@ -512,8 +598,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SLPM-65139") //Gun Survivor 3: Dino Crisis (J) + //Gun Survivor 3: Dino Crisis (J) + if (active_game == "SLPM-65139") { bool valid_query = false; u8 ammoFirst = 0; @@ -537,8 +623,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SLES-52620") //Guncom 2 (E) + //Guncom 2 (E) + if (active_game == "SLES-52620") { bool valid_query = false; u8 ammoCount = 0; @@ -563,8 +649,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SLES-51289") //Gunfighter 2 - Jesse James (E) + //Gunfighter 2 - Jesse James (E) + if (active_game == "SLES-51289") { bool valid_query = false; u32 PointerAmmo = 0; @@ -596,8 +682,8 @@ namespace usb_lightgun } } - - if (active_game == "SLPS-25165") //Gunvari Collection (J) (480i) : Only time crisis + //Gunvari Collection (J) (480i) : Only time crisis + if (active_game == "SLPS-25165") { bool valid_query = false; u8 ammoCount = 0; @@ -617,8 +703,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SLUS-20492") //Ninja Assault (U) + //Ninja Assault (U) + if (active_game == "SLUS-20492") { bool valid_query = false; u8 ammoCount = 0; @@ -644,8 +730,8 @@ namespace usb_lightgun } } - - if (active_game == "SLES-50650") //Resident Evil Survivor 2 (E) + //Resident Evil Survivor 2 (E) + if (active_game == "SLES-50650") { bool valid_query = false; u8 ammoCount = 0; @@ -665,8 +751,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SLUS-20669") //Resident Evil Dead Aim US + //Resident Evil Dead Aim US + if (active_game == "SLUS-20669") { bool valid_query = false; u8 ammoCount = 0; @@ -686,8 +772,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SLES-51617") //Starsky & Hutch (E) + //Starsky & Hutch (E) + if (active_game == "SLES-51617") { bool valid_query = false; u8 ammoCount = 0; @@ -707,8 +793,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SLUS-20619") //Starsky & Hutch (U) + //Starsky & Hutch (U) + if (active_game == "SLUS-20619") { bool valid_query = false; u8 ammoCount = 0; @@ -728,11 +814,14 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SCES-50300") //Time Crisis 2 EU + //Time Crisis 2 EU + if (active_game == "SCES-50300") { bool valid_query = false; u32 ammoCount = 0; + + twoplayerfix = memRead8(0x65CD24) == 1 ? true : false; + if (port == 0) { valid_query = true; @@ -753,11 +842,14 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SLUS-20219") //Time Crisis 2 US + //Time Crisis 2 US + if (active_game == "SLUS-20219") { bool valid_query = false; u32 ammoCount = 0; + + twoplayerfix = memRead8(0x63EE64) == 1 ? true : false; + if (port == 0) { valid_query = true; @@ -779,12 +871,15 @@ namespace usb_lightgun } } - - if (active_game == "SCES-51844") //Time Crisis 3 EU + //Time Crisis 3 EU + if (active_game == "SCES-51844") { bool valid_query = false; u32 ammoCount = 0; u32 weaponType = 0; + + twoplayerfix = memRead8(0x474EEC) == 1 ? true : false; + if (port == 0) { valid_query = true; @@ -807,12 +902,15 @@ namespace usb_lightgun lastWeapon = weaponType; } } - - if (active_game == "SLUS-20645") //Time Crisis 3 US + //Time Crisis 3 US + if (active_game == "SLUS-20645") { bool valid_query = false; u32 ammoCount = 0; u32 weaponType = 0; + + twoplayerfix = memRead8(0x43A16C) == 1 ? true : false; + if (port == 0) { valid_query = true; @@ -835,8 +933,8 @@ namespace usb_lightgun lastWeapon = weaponType; } } - - if (active_game == "SLUS-20927") //Time Crisis Crisis Zone US + //Time Crisis Crisis Zone US + if (active_game == "SLUS-20927") { bool valid_query = false; u32 ammoCount = 0; @@ -863,8 +961,8 @@ namespace usb_lightgun lastWeapon = weaponType; } } - - if (active_game == "SLUS-20221") //Vampire Night (U) + //Vampire Night (U) + if (active_game == "SLUS-20221") { bool valid_query = false; u32 ammoCount = 0; @@ -887,8 +985,8 @@ namespace usb_lightgun lastAmmo = ammoCount; } } - - if (active_game == "SLES-51229") //Virtua Cop Elite Edition + //Virtua Cop Elite Edition + if (active_game == "SLES-51229") { bool valid_query = false; u32 ammoCount = 0; @@ -1004,22 +1102,37 @@ namespace usb_lightgun { Console.WriteLn("GUN B : SHOT (%lld)", diffgunshot); } - /* + if (serialPort != INVALID_HANDLE_VALUE) { - GunCon::SendComMessage("F0x2x0x"); + GunCon2State::SendComMessage("F0x2x0x"); } - */ + MameHookerProxy::GetInstance().Gunshot(port); } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } + if (serialPort != INVALID_HANDLE_VALUE) + { + GunCon2State::SendComMessage("E"); + CloseHandle(serialPort); + serialPort = INVALID_HANDLE_VALUE; + } Console.WriteLn("THREAD : Thread stop"); } void GunCon2State::threadAutoConfigure() { + + std::vector liste_ids_recoil = { + "SLES-50930", "SLES-51095", "SLUS-20485", "SLUS-20389", "SLPM-65139", + "SLES-52620", "SLES-51289", "SLPS-25165", "SLUS-20492", "SLES-50650", + "SLUS-20669", "SLES-51617", "SLUS-20619", "SCES-50300", "SLUS-20219", + "SCES-51844", "SLUS-20645", "SLUS-20927", "SLUS-20221", "SLES-51229" + }; + + int i = 0; while (threadOutputLoaded == false) { @@ -1036,6 +1149,19 @@ namespace usb_lightgun if (serial != "" && active_game == "" && VMManager::HasValidVM()) { active_game = serial; + + bool id_present = false; + for (const std::string& id : liste_ids_recoil) + { + if (id == active_game) + { + id_present = true; + break; + } + } + if (id_present == false) + return; + myThread = new std::thread(&GunCon2State::threadOutputs, this); //AutoConfigure(); return; @@ -1052,12 +1178,13 @@ namespace usb_lightgun std::string serial = VMManager::GetDiscSerial(); Console.WriteLn("NIXX : GunCon2State -> Start GunCon %d for %s", port, serial.c_str()); - + /* if (active_game == "" && serial != "") { active_game = serial; myThread = new std::thread(&GunCon2State::threadOutputs, this); } + */ @@ -1093,7 +1220,7 @@ namespace usb_lightgun //Apply aim adjustement for 2 players TimeCrisis if Widescreen on float pointer_x2 = pointer_x; float pointer_y2 = pointer_y; - if ((active_game == "SLUS-20219" || active_game == "SCES-50300" || active_game == "SCES-51844" || active_game == "SLUS-20645") && EmuConfig.CurrentAspectRatio == AspectRatioType::R16_9) + if ((active_game == "SLUS-20219" || active_game == "SCES-50300" || active_game == "SCES-51844" || active_game == "SLUS-20645") && twoplayerfix)// && EmuConfig.CurrentAspectRatio == AspectRatioType::R16_9) { if (active_game == "SLUS-20219") { @@ -1333,6 +1460,7 @@ namespace usb_lightgun GunCon2State* s = USB_CONTAINER_OF(dev, GunCon2State, dev); s->custom_config = USB::GetConfigBool(si, s->port, TypeName(), "custom_config", false); + s->gun4irComPort = USB::GetConfigInt(si, s->port, TypeName(), "Gun4IRComPort", 0); // Don't override auto config if we've set it. if (!s->auto_config_done || s->custom_config) @@ -1471,6 +1599,9 @@ namespace usb_lightgun TRANSLATE_NOOP("USB", "Applies a color to the chosen crosshair images, can be used for multiple " "players. Specify in HTML/CSS format (e.g. #aabbcc)"), "#ffffff"}, + {SettingInfo::Type::Integer, "Gun4IRComPort", TRANSLATE_NOOP("USB", "Gun4Ir Com port"), + TRANSLATE_NOOP("USB", "Com port to enable recoil, 0=disabled"), "0", "0", "99", "1", TRANSLATE_NOOP("USB", "%d COM"), + nullptr, nullptr, 1.0f}, {SettingInfo::Type::Boolean, "custom_config", TRANSLATE_NOOP("USB", "Manual Screen Configuration"), TRANSLATE_NOOP("USB", "Forces the use of the screen parameters below, instead of automatic parameters if available."), diff --git a/pcsx2/VMManager.cpp b/pcsx2/VMManager.cpp index 17d7d485fb12d..56dc079aceb47 100644 --- a/pcsx2/VMManager.cpp +++ b/pcsx2/VMManager.cpp @@ -1060,6 +1060,28 @@ void VMManager::UpdateDiscDetails(bool booting) { MameHookerProxy::GetInstance().StartGame(s_disc_serial); } + + + std::string exePath = FileSystem::GetProgramPath(); + size_t found = exePath.find_last_of("\\"); + if (found != std::string::npos) + { + std::string ReshadeFile = exePath.substr(0, found + 1) + "ReShade.ini"; + std::string ReshadeDefault = exePath.substr(0, found + 1) + "DefaultReshadePreset.ini"; + std::string ReshadeGame = exePath.substr(0, found + 1) + s_disc_serial + ".ini"; + if (FileSystem::FileExists(ReshadeFile.c_str()) && FileSystem::FileExists(ReshadeDefault.c_str())) + { + if (FileSystem::FileExists(ReshadeGame.c_str())) + { + + WritePrivateProfileStringA("GENERAL", "PresetPath", ReshadeGame.c_str(), ReshadeFile.c_str()); + } + else + { + WritePrivateProfileStringA("GENERAL", "PresetPath", ReshadeDefault.c_str(), ReshadeFile.c_str()); + } + } + } } void VMManager::ClearDiscDetails()