Fix bugs reported in the launcher beta testing

This commit is contained in:
mateusfavarin 2024-07-20 21:07:40 -03:00
parent 6a76670186
commit 8541ce81e9
10 changed files with 73 additions and 118 deletions

View File

@ -141,11 +141,6 @@ struct OnlineCTR
char lastWindowsClientSync;
char desiredFPS;
// control when PSX and PC send/recv
char sleepControl;
char gpuSubmitTooLate;
char enableDeferredGPU;
};
STATIC_ASSERT2(sizeof(struct OnlineCTR) <= 0x400, "Size of OnlineCTR must be lte 1kb");

View File

@ -5,23 +5,6 @@ typedef void (*VehicleFuncPtr)(struct Thread* thread, struct Driver* driver);
#ifdef USE_ONLINE
#include "../AltMods/OnlineCTR/global.h"
void RunVehicleThread(VehicleFuncPtr func, struct Thread* thread, struct Driver* driver);
#pragma optimize("", off)
void FrameStall()
{
// dont stall for this
if(octr->CurrState < LOBBY_HOST_TRACK_PICK)
return;
// wait for PC client to reset
while (octr->sleepControl == 1)
{
// required, or the register never updates
printf("");
}
}
#pragma optimize("", on)
#endif
void DECOMP_MainFrame_GameLogic(struct GameTracker* gGT, struct GamepadSystem* gGamepads)
@ -221,7 +204,7 @@ LAB_80035098:
(gGT->threadBuckets[iVar4].thread != 0)
)
{
// online multiplayer
#ifdef USE_ONLINE
@ -234,37 +217,31 @@ LAB_80035098:
if(gGT->trafficLightsTimer > 3600)
continue;
}
if (iVar4 == 0)
{
struct Driver* dOnline = gGT->drivers[0];
if(dOnline != 0)
{
struct Thread* dThread = dOnline->instSelf->thread;
DECOMP_VehPickupItem_ShootOnCirclePress(dOnline);
RunVehicleSet13(dThread, dOnline);
octr->sleepControl = 1;
octr->desiredFPS = FPS_DOUBLE(30);
// stall
if(octr->enableDeferredGPU == 1)
FrameStall();
}
for(int other = 1; other < 8; other++)
{
dOnline = gGT->drivers[other];
if(dOnline == 0) continue;
struct Thread* dThread = dOnline->instSelf->thread;
RunVehicleSet13(dThread, dOnline);
}
}
// offline
#else
if (iVar4 == 0)

View File

@ -340,7 +340,7 @@ void DECOMP_MainFrame_RenderFrame(struct GameTracker* gGT, struct GamepadSystem*
if((gGT->renderFlags & 0x8000) != 0)
{
WindowBoxLines(gGT);
WindowDivsionLines(gGT);
}
#endif
@ -1483,7 +1483,7 @@ void MultiplayerWumpaHUD(struct GameTracker* gGT)
for(int i = 0; i < gGT->numPlyrCurrGame; i++)
{
struct Driver* d = gGT->drivers[i];
// if race is over for driver
if((d->actionsFlagSet & 0x2000000) != 0)
{
@ -1711,16 +1711,10 @@ void RenderVSYNC(struct GameTracker* gGT)
if(ReadyToFlip(gGT))
{
#ifdef USE_ONLINE
if(boolFirstFrame)
octr->gpuSubmitTooLate = 1;
#endif
// quit, end of stall
return;
}
#ifdef USE_ONLINE
// gpu submission is not too late,
// we got to this while() loop before

View File

@ -22,7 +22,7 @@
//#define USE_VR // Virtual Reality
#ifdef USE_ONLINE
#define USE_60FPS
//#define USE_60FPS
#define USE_BOOSTBAR
#define USE_16BY9
#define USE_RAMEX

View File

@ -1281,18 +1281,7 @@ int main(int argc, char *argv[])
//perhaps instead of reading, keep a local counter, increment that, and then
//write it (without needing a blocking read first).
(*octr.get()).windowsClientSync++;
if (octr.get()->windowsClientSync == 0)
{
// On Niko's computer with MAPPED MEMORY
// 30fps 1x resolution = 4500
// 30fps 9x resolution = 2500
// 60fps = 0
// With the new PINE system, always zero,
// We can not defer the GPU until the PC port is done :(
//printf("Debug: SleepCount=%d\n", sleepCount);
}
octr.startWrite();
// should rename to room selection
if (octr.get()->CurrState >= LAUNCH_PICK_ROOM)
@ -1300,55 +1289,18 @@ int main(int argc, char *argv[])
StartAnimation();
// Wait for PSX to have P1 data,
// which is set at octr->sleepControl
void FrameStall(); FrameStall();
if (octr.get()->CurrState >= 0)
ClientState[octr.get()->CurrState]();
//UPDATE: the former version of this code sort of unconditionally usleep'd for a static amount
//of time (depending on 30 or 60fps). It's been updated to be dynamic, in case of lag/poor pc
//perf, or if PINE overhead is particularly large. If at any point in the future duckstation
//isn't at a locked 30/60fps, this may be the culprit.
// check for frame lag
if (octr.get()->gpuSubmitTooLate == 1)
{
octr.get()->gpuSubmitTooLate = 0;
// if 1-9 frame stalls
if (sleepCount >= 500)
{
// remove from sleep
sleepCount -= 500;
}
// if 10+ frame stalls
else
{
sleepCount = 0;
enableDeferredGPU = 0;
}
}
// PC writes to PSX,
// PSX is read-only
octr.get()->enableDeferredGPU = enableDeferredGPU;
// delay GPU between SEND and RECV
if (enableDeferredGPU == 1)
usleep(sleepCount);
// now check for new RECV message
ProcessNewMessages();
// allow PSX to resume
octr.get()->sleepControl = 0;
octr.startWrite(); //only write the things that have changed.
GCDeadPineData(); //this is probably a decent place to do this.
// Wait for PSX to have P1 data,
// which is set at octr->sleepControl
void FrameStall(); FrameStall();
}
printf("\n");
@ -1370,17 +1322,14 @@ void usleep(__int64 usec)
}
#endif
#pragma optimize("", off)
int gGT_timer = 0;
void FrameStall()
{
// wait for next frame
//TODO: make this a submember of octr
ps1ptr<int> OCTRsleepControl = pBuf.at<int>(octr.get_address() + offsetof(OnlineCTR, sleepControl));
while ((*OCTRsleepControl.get()) == 0)
ps1ptr<int> OCTRsleepControl = pBuf.at<int>(0x80096b20 + 0x1cf8);
while (gGT_timer == (*OCTRsleepControl.get()))
{
usleep(1);
OCTRsleepControl.blockingRead();
}
(*octr.get()).sleepControl = (*OCTRsleepControl.get());
}
#pragma optimize("", on)
}

View File

@ -9,7 +9,7 @@ const std::string g_duckExecutable = g_duckFolder + "duckstation-qt-x64-ReleaseL
const std::string g_clientString = "client.zip";
const std::string g_clientExecutable = "Client.exe";
const std::string g_patchString = "ctr-u_Online30.xdelta";
const std::string g_configString = "settings.ini";
const std::string g_configString = "SCUS-94426.ini";
const std::string GetClientPath(const std::string& version)
{
@ -29,7 +29,7 @@ const std::string GetIniPath_Version(const std::string& version)
const std::string GetIniPath_Duck()
{
return g_duckFolder + g_configString;
return g_duckFolder + "settings.ini";
}
DataManager g_dataManager;

View File

@ -2,7 +2,6 @@
#include "dataManager.h"
#include "IconsFontAwesome6.h"
#include <imgui.h>
#include <misc/cpp/imgui_stdlib.h>
#include <portable-file-dialogs.h>
#include <filesystem>
@ -17,6 +16,14 @@ UI::UI()
m_updater.CheckForUpdates(m_status, m_version);
}
static int FilterUsernameChar(ImGuiInputTextCallbackData* data)
{
if (data->EventChar >= 'a' && data->EventChar <= 'z') { return 0; }
if (data->EventChar >= 'A' && data->EventChar <= 'Z') { return 0; }
if (data->EventChar >= '0' && data->EventChar <= '9') { return 0; }
return 1;
}
void UI::Render(int width, int height)
{
ImGui::SetNextWindowPos(ImVec2(.0f, .0f), ImGuiCond_Always);
@ -24,12 +31,21 @@ void UI::Render(int width, int height)
ImGui::Begin("Main", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
std::string icon = m_username.empty() ? ICON_FA_CIRCLE_XMARK : ICON_FA_CIRCLE_CHECK;
ImGui::InputText(("Username " + icon).c_str(), &m_username);
ImGui::SetItemTooltip("Special characters:\n* = Cross Button\n< = Left Arrow\n@ = Circle\n[ = Square\n^ = Triangle\n& = Space");
ImGui::InputText(("Username " + icon).c_str(), &m_username, ImGuiInputTextFlags_CallbackCharFilter, FilterUsernameChar);
if (m_username.size() > 9) { m_username = m_username.substr(0, 9); }
static bool readBios = true;
bool updateReady = true;
updateReady &= SelectFile(m_biosPath, "Bios Path ", {".bin"}, {"PSX Bios File", "*.bin"}, "Path to a PS1 NTSC-U bios.");
if (updateReady)
{
if (readBios)
{
if (m_updater.IsValidBios(m_biosPath)) { readBios = false; }
else { updateReady = false; }
}
}
else { readBios = true; }
updateReady &= SelectFile(m_gamePath, "Game Path", {".bin", ".img", ".iso"}, {"Game Files", "*.bin *.img *.iso"}, "Path to the clean NTSC-U version of CTR");
ImGui::Text(("Version: " + m_version).c_str());
@ -63,12 +79,24 @@ void UI::Render(int width, int height)
bool UI::SelectFile(std::string& str, const std::string& label, const std::vector<std::string>& ext, const std::vector<std::string>& filters, const std::string& tip)
{
bool validPath = false;
for (const std::string& s : ext)
std::string lowercaseStr;
for (char c : str)
{
if (str.ends_with(s) && std::filesystem::exists(str)) { validPath = true; break; }
if (c <= 'Z' && c >= 'A') { c = c - ('Z' - 'z'); };
lowercaseStr += c;
}
std::string icon = validPath ? ICON_FA_CIRCLE_CHECK : ICON_FA_CIRCLE_XMARK;
auto checkValidPath = [&]
{
if (std::filesystem::exists(str))
{
for (const std::string& s : ext)
{
if (lowercaseStr.ends_with(s)) { return true; }
}
}
};
std::string icon = checkValidPath() ? ICON_FA_CIRCLE_CHECK : ICON_FA_CIRCLE_XMARK;
ImGui::InputText((label + " " + icon).c_str(), &str);
if (!tip.empty()) { ImGui::SetItemTooltip(tip.c_str()); }
ImGui::SameLine();
@ -78,7 +106,7 @@ bool UI::SelectFile(std::string& str, const std::string& label, const std::vecto
if (selection.empty()) { return false; }
str = selection.front();
}
return validPath;
return checkValidPath();
}
bool UI::SelectFolder(std::string& str, const std::string& label, const std::string& tip)

View File

@ -1,8 +1,10 @@
#pragma once
#include "updater.h"
#include <imgui.h>
#include <string>
#include <vector>
#include "updater.h"
class UI
{

View File

@ -23,6 +23,13 @@ bool Updater::IsBusy()
return m_routineRunning;
}
bool Updater::IsValidBios(const std::string& path)
{
std::vector<char> v;
IO::ReadBinaryFile(v, path);
return v.size() == static_cast<size_t>(0x100000);
}
bool Updater::CheckForUpdates(std::string& status, const std::string& currVersion)
{
return StartRoutine([&]
@ -44,6 +51,7 @@ bool Updater::Update(std::string& status, std::string& currVersion, const std::s
return StartRoutine([&]
{
std::string version;
bool copyIni = false;
if (!m_hasDuckstation)
{
status = "Downloading Duckstation...";
@ -77,6 +85,7 @@ bool Updater::Update(std::string& status, std::string& currVersion, const std::s
std::ofstream portableFile(duckPortable.c_str());
portableFile.close();
m_hasDuckstation = true;
copyIni = true;
}
status = "Checking for new updates...";
if (m_updateAvailable || Requests::CheckUpdates(version))
@ -87,7 +96,7 @@ bool Updater::Update(std::string& status, std::string& currVersion, const std::s
std::string path = g_dataFolder + m_versionAvailable + "/";
if (Requests::DownloadUpdates(path, status) && Patch::NewVersion(path, gamePath, status))
{
std::filesystem::copy_file(GetIniPath_Version(currVersion), GetIniPath_Duck());
if (copyIni) { std::filesystem::copy_file(GetIniPath_Version(m_versionAvailable), GetIniPath_Duck()); }
m_updated = true;
m_updateAvailable = false;
currVersion = m_versionAvailable;

View File

@ -9,6 +9,7 @@ public:
Updater();
bool IsUpdated();
bool IsBusy();
bool IsValidBios(const std::string& path);
bool CheckForUpdates(std::string& status, const std::string& currVersion);
bool Update(std::string& status, std::string& currVersion, const std::string& gamePath, const std::string& biosPath);