Fixes for rendering and audio issues#85
Merged
Merged
Conversation
- Raise ENDX when a voice reaches its logical end instead of waiting for SDL's stream queue to drain. - Calculate sustain level with 64-bit fixed-point math so SL=15 does not overflow to -65536.
Check the furniture type first and skip no-collision records before resolving the area pointer. Also cleaned up the reused addr variable into named pointers to make the flow clearer.
MikuPan_RenderSprite3D always used normal alpha blending, but some original GS sprite effects use additive alpha. This made effects such as the defeated ghost orb render as a darker blue instead of the intended bright cyan glow. Add a sprite render path that can select additive blending and use it for Set3DPosTexure when the original GS alpha mode requests src-alpha additive blending.
The defeated ghost screen twist path was using the live screen-copy renderer instead of the captured GS texture used by the original effect. This allowed the scene to distort, but lost the proper source/destination mismatch needed for thetwist and did not preserve the ghost model in the captured image. Render the twisted mesh from the captured GS texture and use the untwisted projection as source UVs, matching the original effect flow.
The distortion particle path used the original PS2 clip result to gate both the preserved GS packet output and MikuPan's GL fallback rendering. This meant a particle could be valid for the GL camera but still be rejected before any GL vertices were emitted. Keep the original PS2 clip test for the GS packet path, but use MikuPan's GL clip matrix when deciding whether to emit GL vertices. This fixes distortion particle effects such as the captured-ghost blue flame, where particles were building normally but never reached the GL renderer.
wagrenier
approved these changes
Jun 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Audio
Fix SPU voice completion so ENDX is driven by emulated sample playback instead of SDL queue drain state.
Voices no longer depend on the SDL queue being fully drained before they can be reused, which could leave sounds backlogged behind tiny leftover queued audio. Finished voices are now cleaned up through the emulated SPU voice state, with ENDX cleared properly and sustain levels handled correctly.
3D Sprite Blending
Adds support for additive blending in the 3D sprite path. Some original GS effects use src-alpha additive blending, but MikuPan was rendering them with normal alpha blending. This fixes effects such as the defeated ghost orbs appearing too dark.
Ghost defeat distortion
Fixes the defeated ghost screen distortion/twist effect. The original effect captures the framebuffer while the ghost is still visible and uses the untwisted projection as source UV's while drawing the twisted mesh. MikuPan was using the live screen-copy path, which distorted the scene but lost the intended twist and did not preserve the ghost model in the captured image.
Particle clipping
Separates the original PS2 clip test from MikuPans GL fallback clipping. The distorion particle path was using the PS2 clip result to gate both the preserved GS packet path and the GL renderer, which could reject valid GL particles before any verticies were emitted. The GS packet path still uses the PS2 clip matrix, while the GL path now uses MikuPans GL clip matrix.
This restores effects like the blue flame when capturing a ghost.
Furniture cover checks
Fixes invalid PS2 address warnings for furniture with no collision or area. FurnCoverCheck was resolving the area pointer before checking the furniture collision type. In the original code this isn't an issue since PosInAreaJudgeSub gates by type, but since MikuPan now uses MikuPan_GetHostPointer, the operation occurred before the check.
Additionally, the function has been cleaned up to avoid the addr identity crisis.
Testing
MSVC on Windows.
Tested in-game both Night 1 and parts of Night 2. No new noticeable bugs have occurred from these changes as far as I can see.