port: P3-d PythonTextTail + textTail module (1:1 40250)

Copy PythonTextTail.cpp/PythonTextTailModule.cpp verbatim, drop the pending
stand-in and the textTail module stub, register initTextTail() after
initChat() and call CPythonTextTail::Initialize() in Create as 40250 does.
Implement CScreen::ProjectPosition/UnprojectPosition (were stubs) with
D3DXVec3Project/Unproject, and ApplicationStringTable_GetString(DWORD) over
UserInterface.rc's English string table. port.login_flow projects the ground
item's name tail in an ALT frame and picks it back by screen position.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-24 01:10:41 +09:00
co-authored by Claude Opus 5.5
parent 72b19b677d
commit 070a27b2cb
19 changed files with 1874 additions and 211 deletions
@@ -1,78 +1,88 @@
{
"reference": "UserInterface/UserInterface.cpp",
"reference_sha256": "beed987e4b1de627acafe7ea6f5fde989b8f4b33c8643fe2abb0f7152ea4a9eb",
"priority": "P4",
"contracts": [],
"functions": {
"ApplicationSetErrorString": {
"status": "TODO"
},
"CheckPythonLibraryFilenames": {
"status": "TODO"
},
"ApplicationStringTable_Initialize": {
"status": "TODO"
},
"ApplicationStringTable_GetString": {
"status": "TODO"
},
"ApplicationStringTable_GetStringz": {
"status": "TODO"
},
"PackInitialize": {
"impl": [
"extension/src/platform/UserInterface/UserInterface.cpp:PackInitialize"
],
"status": "ADAPTED",
"note": "platform PackInitialize: Index pack names resolved to the on-disk .eix spelling case-insensitively; no LogBoxf; CTextFileLoader::SetCacheMode / CSoundData::SetPackMode not called (units not ported, neither affects pack registration)",
"test": "extension/tests/port_eterpack_test.cpp (103 packs, 54891 entries, first-registered wins, 4 SECURITY rejects); extension/tests/proto_test.cpp (40250 locale/en item_proto/mob_proto through pack://)"
},
"RunMainScript": {
"impl": [
"extension/src/platform/ScriptLib/PythonBoot.cpp:PythonBoot::RunMainScript"
],
"status": "ADAPTED",
"note": "40250 runs it on Main()'s stack and takes the CPythonLauncher by reference; Godot owns this process, so PythonBoot::Start holds the launcher and RunMainScript takes only the command line plus a std::string* for the text 40250 shows in LogBox's message box. Of the 37 module initializers only initpack() is called — the rest are 2V slices, which is why system.py still stops at its first import. RegisterCommandLine passes the line through unchanged: the -cs/-ncs auto-login decoding needs EterBase/Utils.cpp SplitLine and EterLib/Util.cpp base64_decode, both still TODO (批次 2V1). '--pause-before-create-window' (system(\"pause\")) and the XTrap init check are dropped: no console and no XTrap on this platform.",
"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"
},
"CreateMetin2GameMutex": {
"status": "TODO"
},
"DestroyMetin2GameMutex": {
"status": "TODO"
},
"__ErrorPythonLibraryIsNotExist": {
"status": "TODO"
},
"__IsTimeStampOption": {
"status": "TODO"
},
"__PrintTimeStamp": {
"status": "TODO"
},
"__IsLocaleOption": {
"status": "TODO"
},
"__IsLocaleVersion": {
"status": "TODO"
},
"__IsOpenIDAuthKeyOption": {
"status": "TODO"
},
"__IsOpenIDTestOption": {
"status": "TODO"
},
"WinMain": {
"status": "TODO"
},
"GrannyError": {
"status": "TODO"
},
"Setup": {
"status": "TODO"
"reference": "UserInterface/UserInterface.cpp",
"reference_sha256": "beed987e4b1de627acafe7ea6f5fde989b8f4b33c8643fe2abb0f7152ea4a9eb",
"priority": "P4",
"contracts": [],
"functions": {
"ApplicationSetErrorString": {
"status": "TODO"
},
"CheckPythonLibraryFilenames": {
"status": "TODO"
},
"ApplicationStringTable_Initialize": {
"status": "TODO"
},
"ApplicationStringTable_GetString": {
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/UserInterface.cpp:ApplicationStringTable_GetString"
],
"note": "Only the (DWORD) overload: LoadString becomes a switch over UserInterface.rc's LANG_ENGLISH/SUBLANG_ENGLISH_US STRINGTABLE. The (DWORD, LPCSTR) metin2client.dat overload is declared but not defined (no caller ported yet).",
"test": "extension/tests/port_login_flow_test.cpp ground-item step (port.login_flow: ALT frame projects the item name tail, textTail Pick returns the ground item VID); PythonTextTail::SetItemTextTailOwner uses IDS_POSSESSIVE_MORPHENE"
},
"ApplicationStringTable_GetStringz": {
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/UserInterface.cpp:ApplicationStringTable_GetStringz"
],
"note": "Only the (DWORD) overload: LoadString becomes a switch over UserInterface.rc's LANG_ENGLISH/SUBLANG_ENGLISH_US STRINGTABLE. The (DWORD, LPCSTR) metin2client.dat overload is declared but not defined (no caller ported yet).",
"test": "extension/tests/port_login_flow_test.cpp ground-item step (port.login_flow: ALT frame projects the item name tail, textTail Pick returns the ground item VID); PythonTextTail::SetItemTextTailOwner uses IDS_POSSESSIVE_MORPHENE"
},
"PackInitialize": {
"impl": [
"extension/src/platform/UserInterface/UserInterface.cpp:PackInitialize"
],
"status": "ADAPTED",
"note": "platform PackInitialize: Index pack names resolved to the on-disk .eix spelling case-insensitively; no LogBoxf; CTextFileLoader::SetCacheMode / CSoundData::SetPackMode not called (units not ported, neither affects pack registration)",
"test": "extension/tests/port_eterpack_test.cpp (103 packs, 54891 entries, first-registered wins, 4 SECURITY rejects); extension/tests/proto_test.cpp (40250 locale/en item_proto/mob_proto through pack://)"
},
"RunMainScript": {
"impl": [
"extension/src/platform/ScriptLib/PythonBoot.cpp:PythonBoot::RunMainScript"
],
"status": "ADAPTED",
"note": "40250 runs it on Main()'s stack and takes the CPythonLauncher by reference; Godot owns this process, so PythonBoot::Start holds the launcher and RunMainScript takes only the command line plus a std::string* for the text 40250 shows in LogBox's message box. Of the 37 module initializers only initpack() is called — the rest are 2V slices, which is why system.py still stops at its first import. RegisterCommandLine passes the line through unchanged: the -cs/-ncs auto-login decoding needs EterBase/Utils.cpp SplitLine and EterLib/Util.cpp base64_decode, both still TODO (批次 2V1). '--pause-before-create-window' (system(\"pause\")) and the XTrap init check are dropped: no console and no XTrap on this platform.",
"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"
},
"CreateMetin2GameMutex": {
"status": "TODO"
},
"DestroyMetin2GameMutex": {
"status": "TODO"
},
"__ErrorPythonLibraryIsNotExist": {
"status": "TODO"
},
"__IsTimeStampOption": {
"status": "TODO"
},
"__PrintTimeStamp": {
"status": "TODO"
},
"__IsLocaleOption": {
"status": "TODO"
},
"__IsLocaleVersion": {
"status": "TODO"
},
"__IsOpenIDAuthKeyOption": {
"status": "TODO"
},
"__IsOpenIDTestOption": {
"status": "TODO"
},
"WinMain": {
"status": "TODO"
},
"GrannyError": {
"status": "TODO"
},
"Setup": {
"status": "TODO"
}
}
}
}