mirror of
https://github.com/CTR-tools/CTR-ModSDK.git
synced 2024-11-30 08:50:33 +00:00
Fix bugs reported in the launcher beta testing
This commit is contained in:
parent
6a76670186
commit
8541ce81e9
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "updater.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "updater.h"
|
||||
|
||||
class UI
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user