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/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": "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": [],
|
||||
"functions": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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": {
|
||||
"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"
|
||||
},
|
||||
"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": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "Win32 named mutex; no caller in 40250."
|
||||
},
|
||||
"DestroyMetin2GameMutex": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "Win32 named mutex; no caller in 40250."
|
||||
},
|
||||
"__ErrorPythonLibraryIsNotExist": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "message box for CheckPythonLibraryFilenames (N_A); PythonBoot::Start returns the InstallStdLib error instead."
|
||||
},
|
||||
"__IsTimeStampOption": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "WinMain launcher option (/timestamp -> build-stamp message box); the host has no Win32 command line."
|
||||
},
|
||||
"__PrintTimeStamp": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "WinMain /timestamp message box with _MSC_VER build stamp; no gameplay semantics."
|
||||
},
|
||||
"__IsLocaleOption": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "WinMain --locale writes locale.txt and quits (launcher diagnostics); the host has no Win32 command line."
|
||||
},
|
||||
"__IsLocaleVersion": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "WinMain --perforce-revision writes <exe>.version and quits (patcher diagnostics)."
|
||||
},
|
||||
"__IsOpenIDAuthKeyOption": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "USE_OPENID is not defined in the 40250 build; compiled out."
|
||||
},
|
||||
"__IsOpenIDTestOption": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "USE_OPENID is not defined in the 40250 build; compiled out."
|
||||
},
|
||||
"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": {
|
||||
"status": "TODO"
|
||||
"status": "N_A",
|
||||
"note": "never installed: 40250 Setup sets the Granny log callback Function to nullptr."
|
||||
},
|
||||
"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 "EterBase/Timer.h"
|
||||
#include "PythonBoot.h"
|
||||
#include "../UserInterface/UserInterface.h"
|
||||
#include "PythonHost.h"
|
||||
#include "../EterLib/UIRenderCommands.h"
|
||||
#include "../EterBase/LogBox.h"
|
||||
@@ -714,6 +715,8 @@ bool Start(const char* stdlib_path, std::string* error)
|
||||
});
|
||||
#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(...).
|
||||
std::string locale_config = "locale.cfg";
|
||||
if (const char* client = std::getenv("MT_40250_CLIENT"))
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "MilesLib/SoundData.h"
|
||||
#include "UserInterface.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
@@ -26,6 +27,15 @@
|
||||
// 40250 UserInterface.cpp:49.
|
||||
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
|
||||
// client resolves is UserInterface.rc's LANG_ENGLISH, SUBLANG_ENGLISH_US section (ids from resource.h).
|
||||
namespace
|
||||
@@ -45,12 +55,22 @@ const char* LoadAppString(DWORD dwID)
|
||||
return "";
|
||||
}
|
||||
|
||||
std::map<DWORD, std::string> gs_kMap_dwID_stLocale;
|
||||
} // 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)
|
||||
{
|
||||
std::string& rstLocale=gs_kMap_dwID_stLocale[dwID];
|
||||
std::string& rstLocale=gs_kAppStrTable.m_kMap_dwID_stLocale[dwID];
|
||||
rstLocale=LoadAppString(dwID);
|
||||
|
||||
return rstLocale;
|
||||
|
||||
@@ -10,3 +10,10 @@ bool PackInitialize(const char * c_pszFolder);
|
||||
// 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.
|
||||
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, LPCSTR szKey);
|
||||
|
||||
extern void ApplicationSetErrorString(const char* szErrorString);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "ScriptLib/StdAfx.h"
|
||||
#include "../../src/platform/ScriptLib/PythonBoot.h"
|
||||
#include "../../src/platform/ScriptLib/PythonHost.h"
|
||||
#include "UserInterface/StdAfx.h" // ApplicationSetErrorString, ApplicationStringTable_GetStringz
|
||||
#include "../../src/platform/UserInterface/UserInterface.h"
|
||||
#include "../../src/platform/EterLib/UIRenderCommands.h"
|
||||
#include "../../src/platform/EterLib/RenderCommands3D.h"
|
||||
@@ -327,6 +328,13 @@ int main(int argc, char** argv)
|
||||
GraphicBaseAccess::DetectorString(&modes);
|
||||
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;
|
||||
CHECK(!screen.IsLostDevice() && screen.RestoreDevice());
|
||||
|
||||
Reference in New Issue
Block a user