port 2V2-d.2: Granny runtime on libgr2, main character model animates

Implement the Granny SDK 2.11 API the client uses on top of libgr2
(platform/EterGrnLib/GrannyRuntime.cpp, shim granny.h declared from the
SDK header): file sections, type-definition vertex conversion, material
textures by Usage, mesh/bone bindings, deformer, control clock/loop/ease
and weighted SRT sampling. Port EterGrnLib (LODController, Material, Mesh,
Model, ModelInstance*, Motion, Thing, ThingInstance, Util) plus EterLib
GrpObjectInstance/GrpCollisionObject/CollisionData verbatim and drop their
platform skeletons and pending stand-ins; register the gr2 resource
factory; vertex/index buffers are CPU-side until the 2V2-e render adapter.

app.UpdateGame/RenderGame now run 40250's bodies, reaching the
CPythonApplication members through their singletons (the platform has no
app object); CPythonGraphic joins GameSingletons in member order, and
GetMousePosition reads the host cursor.

port.login_flow asserts the main instance's PART_MAIN model has meshes,
its diffuse image loaded and the WAIT motion moves the bones between
frames; offline and live pass, port_gate macos PASS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-23 19:43:27 +09:00
co-authored by Claude Opus 5.5
parent 5266b00c6e
commit 668f48d6ec
74 changed files with 11404 additions and 2356 deletions
+41
View File
@@ -302,6 +302,33 @@ typedef enum _D3DTEXTURESTAGESTATETYPE
D3DTSS_FORCE_DWORD = 0x7fffffff,
} D3DTEXTURESTAGESTATETYPE;
// D3D8 texture coordinate generation, transform flags and addressing (d3d8types.h).
enum : DWORD {
D3DTSS_TCI_PASSTHRU = 0x00000000,
D3DTSS_TCI_CAMERASPACENORMAL = 0x00010000,
D3DTSS_TCI_CAMERASPACEPOSITION = 0x00020000,
D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR = 0x00030000,
};
typedef enum _D3DTEXTURETRANSFORMFLAGS
{
D3DTTFF_DISABLE = 0,
D3DTTFF_COUNT1 = 1,
D3DTTFF_COUNT2 = 2,
D3DTTFF_COUNT3 = 3,
D3DTTFF_COUNT4 = 4,
D3DTTFF_PROJECTED = 256,
D3DTTFF_FORCE_DWORD = 0x7fffffff,
} D3DTEXTURETRANSFORMFLAGS;
typedef enum _D3DTEXTUREADDRESS
{
D3DTADDRESS_WRAP = 1,
D3DTADDRESS_MIRROR = 2,
D3DTADDRESS_CLAMP = 3,
D3DTADDRESS_BORDER = 4,
D3DTADDRESS_MIRRORONCE = 5,
D3DTADDRESS_FORCE_DWORD = 0x7fffffff,
} D3DTEXTUREADDRESS;
// D3D8 texture-stage arguments (d3d8types.h D3DTA_*).
enum : DWORD {
D3DTA_SELECTMASK = 0x0000000f,
@@ -386,6 +413,20 @@ typedef enum _D3DCULL {
#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1)
#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2)
#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3)
#define D3DUSAGE_RENDERTARGET 0x00000001L
#define D3DUSAGE_DEPTHSTENCIL 0x00000002L
#define D3DUSAGE_WRITEONLY 0x00000008L
#define D3DUSAGE_SOFTWAREPROCESSING 0x00000010L
#define D3DUSAGE_DONOTCLIP 0x00000020L
#define D3DUSAGE_POINTS 0x00000040L
#define D3DUSAGE_RTPATCHES 0x00000080L
#define D3DUSAGE_NPATCHES 0x00000100L
#define D3DUSAGE_DYNAMIC 0x00000200L
#define D3DLOCK_READONLY 0x00000010L
#define D3DLOCK_DISCARD 0x00002000L
#define D3DLOCK_NOOVERWRITE 0x00001000L
#define D3DLOCK_NOSYSLOCK 0x00000800L
#define D3DLOCK_NO_DIRTY_UPDATE 0x00008000L
#define D3DFVF_RESERVED0 0x001
#define D3DFVF_POSITION_MASK 0x00E
#define D3DFVF_XYZ 0x002
+11
View File
@@ -79,6 +79,17 @@ D3DXVECTOR4* D3DXVec3Transform(D3DXVECTOR4* pOut, const D3DXVECTOR3* pV, const D
return pOut;
}
D3DXVECTOR4* D3DXVec4Transform(D3DXVECTOR4* pOut, const D3DXVECTOR4* pV, const D3DXMATRIX* pM)
{
D3DXVECTOR4 out;
out.x = pM->m[0][0] * pV->x + pM->m[1][0] * pV->y + pM->m[2][0] * pV->z + pM->m[3][0] * pV->w;
out.y = pM->m[0][1] * pV->x + pM->m[1][1] * pV->y + pM->m[2][1] * pV->z + pM->m[3][1] * pV->w;
out.z = pM->m[0][2] * pV->x + pM->m[1][2] * pV->y + pM->m[2][2] * pV->z + pM->m[3][2] * pV->w;
out.w = pM->m[0][3] * pV->x + pM->m[1][3] * pV->y + pM->m[2][3] * pV->z + pM->m[3][3] * pV->w;
*pOut = out;
return pOut;
}
D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM)
{
const FLOAT norm = pM->m[0][3] * pV->x + pM->m[1][3] * pV->y + pM->m[2][3] * pV->z + pM->m[3][3];
+1
View File
@@ -335,6 +335,7 @@ D3DXVECTOR3* D3DXVec3Normalize(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV);
D3DXVECTOR4* D3DXVec3Transform(D3DXVECTOR4* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
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);
// --- D3DXMATRIX ---
inline D3DXMATRIX* D3DXMatrixIdentity(D3DXMATRIX* pOut)
+358 -4
View File
@@ -1,7 +1,8 @@
#pragma once
// Shim for RAD Granny 2.11 <granny.h> (40250 extern/include): the scalar types and structs that
// EterGrnLib headers name, with the SDK's layout; every other Granny object is opaque. Loading and
// skinning go through platform/ (backed by libgr2), never through these declarations.
// Shim for RAD Granny 2.11 <granny.h> (40250 extern/include): the scalar types, the public data structs
// EterGrnLib reads (SDK field names and order) and the functions it calls. The file-data structs are
// built from libgr2 and the runtime objects (file, model instance, control, pose, binding, deformer)
// stay opaque; both live in platform/EterGrnLib/GrannyRuntime.cpp.
#include <stdint.h>
typedef uint32_t granny_uint32;
@@ -11,10 +12,14 @@ typedef int16_t granny_int16;
typedef uint8_t granny_uint8;
typedef int8_t granny_int8;
typedef float granny_real32;
typedef double granny_real64x;
typedef granny_uint32 granny_bool32;
typedef granny_int32 granny_int32x;
typedef granny_uint32 granny_uint32x;
typedef uintptr_t granny_uintaddrx;
typedef granny_real32 granny_triple[3];
typedef granny_real32 granny_quad[4];
typedef granny_real32 granny_matrix_4x4[4][4];
typedef enum granny_member_type
{
@@ -46,6 +51,76 @@ typedef enum granny_member_type
Grannymember_type_forceint = 0x7fffffff
} granny_member_type;
typedef enum granny_material_texture_type
{
GrannyUnknownTextureType,
GrannyAmbientColorTexture,
GrannyDiffuseColorTexture,
GrannySpecularColorTexture,
GrannySelfIlluminationTexture,
GrannyOpacityTexture,
GrannyBumpHeightTexture,
GrannyReflectionTexture,
GrannyRefractionTexture,
GrannyDisplacementTexture,
GrannyOnePastLastMaterialTextureType,
Grannymaterial_texture_type_forceint = 0x7fffffff
} granny_material_texture_type;
typedef enum granny_deformation_type
{
GrannyDeformPosition = 1,
GrannyDeformPositionNormal,
GrannyDeformPositionNormalTangent,
GrannyDeformPositionNormalTangentBinormal,
Grannydeformation_type_forceint = 0x7fffffff
} granny_deformation_type;
typedef enum granny_deformer_tail_flags
{
GrannyDontAllowUncopiedTail,
GrannyAllowUncopiedTail,
GrannyAllowUninitializedDestTail,
Grannydeformer_tail_flags_forceint = 0x7fffffff
} granny_deformer_tail_flags;
typedef enum granny_standard_section_index
{
GrannyStandardMainSection = 0,
GrannyStandardRigidVertexSection = 1,
GrannyStandardRigidIndexSection = 2,
GrannyStandardDeformableVertexSection = 3,
GrannyStandardDeformableIndexSection = 4,
GrannyStandardTextureSection = 5,
GrannyStandardDiscardableSection = 6,
GrannyStandardUnloadedSection = 7,
GrannyStandardSectionCount = 8,
Grannystandard_section_index_forceint = 0x7fffffff
} granny_standard_section_index;
typedef enum granny_log_message_type
{
GrannyIgnoredLogMessage,
GrannyNoteLogMessage,
GrannyWarningLogMessage,
GrannyErrorLogMessage,
GrannyOnePastLastMessageType,
Grannylog_message_type_forceint = 0x7fffffff
} granny_log_message_type;
typedef granny_int32 granny_log_message_origin;
#define GrannyVertexPositionName "Position"
#define GrannyVertexNormalName "Normal"
#define GrannyVertexTangentName "Tangent"
#define GrannyVertexBinormalName "Binormal"
#define GrannyVertexTangentBinormalCrossName "TangentBinormalCross"
#define GrannyVertexBoneWeightsName "BoneWeights"
#define GrannyVertexBoneIndicesName "BoneIndices"
#define GrannyVertexDiffuseColorName "DiffuseColor"
#define GrannyVertexSpecularColorName "SpecularColor"
#define GrannyVertexTextureCoordinatesName "TextureCoordinates"
#define GrannyVertexMorphCurvePrefix "VertexMorphCurve"
struct granny_data_type_definition
{
granny_member_type Type;
@@ -57,9 +132,10 @@ struct granny_data_type_definition
};
struct granny_animation;
struct granny_bone;
struct granny_control;
struct granny_file;
struct granny_file_info;
struct granny_local_pose;
struct granny_material;
struct granny_mesh;
struct granny_mesh_binding;
@@ -67,4 +143,282 @@ struct granny_mesh_deformer;
struct granny_model;
struct granny_model_instance;
struct granny_skeleton;
struct granny_texture;
struct granny_world_pose;
struct granny_conversion_handler;
struct granny_variant
{
granny_data_type_definition* Type;
void* Object;
};
struct granny_transform
{
granny_uint32 Flags;
granny_triple Position;
granny_quad Orientation;
granny_triple ScaleShear[3];
};
struct granny_texture
{
char const* FromFileName;
granny_int32 TextureType;
granny_int32 Width;
granny_int32 Height;
granny_int32 Encoding;
granny_int32 SubFormat;
granny_variant ExtendedData;
};
struct granny_material_map
{
char const* Usage;
granny_material* Material;
};
struct granny_material
{
char const* Name;
granny_int32 MapCount;
granny_material_map* Maps;
granny_texture* Texture;
granny_variant ExtendedData;
};
struct granny_bone
{
char const* Name;
granny_int32 ParentIndex;
granny_transform LocalTransform;
granny_matrix_4x4 InverseWorld4x4;
granny_real32 LODError;
granny_variant ExtendedData;
};
struct granny_skeleton
{
char const* Name;
granny_int32 BoneCount;
granny_bone* Bones;
granny_int32 LODType;
granny_variant ExtendedData;
};
struct granny_vertex_data
{
granny_data_type_definition* VertexType;
granny_int32 VertexCount;
granny_uint8* Vertices;
granny_int32 VertexComponentNameCount;
char const** VertexComponentNames;
};
struct granny_tri_material_group
{
granny_int32 MaterialIndex;
granny_int32 TriFirst;
granny_int32 TriCount;
};
struct granny_tri_topology
{
granny_int32 GroupCount;
granny_tri_material_group* Groups;
granny_int32 IndexCount;
granny_int32* Indices;
granny_int32 Index16Count;
granny_uint16* Indices16;
};
struct granny_material_binding
{
granny_material* Material;
};
struct granny_bone_binding
{
char const* BoneName;
granny_triple OBBMin;
granny_triple OBBMax;
granny_int32 TriangleCount;
granny_int32* TriangleIndices;
};
struct granny_mesh
{
char const* Name;
granny_vertex_data* PrimaryVertexData;
granny_int32 MorphTargetCount;
void* MorphTargets;
granny_tri_topology* PrimaryTopology;
granny_int32 MaterialBindingCount;
granny_material_binding* MaterialBindings;
granny_int32 BoneBindingCount;
granny_bone_binding* BoneBindings;
granny_variant ExtendedData;
};
struct granny_model_mesh_binding
{
granny_mesh* Mesh;
};
struct granny_model
{
char const* Name;
granny_skeleton* Skeleton;
granny_transform InitialPlacement;
granny_int32 MeshBindingCount;
granny_model_mesh_binding* MeshBindings;
granny_variant ExtendedData;
};
struct granny_text_track_entry
{
granny_real32 TimeStamp;
char const* Text;
};
struct granny_text_track
{
char const* Name;
granny_int32 EntryCount;
granny_text_track_entry* Entries;
};
struct granny_track_group
{
char const* Name;
granny_int32 TextTrackCount;
granny_text_track* TextTracks;
granny_transform InitialPlacement;
granny_int32 Flags;
granny_variant ExtendedData;
};
struct granny_animation
{
char const* Name;
granny_real32 Duration;
granny_real32 TimeStep;
granny_real32 Oversampling;
granny_int32 TrackGroupCount;
granny_track_group** TrackGroups;
granny_int32 DefaultLoopCount;
granny_int32 Flags;
granny_variant ExtendedData;
};
struct granny_file_info
{
char const* FromFileName;
granny_int32 TextureCount;
granny_texture** Textures;
granny_int32 MaterialCount;
granny_material** Materials;
granny_int32 SkeletonCount;
granny_skeleton** Skeletons;
granny_int32 MeshCount;
granny_mesh** Meshes;
granny_int32 ModelCount;
granny_model** Models;
granny_int32 AnimationCount;
granny_animation** Animations;
granny_variant ExtendedData;
};
struct granny_system_clock
{
granny_uint32 Data[4];
};
typedef void granny_log_function(granny_log_message_type Type, granny_log_message_origin Origin,
char const* File, granny_int32x Line, char const* Message, void* UserData);
struct granny_log_callback
{
granny_log_function* Function;
void* UserData;
};
extern granny_data_type_definition* GrannyPNT332VertexType;
// Files
granny_file* GrannyReadEntireFileFromMemory(granny_int32x MemorySize, void const* Memory);
granny_file_info* GrannyGetFileInfo(granny_file* File);
void GrannyFreeFile(granny_file* File);
void GrannyFreeFileSection(granny_file* File, granny_int32x SectionIndex);
void GrannySetLogCallback(granny_log_callback const* LogCallback);
// Data types
granny_int32x GrannyGetTotalTypeSize(granny_data_type_definition const* TypeDefinition);
bool GrannyFindMatchingMember(granny_data_type_definition const* SourceType, void const* SourceObject,
char const* DestMemberName, granny_variant* Result);
void GrannyConvertSingleObject(granny_data_type_definition const* SourceType, void const* SourceObject,
granny_data_type_definition const* DestType, void* DestObject,
granny_conversion_handler* OverrideHandler);
// Materials, skeletons, meshes
granny_texture* GrannyGetMaterialTextureByType(granny_material const* Material, granny_material_texture_type Type);
bool GrannyFindBoneByName(granny_skeleton const* Skeleton, char const* BoneName, granny_int32x* BoneIndex);
bool GrannyMeshIsRigid(granny_mesh const* Mesh);
granny_int32x GrannyGetMeshVertexCount(granny_mesh const* Mesh);
granny_data_type_definition* GrannyGetMeshVertexType(granny_mesh const* Mesh);
void* GrannyGetMeshVertices(granny_mesh const* Mesh);
void GrannyCopyMeshVertices(granny_mesh const* Mesh, granny_data_type_definition const* VertexType, void* DestVertices);
granny_int32x GrannyGetMeshIndexCount(granny_mesh const* Mesh);
void GrannyCopyMeshIndices(granny_mesh const* Mesh, granny_int32x BytesPerIndex, void* DestIndices);
granny_int32x GrannyGetMeshTriangleGroupCount(granny_mesh const* Mesh);
granny_tri_material_group* GrannyGetMeshTriangleGroups(granny_mesh const* Mesh);
// Mesh binding and deformation
granny_mesh_binding* GrannyNewMeshBinding(granny_mesh const* Mesh, granny_skeleton const* FromSkeleton, granny_skeleton const* ToSkeleton);
void GrannyFreeMeshBinding(granny_mesh_binding* Binding);
granny_int32x const* GrannyGetMeshBindingToBoneIndices(granny_mesh_binding const* Binding);
granny_mesh_deformer* GrannyNewMeshDeformer(granny_data_type_definition const* InputVertexLayout,
granny_data_type_definition const* OutputVertexLayout,
granny_deformation_type DeformationType, granny_deformer_tail_flags TailFlag);
void GrannyFreeMeshDeformer(granny_mesh_deformer* Deformer);
void GrannyDeformVertices(granny_mesh_deformer const* Deformer, granny_int32x const* MatrixIndices,
granny_real32 const* MatrixBuffer4x4, granny_int32x VertexCount,
void const* SourceVertices, void* DestVertices);
// Model instances and controls
granny_model_instance* GrannyInstantiateModel(granny_model const* Model);
void GrannyFreeModelInstance(granny_model_instance* ModelInstance);
granny_skeleton* GrannyGetSourceSkeleton(granny_model_instance const* Model);
void GrannySetModelClock(granny_model_instance const* ModelInstance, granny_real32 NewClock);
void GrannyFreeCompletedModelControls(granny_model_instance const* ModelInstance);
void GrannyUpdateModelMatrix(granny_model_instance const* ModelInstance, granny_real32 SecondsElapsed,
granny_real32 const* ModelMatrix4x4, granny_real32* DestMatrix4x4, bool Inverse);
granny_control* GrannyPlayControlledAnimation(granny_real32 StartTime, granny_animation const* Animation, granny_model_instance* Model);
void GrannyFreeControl(granny_control* Control);
void GrannyFreeControlOnceUnused(granny_control* Control);
bool GrannyFreeControlIfComplete(granny_control* Control);
bool GrannyControlIsComplete(granny_control const* Control);
void GrannyCompleteControlAt(granny_control* Control, granny_real32 AtSeconds);
void GrannySetControlSpeed(granny_control* Control, granny_real32 Speed);
granny_real32 GrannyGetControlSpeed(granny_control const* Control);
void GrannySetControlLoopCount(granny_control* Control, granny_int32x LoopCount);
granny_int32x GrannyGetControlLoopCount(granny_control const* Control);
void GrannySetControlRawLocalClock(granny_control* Control, granny_real32 LocalClock);
granny_real32 GrannyGetControlRawLocalClock(granny_control* Control);
granny_real32 GrannyGetControlLocalDuration(granny_control const* Control);
void GrannySetControlEaseIn(granny_control* Control, bool EaseIn);
void GrannySetControlEaseOut(granny_control* Control, bool EaseOut);
void GrannySetControlEaseInCurve(granny_control* Control, granny_real32 StartSeconds, granny_real32 EndSeconds,
granny_real32 StartValue, granny_real32 StartTangent, granny_real32 EndTangent, granny_real32 EndValue);
void GrannySetControlEaseOutCurve(granny_control* Control, granny_real32 StartSeconds, granny_real32 EndSeconds,
granny_real32 StartValue, granny_real32 StartTangent, granny_real32 EndTangent, granny_real32 EndValue);
// Poses
granny_local_pose* GrannyNewLocalPose(granny_int32x BoneCount);
void GrannyFreeLocalPose(granny_local_pose* LocalPose);
granny_world_pose* GrannyNewWorldPose(granny_int32x BoneCount);
void GrannyFreeWorldPose(granny_world_pose* WorldPose);
void GrannySampleModelAnimationsAccelerated(granny_model_instance const* ModelInstance, granny_int32x BoneCount,
granny_real32 const* Offset4x4, granny_local_pose* Scratch, granny_world_pose* Result);
granny_real32* GrannyGetWorldPose4x4(granny_world_pose const* WorldPose, granny_int32x BoneIndex);
granny_real32* GrannyGetWorldPoseComposite4x4(granny_world_pose const* WorldPose, granny_int32x BoneIndex);
granny_matrix_4x4* GrannyGetWorldPoseComposite4x4Array(granny_world_pose const* WorldPose);