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
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,235 @@
#include "StdAfx.h"
#include "PythonTextTail.h"
#include "PythonCharacterManager.h"
PyObject * textTailClear(PyObject * poSelf, PyObject * poArgs)
{
CPythonTextTail::Instance().Clear();
return Py_BuildNone();
}
PyObject * textTailUpdateAllTextTail(PyObject * poSelf, PyObject * poArgs)
{
CPythonTextTail::Instance().UpdateAllTextTail();
return Py_BuildNone();
}
PyObject * textTailUpdateShowingTextTail(PyObject * poSelf, PyObject * poArgs)
{
CPythonTextTail::Instance().UpdateShowingTextTail();
return Py_BuildNone();
}
PyObject * textTailRender(PyObject * poSelf, PyObject * poArgs)
{
CPythonTextTail::Instance().Render();
return Py_BuildNone();
}
PyObject * textTailRegisterCharacterTextTail(PyObject * poSelf, PyObject * poArgs)
{
int iGuildID;
if (!PyTuple_GetInteger(poArgs, 0, &iGuildID))
return Py_BuildException();
int iVirtualID;
if (!PyTuple_GetInteger(poArgs, 1, &iVirtualID))
return Py_BuildException();
CPythonTextTail::Instance().RegisterCharacterTextTail(iGuildID, iVirtualID, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
return Py_BuildNone();
}
PyObject * textTailGetPosition(PyObject * poSelf, PyObject * poArgs)
{
int VirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
return Py_BuildException();
float x=0.0f;
float y=0.0f;
float z=0.0f;
bool isData=CPythonTextTail::Instance().GetTextTailPosition(VirtualID, &x, &y, &z);
if (!isData)
{
CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance();
CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr();
if (pkInstMain)
{
const D3DXVECTOR3 & c_rv3Position = pkInstMain->GetGraphicThingInstanceRef().GetPosition();
CPythonGraphic::Instance().ProjectPosition(c_rv3Position.x, c_rv3Position.y, c_rv3Position.z, &x, &y);
}
}
return Py_BuildValue("fff", x, y, z);
}
PyObject * textTailIsChat(PyObject * poSelf, PyObject * poArgs)
{
int VirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
return Py_BuildException();
return Py_BuildValue("i", CPythonTextTail::Instance().IsChatTextTail(VirtualID));
}
PyObject * textTailRegisterChatTail(PyObject * poSelf, PyObject * poArgs)
{
int VirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
return Py_BuildException();
char * szText;
if (!PyTuple_GetString(poArgs, 1, &szText))
return Py_BuildException();
CPythonTextTail::Instance().RegisterChatTail(VirtualID, szText);
return Py_BuildNone();
}
PyObject * textTailRegisterInfoTail(PyObject * poSelf, PyObject * poArgs)
{
int VirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
return Py_BuildException();
char * szText;
if (!PyTuple_GetString(poArgs, 1, &szText))
return Py_BuildException();
CPythonTextTail::Instance().RegisterInfoTail(VirtualID, szText);
return Py_BuildNone();
}
PyObject * textTailAttachTitle(PyObject * poSelf, PyObject * poArgs)
{
int iVirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID))
return Py_BuildException();
char * szName;
if (!PyTuple_GetString(poArgs, 1, &szName))
return Py_BuildException();
float fr;
if (!PyTuple_GetFloat(poArgs, 2, &fr))
return Py_BuildException();
float fg;
if (!PyTuple_GetFloat(poArgs, 3, &fg))
return Py_BuildException();
float fb;
if (!PyTuple_GetFloat(poArgs, 4, &fb))
return Py_BuildException();
CPythonTextTail::Instance().AttachTitle(iVirtualID, szName, D3DXCOLOR(fr, fg, fb, 1.0f));
return Py_BuildNone();
}
PyObject * textTailShowCharacterTextTail(PyObject * poSelf, PyObject * poArgs)
{
int VirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
return Py_BuildException();
CPythonTextTail::Instance().ShowCharacterTextTail(VirtualID);
return Py_BuildNone();
}
PyObject * textTailShowItemTextTail(PyObject * poSelf, PyObject * poArgs)
{
int VirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
return Py_BuildException();
CPythonTextTail::Instance().ShowItemTextTail(VirtualID);
return Py_BuildNone();
}
PyObject * textTailArrangeTextTail(PyObject * poSelf, PyObject * poArgs)
{
CPythonTextTail::Instance().ArrangeTextTail();
return Py_BuildNone();
}
PyObject * textTailHideAllTextTail(PyObject * poSelf, PyObject * poArgs)
{
CPythonTextTail::Instance().HideAllTextTail();
return Py_BuildNone();
}
PyObject * textTailShowAllTextTail(PyObject * poSelf, PyObject * poArgs)
{
CPythonTextTail::Instance().ShowAllTextTail();
return Py_BuildNone();
}
PyObject * textTailPick(PyObject * poSelf, PyObject * poArgs)
{
int ix;
if (!PyTuple_GetInteger(poArgs, 0, &ix))
return Py_BuildException();
int iy;
if (!PyTuple_GetInteger(poArgs, 1, &iy))
return Py_BuildException();
int iValue = CPythonTextTail::Instance().Pick(ix, iy);
return Py_BuildValue("i", iValue);
}
PyObject * textTailSelectItemName(PyObject * poSelf, PyObject * poArgs)
{
int iVirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID))
return Py_BuildException();
CPythonTextTail::Instance().SelectItemName(iVirtualID);
return Py_BuildNone();
}
PyObject * textTailEnablePKTitle(PyObject * poSelf, PyObject * poArgs)
{
int iFlag;
if (!PyTuple_GetInteger(poArgs, 0, &iFlag))
return Py_BuildException();
CPythonTextTail::Instance().EnablePKTitle(iFlag);
return Py_BuildNone();
}
void initTextTail()
{
static PyMethodDef s_methods[] =
{
{ "Clear", textTailClear, METH_VARARGS },
{ "UpdateAllTextTail", textTailUpdateAllTextTail, METH_VARARGS },
{ "UpdateShowingTextTail", textTailUpdateShowingTextTail, METH_VARARGS },
{ "Render", textTailRender, METH_VARARGS },
{ "ShowCharacterTextTail", textTailShowCharacterTextTail, METH_VARARGS },
{ "ShowItemTextTail", textTailShowItemTextTail, METH_VARARGS },
{ "GetPosition", textTailGetPosition, METH_VARARGS },
{ "IsChat", textTailIsChat, METH_VARARGS },
{ "ArrangeTextTail", textTailArrangeTextTail, METH_VARARGS },
{ "HideAllTextTail", textTailHideAllTextTail, METH_VARARGS },
{ "ShowAllTextTail", textTailShowAllTextTail, METH_VARARGS },
{ "Pick", textTailPick, METH_VARARGS },
{ "SelectItemName", textTailSelectItemName, METH_VARARGS },
{ "EnablePKTitle", textTailEnablePKTitle, METH_VARARGS },
// For Test
{ "RegisterCharacterTextTail", textTailRegisterCharacterTextTail, METH_VARARGS },
{ "RegisterChatTail", textTailRegisterChatTail, METH_VARARGS },
{ "RegisterInfoTail", textTailRegisterInfoTail, METH_VARARGS },
{ "AttachTitle", textTailAttachTitle, METH_VARARGS },
{ NULL, NULL, NULL },
};
Py_InitModule("textTail", s_methods);
}
@@ -50,8 +50,15 @@ void initPlayer();
void initItem();
void initNonPlayer();
void initTrade();
void initTextTail();
void initChat();
void initnet();
void initeffect();
void initfly();
void initServerStateChecker();
extern const std::string& ApplicationStringTable_GetString(DWORD dwID);
extern const std::string& ApplicationStringTable_GetString(DWORD dwID, LPCSTR szKey);
extern const char* ApplicationStringTable_GetStringz(DWORD dwID);
extern const char* ApplicationStringTable_GetStringz(DWORD dwID, LPCSTR szKey);
+39
View File
@@ -101,6 +101,45 @@ D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, co
return pOut;
}
namespace
{
// World * View * Projection, skipping the null ones.
D3DXMATRIX world_view_projection(const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld)
{
D3DXMATRIX m;
D3DXMatrixIdentity(&m);
for (const D3DXMATRIX* p : {pWorld, pView, pProjection})
if (p)
D3DXMatrixMultiply(&m, &m, p);
return m;
}
} // namespace
D3DXVECTOR3* D3DXVec3Project(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DVIEWPORT8* pViewport,
const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld)
{
const D3DXMATRIX m = world_view_projection(pProjection, pView, pWorld);
D3DXVECTOR3 v;
D3DXVec3TransformCoord(&v, pV, &m);
pOut->x = pViewport->X + (1.0f + v.x) * pViewport->Width / 2.0f;
pOut->y = pViewport->Y + (1.0f - v.y) * pViewport->Height / 2.0f;
pOut->z = pViewport->MinZ + v.z * (pViewport->MaxZ - pViewport->MinZ);
return pOut;
}
D3DXVECTOR3* D3DXVec3Unproject(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DVIEWPORT8* pViewport,
const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld)
{
D3DXMATRIX m = world_view_projection(pProjection, pView, pWorld);
D3DXMatrixInverse(&m, nullptr, &m);
D3DXVECTOR3 v;
v.x = 2.0f * (pV->x - pViewport->X) / pViewport->Width - 1.0f;
v.y = 1.0f - 2.0f * (pV->y - pViewport->Y) / pViewport->Height;
v.z = (pV->z - pViewport->MinZ) / (pViewport->MaxZ - pViewport->MinZ);
D3DXVec3TransformCoord(pOut, &v, &m);
return pOut;
}
D3DXVECTOR3* D3DXVec3TransformNormal(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM)
{
D3DXVECTOR3 out;
+5
View File
@@ -337,6 +337,11 @@ D3DXVECTOR4* D3DXVec3Transform(D3DXVECTOR4* pOut, const D3DXVECTOR3* pV, const D
D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
D3DXVECTOR3* D3DXVec3TransformNormal(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
D3DXVECTOR4* D3DXVec4Transform(D3DXVECTOR4* pOut, const D3DXVECTOR4* pV, const D3DXMATRIX* pM);
// D3DX semantics: object space → viewport pixels (x, y) and depth in [MinZ, MaxZ], and back; a null matrix is identity.
D3DXVECTOR3* D3DXVec3Project(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DVIEWPORT8* pViewport,
const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld);
D3DXVECTOR3* D3DXVec3Unproject(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DVIEWPORT8* pViewport,
const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld);
// --- D3DXMATRIX ---
inline D3DXMATRIX* D3DXMatrixIdentity(D3DXMATRIX* pOut)