#pragma once // Our hooks into SceneWindow.dll's scene code, installed once, the first time an engine is made. Each replaces where // IMVU's code calls a function (an entry of an exported vtable, or a call instruction's target), after checking it // calls the function expected, with ours, which calls IMVU's: nothing else is changed, and nothing is if a check // fails (an unexpected SceneWindow.dll: the hooks' features are then off, and the client runs as it would without). // // - SceneViewer::step (the IFrameListener vtable): the client's tick, 30 times a second (SceneWindow.dll's runApp // calls stepFrame, which steps each scene viewer). Recorded, for the frame pacer and for drawing between ticks. // - ModelInstance::render's call to updateCalSkeleton, which poses the model before it's drawn: between ticks, the // model is posed at the time between them (its animations' times moved on by the fraction of a frame since the // tick; Cal3D poses between keyframes) and crossfading animations' weights partway to the next tick's, then its // animations are put back as they were. // - ModelInstance::render's call to ParticleSystem::render: between ticks, particles drawn moved on by their velocity // times the time since the tick (as the particle library moves them at each tick), then put back. // - CameraController::getCameraTransform (its exported vtable): between ticks, the camera where its easing toward its // target has brought it since the tick. #include namespace t5de::scene_hooks { void install(); // Whether the hooks are installed. [[nodiscard]] bool installed(); // When a scene viewer last stepped (QueryPerformanceCounter), or 0 if none has. [[nodiscard]] std::int64_t lastStep(); } // namespace t5de::scene_hooks