feat: initial controller tooltips hotswap

This commit is contained in:
2026-08-10 04:14:40 -04:00
parent b737c3eccb
commit 23d4db901a
3 changed files with 210 additions and 3 deletions
Binary file not shown.
+169 -3
View File
@@ -47,9 +47,19 @@
#endif
#ifdef _WINDOWS64
wstring controlTooltipsPath = L"";
wstring skinName = L"";
#endif
CRITICAL_SECTION UIController::ms_reloadSkinCS;
bool UIController::ms_bReloadSkinCSInitialised = false;
#ifdef _WINDOWS64
CRITICAL_SECTION UIController::ms_controllerPollCS;
bool UIController::ms_bControllerPollCSInitialised = false;
#endif
DWORD UIController::m_dwTrialTimerLimitSecs=DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME;
static void RADLINK WarningCallback(void *user_callback_data, Iggy *player, IggyResult code, const char *message)
@@ -233,6 +243,12 @@ UIController::UIController()
InitializeCriticalSection(&ms_reloadSkinCS);
ms_bReloadSkinCSInitialised = true;
}
if(!ms_bControllerPollCSInitialised)
{
InitializeCriticalSection(&ms_controllerPollCS);
ms_bControllerPollCSInitialised = true;
}
}
void UIController::SetSysUIShowing(bool bVal)
@@ -282,6 +298,14 @@ void UIController::postInit()
//
loadSkins();
#ifdef _WINDOWS64
m_LastControllerType = UNKNOWN;
m_bControllerTypeChanged = false;
m_controllerPollThread = new C4JThread(controllerPollThreadProc, (void*)this, "Controller poll thread");
m_controllerPollThread->Run();
#endif
for(unsigned int i = 0; i < eUIGroup_COUNT; ++i)
{
m_groups[i] = new UIGroup((EUIGroup)i,i-1);
@@ -489,8 +513,112 @@ void UIController::tick()
++it;
}
}
#ifdef _WINDOWS64
fetchControlTooltipSWF();
#endif
}
#ifdef _WINDOWS64
int UIController::controllerPollThreadProc(void* lpParam)
{
UIController *controller = (UIController *)lpParam;
while(true)
{
EControllerType polled = controller->GetControllerType(InputManager.PollControllerType(0));
EnterCriticalSection(&ms_controllerPollCS);
if(polled != EControllerType::UNKNOWN && polled != controller->m_LastControllerType)
{
controller->m_bControllerTypeChanged = true;
wstring path = controller->GetControlTooltipsPath(polled);
controller->getMovieData(path);
}
LeaveCriticalSection(&ms_controllerPollCS);
Sleep(250);
}
return 0;
}
wstring UIController::GetControlTooltipsPath(EControllerType ControllerType)
{
if(ControllerType == EControllerType::UNSET)
{
EControllerType ControllerType = GetControllerType(InputManager.PollControllerType(0));
}
switch(ControllerType)
{
case EControllerType::PS3:
return m_fScreenHeight >= 1080.0f
? L"ControlTooltips\\HD\\PS3HDControls.swf"
: L"ControlTooltips\\PS3Controls.swf";
case EControllerType::PS4:
return m_fScreenHeight >= 1080.0f
? L"ControlTooltips\\HD\\OrbisHDControls.swf"
: L"ControlTooltips\\OrbisControls.swf";
case EControllerType::XBOXONE:
return m_fScreenHeight >= 1080.0f
? L"ControlTooltips\\HD\\DurangoHDControls.swf"
: L"ControlTooltips\\DurangoControls.swf";
case EControllerType::XBOX360:
return m_fScreenHeight >= 1080.0f
? L"ControlTooltips\\HD\\XboxHDControls.swf"
: L"ControlTooltips\\XboxControls.swf";
default:
return m_fScreenHeight >= 1080.0f
? L"ControlTooltips\\HD\\Windows64HDControls.swf"
: L"ControlTooltips\\Windows64Controls.swf";
}
}
UIController::EControllerType UIController::GetControllerType(const char* controllerType)
{
if (strcmp(controllerType, "PS3") == 0) return EControllerType::PS3;
if (strcmp(controllerType, "PS4") == 0) return EControllerType::PS4;
if (strcmp(controllerType, "PS5") == 0) return EControllerType::PS5;
if (strcmp(controllerType, "XBOXONE") == 0) return EControllerType::XBOXONE;
if (strcmp(controllerType, "XBOX360") == 0) return EControllerType::XBOX360;
if (strcmp(controllerType, "SWITCH") == 0) return EControllerType::SWITCH;
if (strcmp(controllerType, "GAMECUBE") == 0) return EControllerType::GAMECUBE;
if (strcmp(controllerType, "STANDARD") == 0) return EControllerType::STANDARD;
return EControllerType::UNKNOWN;
}
void UIController::fetchControlTooltipSWF()
{
if (!m_bControllerTypeChanged)
return;
if (IsReloadingSkin())
return;
EControllerType ControllerType = GetControllerType(InputManager.PollControllerType(0));
if (ControllerType == EControllerType::UNKNOWN)
return; // str1k3r - ignore UNKNOWN, keep last tooltip
if (ControllerType == m_LastControllerType)
{
m_bControllerTypeChanged = false;
return; // str1k3r - nothing changed, skip reload
}
m_LastControllerType = ControllerType;
m_bControllerTypeChanged = false;
controlTooltipsPath = GetControlTooltipsPath(ControllerType);
skinName = (m_fScreenHeight >= 1080.0f) ? L"skinControlTooltipsHD.swf" : L"skinControlTooltips.swf";
reloadSingleSkin(eLibrary_ControlTooltips, controlTooltipsPath, skinName);
}
#endif
void UIController::loadSkins()
{
wstring platformSkinPath = L"";
@@ -503,10 +631,12 @@ void UIController::loadSkins()
if(m_fScreenHeight >= 1080.0f)
{
platformSkinPath = L"skinHDWin.swf";
controlTooltipsPath = GetControlTooltipsPath();
}
else
{
platformSkinPath = L"skinWin.swf";
platformSkinPath = L"skinWin.swf";
controlTooltipsPath = GetControlTooltipsPath();
}
#elif defined _DURANGO
if(m_fScreenHeight==1080.0f)
@@ -539,6 +669,9 @@ void UIController::loadSkins()
m_iggyLibraries[eLibrary_GraphicsInGame] = loadSkin(L"skinHDGraphicsInGame.swf", L"skinHDGraphicsInGame.swf");
m_iggyLibraries[eLibrary_GraphicsTooltips] = loadSkin(L"skinHDGraphicsTooltips.swf", L"skinHDGraphicsTooltips.swf");
m_iggyLibraries[eLibrary_GraphicsLabels] = loadSkin(L"skinHDGraphicsLabels.swf", L"skinHDGraphicsLabels.swf");
#ifdef _WINDOWS64
m_iggyLibraries[eLibrary_ControlTooltips] = loadSkin(controlTooltipsPath, L"skinControlTooltipsHD.swf");
#endif
m_iggyLibraries[eLibrary_Labels] = loadSkin(L"skinHDLabels.swf", L"skinHDLabels.swf");
m_iggyLibraries[eLibrary_InGame] = loadSkin(L"skinHDInGame.swf", L"skinHDInGame.swf");
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHDHud.swf", L"skinHDHud.swf");
@@ -553,6 +686,9 @@ void UIController::loadSkins()
m_iggyLibraries[eLibrary_GraphicsInGame] = loadSkin(L"skinGraphicsInGame.swf", L"skinGraphicsInGame.swf");
m_iggyLibraries[eLibrary_GraphicsTooltips] = loadSkin(L"skinGraphicsTooltips.swf", L"skinGraphicsTooltips.swf");
m_iggyLibraries[eLibrary_GraphicsLabels] = loadSkin(L"skinGraphicsLabels.swf", L"skinGraphicsLabels.swf");
#ifdef _WINDOWS64
m_iggyLibraries[eLibrary_ControlTooltips] = loadSkin(controlTooltipsPath, L"skinControlTooltips.swf");
#endif
m_iggyLibraries[eLibrary_Labels] = loadSkin(L"skinLabels.swf", L"skinLabels.swf");
m_iggyLibraries[eLibrary_InGame] = loadSkin(L"skinInGame.swf", L"skinInGame.swf");
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHud.swf", L"skinHud.swf");
@@ -567,10 +703,10 @@ IggyLibrary UIController::loadSkin(const wstring &skinPath, const wstring &skinN
// 4J Stu - We need to load the platformskin before the normal skin, as the normal skin requires some elements from the platform skin
if(!skinPath.empty() && app.hasArchiveFile(skinPath))
{
byteArray baFile = app.getArchiveFile(skinPath);
byteArray baFile = getMovieData(skinPath); // str1k3r - replaced app.getArchiveFile(skinPath); with this to try and prevent any stutters
lib = IggyLibraryCreateFromMemoryUTF16( (IggyUTF16 *)skinName.c_str() , (void *)baFile.data, baFile.length, NULL );
delete[] baFile.data;
//delete[] baFile.data;
#ifdef _DEBUG
IggyMemoryUseInfo memoryInfo;
rrbool res;
@@ -594,6 +730,36 @@ IggyLibrary UIController::loadSkin(const wstring &skinPath, const wstring &skinN
return lib;
}
void UIController::reloadSingleSkin(ELibraries lib, const wstring &skinPath, const wstring &skinName)
{
if(m_iggyLibraries[lib] != IGGY_INVALID_LIBRARY)
{
IggyLibraryDestroy(m_iggyLibraries[lib]);
m_iggyLibraries[lib] = IGGY_INVALID_LIBRARY;
}
m_iggyLibraries[lib] = loadSkin(skinPath, skinName);
if(skinName == L"skinControlTooltipsHD.swf" || skinName == L"skinControlTooltips.swf")
{
for(unsigned int i = 0; i < eUIGroup_COUNT; ++i)
{
if(m_groups[i]->getTooltips())
m_groups[i]->getTooltips()->destroyMovie();
if(m_groups[i]->getPressStartToPlay())
m_groups[i]->getPressStartToPlay()->destroyMovie();
}
for(unsigned int i = 0; i < eUIGroup_COUNT; ++i)
{
if(m_groups[i]->getTooltips())
m_groups[i]->getTooltips()->reloadMovie(true);
if(m_groups[i]->getPressStartToPlay())
m_groups[i]->getPressStartToPlay()->reloadMovie(true);
}
}
}
void UIController::ReloadSkin()
{
// Destroy all scene swf
+41
View File
@@ -21,6 +21,9 @@ public:
static CRITICAL_SECTION ms_reloadSkinCS;
static bool ms_bReloadSkinCSInitialised;
static CRITICAL_SECTION UIController::ms_controllerPollCS;
static bool UIController::ms_bControllerPollCSInitialised;
protected:
UIComponent_DebugUIConsole *m_uiDebugConsole;
UIComponent_DebugUIMarketingGuide *m_uiDebugMarketingGuide;
@@ -49,6 +52,35 @@ private:
eFont_Korean,
};
#ifdef _WINDOWS64
enum EControllerType
{
// SONY
PS3,
PS4,
PS5,
// MICROSOFT
XBOXONE,
XBOX360,
// NINTENDO
SWITCH,
GAMECUBE,
// MISC
STANDARD,
UNKNOWN,
UNSET
};
EControllerType m_LastControllerType;
C4JThread *m_controllerPollThread;
volatile bool m_bControllerTypeChanged;
static int controllerPollThreadProc(void *lpParam);
#endif
// 4J-JEV: It's important that currentFont == targetFont, unless updateCurrentLanguage is going to be called.
EFont m_eCurrentFont, m_eTargetFont;
@@ -91,6 +123,9 @@ private:
eLibrary_GraphicsInGame,
eLibrary_GraphicsTooltips,
eLibrary_GraphicsLabels,
#ifdef _WINDOWS64
eLibrary_ControlTooltips,
#endif
eLibrary_Labels,
eLibrary_InGame,
eLibrary_HUD,
@@ -199,12 +234,18 @@ public:
public:
// TICKING
virtual void tick();
#ifdef _WINDOWS64
wstring GetControlTooltipsPath(EControllerType ControllerType = EControllerType::UNSET);
EControllerType GetControllerType(const char* controllerType);
void fetchControlTooltipSWF();
#endif
private:
void loadSkins();
IggyLibrary loadSkin(const wstring &skinPath, const wstring &skinName);
public:
void reloadSingleSkin(ELibraries lib, const wstring &skinPath, const wstring &skinName);
void ReloadSkin();
virtual void StartReloadSkinThread();
virtual bool IsReloadingSkin();