port: UserInterface.cpp entry unit — ApplicationSetErrorString/StringTable_Initialize verbatim, Main ADAPTED to PythonBoot, Win32 entry N_A
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
fd4d9a39df
commit
b497fce393
@@ -639,3 +639,4 @@
|
|||||||
{"date": "2026-09-30", "unit": "EterLib/GrpScreen.cpp", "action": "port", "evidence": "verbatim; 2d draws -> UIRender commands, Show without the web-page rects; D3D8 shim gains TestCooperativeLevel/Reset/Present/GetVertexShader + ID3DXMesh; port.app_loop (3D line/bar draws, device not lost), port.login_flow (picking/projection)"}
|
{"date": "2026-09-30", "unit": "EterLib/GrpScreen.cpp", "action": "port", "evidence": "verbatim; 2d draws -> UIRender commands, Show without the web-page rects; D3D8 shim gains TestCooperativeLevel/Reset/Present/GetVertexShader + ID3DXMesh; port.app_loop (3D line/bar draws, device not lost), port.login_flow (picking/projection)"}
|
||||||
{"date": "2026-09-30", "unit": "EterLib/GrpDevice.cpp", "action": "port", "evidence": "verbatim except Create (recording device in place of Direct3DCreate8/detector/CreateDevice, EL3D_ConfirmDevice on its caps); RecordingDevice decodes declaration-only vertex shaders to stream-0 FVFs; GrpScreen Show uses the GrpDevice browser globals; port.app_loop (PT/PNT/PNT2 FVFs, max texture 4096), full ctest, live-client screenshot matches"}
|
{"date": "2026-09-30", "unit": "EterLib/GrpDevice.cpp", "action": "port", "evidence": "verbatim except Create (recording device in place of Direct3DCreate8/detector/CreateDevice, EL3D_ConfirmDevice on its caps); RecordingDevice decodes declaration-only vertex shaders to stream-0 FVFs; GrpScreen Show uses the GrpDevice browser globals; port.app_loop (PT/PNT/PNT2 FVFs, max texture 4096), full ctest, live-client screenshot matches"}
|
||||||
{"date": "2026-09-30", "unit": "EterLib/GrpDetector.cpp", "action": "port", "evidence": "verbatim; IDirect3D8 shim completed (adapter count/caps/format checks/CreateDevice) and implemented once as the host adapter behind Direct3DCreate8 (RecordingDevice.cpp), which CPythonGraphic::GetD3D also returns; GrpDevice::Create now verbatim but for the D3DX debug meshes; port.app_loop (800x600x32 HWVP D16 mode, ms_lpd3d, GetString), full ctest, live-client screenshot matches"}
|
{"date": "2026-09-30", "unit": "EterLib/GrpDetector.cpp", "action": "port", "evidence": "verbatim; IDirect3D8 shim completed (adapter count/caps/format checks/CreateDevice) and implemented once as the host adapter behind Direct3DCreate8 (RecordingDevice.cpp), which CPythonGraphic::GetD3D also returns; GrpDevice::Create now verbatim but for the D3DX debug meshes; port.app_loop (800x600x32 HWVP D16 mode, ms_lpd3d, GetString), full ctest, live-client screenshot matches"}
|
||||||
|
{"date": "2026-09-30", "unit": "UserInterface/UserInterface.cpp", "action": "port", "evidence": "ApplicationSetErrorString/ApplicationStringTable_Initialize verbatim + port.app_loop; Main ADAPTED to PythonBoot; Win32 entry/launcher options N_A"}
|
||||||
|
|||||||
@@ -5,13 +5,28 @@
|
|||||||
"contracts": [],
|
"contracts": [],
|
||||||
"functions": {
|
"functions": {
|
||||||
"ApplicationSetErrorString": {
|
"ApplicationSetErrorString": {
|
||||||
"status": "TODO"
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"src/platform/UserInterface/UserInterface.cpp:ApplicationSetErrorString"
|
||||||
|
],
|
||||||
|
"test": [
|
||||||
|
"tests/port/port_app_loop_test.cpp (port.app_loop: ApplicationSetErrorString fills gs_szErrorString; ApplicationStringTable_GetStringz(IDS_APP_NAME))"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"CheckPythonLibraryFilenames": {
|
"CheckPythonLibraryFilenames": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "Win32 install check of lib\\\\*.pyc next to the exe. The embedded CPython 2.7 stdlib is installed by PythonHost::InstallStdLib, whose failure fails PythonBoot::Start."
|
||||||
},
|
},
|
||||||
"ApplicationStringTable_Initialize": {
|
"ApplicationStringTable_Initialize": {
|
||||||
"status": "TODO"
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"src/platform/UserInterface/UserInterface.cpp:ApplicationStringTable_Initialize",
|
||||||
|
"src/platform/ScriptLib/PythonBoot.cpp:PythonBoot::Start"
|
||||||
|
],
|
||||||
|
"test": [
|
||||||
|
"tests/port/port_app_loop_test.cpp (port.app_loop: ApplicationSetErrorString fills gs_szErrorString; ApplicationStringTable_GetStringz(IDS_APP_NAME))"
|
||||||
|
],
|
||||||
|
"note": "verbatim; PythonBoot::Start calls it before locale.cfg as WinMain does, with a NULL module handle (LoadString is the English STRINGTABLE switch)."
|
||||||
},
|
},
|
||||||
"ApplicationStringTable_GetString": {
|
"ApplicationStringTable_GetString": {
|
||||||
"status": "ADAPTED",
|
"status": "ADAPTED",
|
||||||
@@ -46,43 +61,65 @@
|
|||||||
"test": "project/python_host_test.gd (godot --headless --path project --script python_host_test.gd) and the same check through MT_TEST_MODE=python in project/client_main.gd -> system.py stops at ImportError: No module named app, the same point as ctest port.python_launcher"
|
"test": "project/python_host_test.gd (godot --headless --path project --script python_host_test.gd) and the same check through MT_TEST_MODE=python in project/client_main.gd -> system.py stops at ImportError: No module named app, the same point as ctest port.python_launcher"
|
||||||
},
|
},
|
||||||
"Main": {
|
"Main": {
|
||||||
"status": "TODO"
|
"status": "ADAPTED",
|
||||||
|
"impl": [
|
||||||
|
"src/platform/ScriptLib/PythonBoot.cpp:PythonBoot::Start",
|
||||||
|
"src/platform/ScriptLib/PythonBoot.cpp:PythonBoot::RunMainScript",
|
||||||
|
"src/platform/UserInterface/UserInterface.cpp:PackSingletons"
|
||||||
|
],
|
||||||
|
"note": "40250: Main seeds rand, opens the log, creates CLZO/CEterPackManager, PackInitialize(\"pack\"), locale, CPythonApplication, CPythonLauncher + exception sender, RunMainScript, then tears down. Port: the host owns the frame loop, so PythonBoot::Start does the setup (launcher, exception sender, singletons, CPythonApplication::Create pieces), PackSingletons/PackInitialize run from the host pack bootstrap, and RunMainScript runs system.py on a script fiber that parks in app.Loop(). Invariant: the same singletons exist and system.py runs with __COMMAND_LINE__ before the first frame.",
|
||||||
|
"test": [
|
||||||
|
"tests/port/port_app_loop_test.cpp (port.app_loop: Start + RunMainScript reach app.Loop)",
|
||||||
|
"tests/port/port_login_flow_test.cpp"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"CreateMetin2GameMutex": {
|
"CreateMetin2GameMutex": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "Win32 named mutex; no caller in 40250."
|
||||||
},
|
},
|
||||||
"DestroyMetin2GameMutex": {
|
"DestroyMetin2GameMutex": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "Win32 named mutex; no caller in 40250."
|
||||||
},
|
},
|
||||||
"__ErrorPythonLibraryIsNotExist": {
|
"__ErrorPythonLibraryIsNotExist": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "message box for CheckPythonLibraryFilenames (N_A); PythonBoot::Start returns the InstallStdLib error instead."
|
||||||
},
|
},
|
||||||
"__IsTimeStampOption": {
|
"__IsTimeStampOption": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "WinMain launcher option (/timestamp -> build-stamp message box); the host has no Win32 command line."
|
||||||
},
|
},
|
||||||
"__PrintTimeStamp": {
|
"__PrintTimeStamp": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "WinMain /timestamp message box with _MSC_VER build stamp; no gameplay semantics."
|
||||||
},
|
},
|
||||||
"__IsLocaleOption": {
|
"__IsLocaleOption": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "WinMain --locale writes locale.txt and quits (launcher diagnostics); the host has no Win32 command line."
|
||||||
},
|
},
|
||||||
"__IsLocaleVersion": {
|
"__IsLocaleVersion": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "WinMain --perforce-revision writes <exe>.version and quits (patcher diagnostics)."
|
||||||
},
|
},
|
||||||
"__IsOpenIDAuthKeyOption": {
|
"__IsOpenIDAuthKeyOption": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "USE_OPENID is not defined in the 40250 build; compiled out."
|
||||||
},
|
},
|
||||||
"__IsOpenIDTestOption": {
|
"__IsOpenIDTestOption": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "USE_OPENID is not defined in the 40250 build; compiled out."
|
||||||
},
|
},
|
||||||
"WinMain": {
|
"WinMain": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "Win32 entry: hackshield/XTrap/GameGuard/CheckLatestFiles/WebBrowser/COM and launcher options. The platform entry is the host (src/host, android) calling PythonBoot::Start (ApplicationStringTable_Initialize, locale.cfg + SetDefaultCodePage) then PythonBoot::RunMainScript."
|
||||||
},
|
},
|
||||||
"GrannyError": {
|
"GrannyError": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "never installed: 40250 Setup sets the Granny log callback Function to nullptr."
|
||||||
},
|
},
|
||||||
"Setup": {
|
"Setup": {
|
||||||
"status": "TODO"
|
"status": "N_A",
|
||||||
|
"note": "timeBeginPeriod (Win32 timer resolution) and a null Granny log callback, which is the GrannyRuntime default."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include "UserInterface/PythonApplication.h"
|
#include "UserInterface/PythonApplication.h"
|
||||||
#include "EterBase/Timer.h"
|
#include "EterBase/Timer.h"
|
||||||
#include "PythonBoot.h"
|
#include "PythonBoot.h"
|
||||||
|
#include "../UserInterface/UserInterface.h"
|
||||||
#include "PythonHost.h"
|
#include "PythonHost.h"
|
||||||
#include "../EterLib/UIRenderCommands.h"
|
#include "../EterLib/UIRenderCommands.h"
|
||||||
#include "../EterBase/LogBox.h"
|
#include "../EterBase/LogBox.h"
|
||||||
@@ -714,6 +715,8 @@ bool Start(const char* stdlib_path, std::string* error)
|
|||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// 40250 WinMain (UserInterface.cpp:524): ApplicationStringTable_Initialize(hInstance) before locale.cfg.
|
||||||
|
ApplicationStringTable_Initialize(NULL);
|
||||||
// 40250 Main (UserInterface.cpp:410): if (LocaleService_LoadGlobal(hInstance)) SetDefaultCodePage(...).
|
// 40250 Main (UserInterface.cpp:410): if (LocaleService_LoadGlobal(hInstance)) SetDefaultCodePage(...).
|
||||||
std::string locale_config = "locale.cfg";
|
std::string locale_config = "locale.cfg";
|
||||||
if (const char* client = std::getenv("MT_40250_CLIENT"))
|
if (const char* client = std::getenv("MT_40250_CLIENT"))
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "MilesLib/SoundData.h"
|
#include "MilesLib/SoundData.h"
|
||||||
#include "UserInterface.h"
|
#include "UserInterface.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -26,6 +27,15 @@
|
|||||||
// 40250 UserInterface.cpp:49.
|
// 40250 UserInterface.cpp:49.
|
||||||
bool __IS_TEST_SERVER_MODE__=false;
|
bool __IS_TEST_SERVER_MODE__=false;
|
||||||
|
|
||||||
|
// 40250 UserInterface.cpp:73. WinMain shows the text in a message box after Main returns; here it stays readable
|
||||||
|
// for the host.
|
||||||
|
char gs_szErrorString[512] = "";
|
||||||
|
|
||||||
|
void ApplicationSetErrorString(const char* szErrorString)
|
||||||
|
{
|
||||||
|
strcpy(gs_szErrorString, szErrorString);
|
||||||
|
}
|
||||||
|
|
||||||
// 40250 UserInterface.cpp:98. PORT: LoadString reads the executable's STRINGTABLE; the one the supplied English
|
// 40250 UserInterface.cpp:98. PORT: LoadString reads the executable's STRINGTABLE; the one the supplied English
|
||||||
// client resolves is UserInterface.rc's LANG_ENGLISH, SUBLANG_ENGLISH_US section (ids from resource.h).
|
// client resolves is UserInterface.rc's LANG_ENGLISH, SUBLANG_ENGLISH_US section (ids from resource.h).
|
||||||
namespace
|
namespace
|
||||||
@@ -45,12 +55,22 @@ const char* LoadAppString(DWORD dwID)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<DWORD, std::string> gs_kMap_dwID_stLocale;
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
struct ApplicationStringTable
|
||||||
|
{
|
||||||
|
HINSTANCE m_hInstance;
|
||||||
|
std::map<DWORD, std::string> m_kMap_dwID_stLocale;
|
||||||
|
} gs_kAppStrTable;
|
||||||
|
|
||||||
|
void ApplicationStringTable_Initialize(HINSTANCE hInstance)
|
||||||
|
{
|
||||||
|
gs_kAppStrTable.m_hInstance=hInstance;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string& ApplicationStringTable_GetString(DWORD dwID)
|
const std::string& ApplicationStringTable_GetString(DWORD dwID)
|
||||||
{
|
{
|
||||||
std::string& rstLocale=gs_kMap_dwID_stLocale[dwID];
|
std::string& rstLocale=gs_kAppStrTable.m_kMap_dwID_stLocale[dwID];
|
||||||
rstLocale=LoadAppString(dwID);
|
rstLocale=LoadAppString(dwID);
|
||||||
|
|
||||||
return rstLocale;
|
return rstLocale;
|
||||||
|
|||||||
@@ -10,3 +10,10 @@ bool PackInitialize(const char * c_pszFolder);
|
|||||||
// The two function-static singletons 40250 Main() creates before PackInitialize("pack")
|
// The two function-static singletons 40250 Main() creates before PackInitialize("pack")
|
||||||
// (`static CLZO lzo; static CEterPackManager EterPackManager;`), created on first use and alive until exit.
|
// (`static CLZO lzo; static CEterPackManager EterPackManager;`), created on first use and alive until exit.
|
||||||
void PackSingletons();
|
void PackSingletons();
|
||||||
|
|
||||||
|
// 40250: ApplicationStringTable_Initialize (WinMain, before LocaleService_LoadConfig). LoadString has no module
|
||||||
|
// here, so the handle is only stored.
|
||||||
|
void ApplicationStringTable_Initialize(HINSTANCE hInstance);
|
||||||
|
|
||||||
|
// gs_szErrorString (40250 UserInterface.cpp:73), set by ApplicationSetErrorString (UserInterface/StdAfx.h); WinMain shows it after Main.
|
||||||
|
extern char gs_szErrorString[512];
|
||||||
|
|||||||
@@ -76,3 +76,5 @@ extern const std::string& ApplicationStringTable_GetString(DWORD dwID, LPCSTR sz
|
|||||||
|
|
||||||
extern const char* ApplicationStringTable_GetStringz(DWORD dwID);
|
extern const char* ApplicationStringTable_GetStringz(DWORD dwID);
|
||||||
extern const char* ApplicationStringTable_GetStringz(DWORD dwID, LPCSTR szKey);
|
extern const char* ApplicationStringTable_GetStringz(DWORD dwID, LPCSTR szKey);
|
||||||
|
|
||||||
|
extern void ApplicationSetErrorString(const char* szErrorString);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "ScriptLib/StdAfx.h"
|
#include "ScriptLib/StdAfx.h"
|
||||||
#include "../../src/platform/ScriptLib/PythonBoot.h"
|
#include "../../src/platform/ScriptLib/PythonBoot.h"
|
||||||
#include "../../src/platform/ScriptLib/PythonHost.h"
|
#include "../../src/platform/ScriptLib/PythonHost.h"
|
||||||
|
#include "UserInterface/StdAfx.h" // ApplicationSetErrorString, ApplicationStringTable_GetStringz
|
||||||
#include "../../src/platform/UserInterface/UserInterface.h"
|
#include "../../src/platform/UserInterface/UserInterface.h"
|
||||||
#include "../../src/platform/EterLib/UIRenderCommands.h"
|
#include "../../src/platform/EterLib/UIRenderCommands.h"
|
||||||
#include "../../src/platform/EterLib/RenderCommands3D.h"
|
#include "../../src/platform/EterLib/RenderCommands3D.h"
|
||||||
@@ -327,6 +328,13 @@ int main(int argc, char** argv)
|
|||||||
GraphicBaseAccess::DetectorString(&modes);
|
GraphicBaseAccess::DetectorString(&modes);
|
||||||
CHECK(modes.find("800x600x32 HWVP") != std::string::npos);
|
CHECK(modes.find("800x600x32 HWVP") != std::string::npos);
|
||||||
}
|
}
|
||||||
|
// 40250 UserInterface.cpp: CheckLatestFiles hands WinMain its message through ApplicationSetErrorString;
|
||||||
|
// the string table keeps the (DWORD) text per id.
|
||||||
|
CHECK(gs_szErrorString[0] == '\0');
|
||||||
|
ApplicationSetErrorString("File 'a' is not latest version.");
|
||||||
|
CHECK(std::string(gs_szErrorString) == "File 'a' is not latest version.");
|
||||||
|
gs_szErrorString[0] = '\0';
|
||||||
|
CHECK(std::string(ApplicationStringTable_GetStringz(1)) == "Metin 2");
|
||||||
{
|
{
|
||||||
CScreen screen;
|
CScreen screen;
|
||||||
CHECK(!screen.IsLostDevice() && screen.RestoreDevice());
|
CHECK(!screen.IsLostDevice() && screen.RestoreDevice());
|
||||||
|
|||||||
Reference in New Issue
Block a user