2V2-e.1: 3D draw-command channel — recording D3D8 device, StateManager, GrpBase, camera

EterLib/StateManager.cpp and GrpBase.cpp ported verbatim. CGraphicDevice::Create builds a platform
IDirect3DDevice8 that keeps the device state and records every Draw* call as a Render3DDraw
(vertices decoded by FVF, strips/fans expanded, textures, world/view/proj, blend/depth/light state).
The 40250 camera (__UpdateCamera, SetCenterPosition, ...) and the Process order
(__UpdateCamera -> OnCameraUpdate -> OnUIUpdate -> Begin/SetInterfaceRenderState/OnUIRender/End)
are in place; CScreen Begin/End, CPythonGraphic render states and CCullingManager::Process matrix
updates are verbatim. port.login_flow asserts a textured, lit character draw under the RH
perspective with every vertex on screen; offline and live pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-23 20:15:54 +09:00
co-authored by Claude Opus 5.5
parent 668f48d6ec
commit 5bfa13c5cc
27 changed files with 3616 additions and 777 deletions
@@ -3,6 +3,9 @@
// that ports the unit into port/ (docs/PORT-PLAN.md 2V1).
#include "UserInterface/StdAfx.h"
#include "UserInterface/PythonPlayer.h"
#include "UserInterface/PythonApplication.h"
#include "UserInterface/PythonCharacterManager.h"
#include "UserInterface/InstanceBase.h"
#include "../../PlatformStub.h"
@@ -20,6 +23,9 @@ auto CPythonPlayer::SPlayerStatus::GetPoint(UINT) -> long
CPythonPlayer::CPythonPlayer()
{
MT_PLATFORM_STUB();
// PORT: the one member the stand-in's ported functions read; 40250's constructor reaches it
// through Clear() (PythonPlayer.cpp:1624).
m_dwMainCharacterIndex = 0;
}
CPythonPlayer::~CPythonPlayer()
@@ -63,9 +69,21 @@ auto CPythonPlayer::SetAttackKeyState(bool) -> void
MT_PLATFORM_STUB();
}
auto CPythonPlayer::NEW_GetMainActorPosition(TPixelPosition *) -> void
// 40250 PythonPlayer.cpp:87, verbatim: UpdateGame centres the camera on the main actor.
void CPythonPlayer::NEW_GetMainActorPosition(TPixelPosition* pkPPosActor)
{
MT_PLATFORM_STUB();
TPixelPosition kPPosMainActor;
IAbstractPlayer& rkPlayer=IAbstractPlayer::GetSingleton();
CInstanceBase * pInstance = rkPlayer.NEW_GetMainActorPtr();
if (pInstance)
{
pInstance->NEW_GetPixelPosition(pkPPosActor);
}
else
{
CPythonApplication::Instance().GetCenterPosition(pkPPosActor);
}
}
auto CPythonPlayer::RegisterEffect(DWORD, const char *, bool) -> bool
@@ -194,16 +212,17 @@ auto CPythonPlayer::AlarmHaveToGo() -> void
MT_PLATFORM_STUB();
}
auto CPythonPlayer::NEW_FindActorPtr(DWORD) -> CInstanceBase *
// 40250 PythonPlayer.cpp:127
CInstanceBase* CPythonPlayer::NEW_FindActorPtr(DWORD dwVID)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<CInstanceBase *>();
CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
return rkChrMgr.GetInstancePtr(dwVID);
}
auto CPythonPlayer::NEW_GetMainActorPtr() -> CInstanceBase *
// 40250 PythonPlayer.cpp
CInstanceBase* CPythonPlayer::NEW_GetMainActorPtr()
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<CInstanceBase *>();
return NEW_FindActorPtr(m_dwMainCharacterIndex);
}
auto CPythonPlayer::Clear() -> void
@@ -237,15 +256,18 @@ auto CPythonPlayer::SetPlayTime(DWORD) -> void
MT_PLATFORM_STUB();
}
auto CPythonPlayer::SetMainCharacterIndex(int) -> void
// 40250 PythonPlayer.cpp:276
// PORT: the main instance's SetEventHandler(CPythonPlayerEventHandler) is left out; the player event
// handler (PythonPlayerEventHandler.cpp) is not ported.
void CPythonPlayer::SetMainCharacterIndex(int iIndex)
{
MT_PLATFORM_STUB();
m_dwMainCharacterIndex = iIndex;
}
auto CPythonPlayer::GetMainCharacterIndex() -> DWORD
// 40250 PythonPlayer.cpp:288
DWORD CPythonPlayer::GetMainCharacterIndex()
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<DWORD>();
return m_dwMainCharacterIndex;
}
auto CPythonPlayer::IsMainCharacterIndex(DWORD) -> bool