Implement looping SFX and immediate rotation opcodes

This commit is contained in:
gamer147
2026-07-28 23:45:48 -04:00
parent d2ec834fc3
commit dad3ed4a4b
13 changed files with 112 additions and 28 deletions

View File

@@ -133,6 +133,9 @@ public interface IHost
void SetVoiceBgmDuckControl(long flags) { }
void LoadSoundEffect(long resourceId, int channel) { }
void StartSoundEffect(int channel) { }
// Ops 0xb5/0xba share the native channel-start worker. Mode 0 plays once; mode 1
// rewinds the decoder at EOF. The one-argument seam remains for simple hosts.
void StartSoundEffect(int channel, int startMode) => StartSoundEffect(channel);
// Native SetDelay (op 0x2bf) starts an already-loaded channel after delayMs.
// startMode is forwarded to the same worker used by immediate SFX starts.
void ScheduleSoundEffectStart(int channel, int startMode, long delayMs) { }

View File

@@ -979,6 +979,17 @@ public sealed class GfxState
}
}
/// <summary>Op 0x1fe: immediately replace the object's current axis-angle rotation matrix at
/// obj+0xec. Axis components and angle are retained as native floating-point values.</summary>
public void SetCurrentRotation(long handle, (long X, long Y, long Z) axis, long angleDegrees)
{
lock (_lock)
{
var o = GetOrCreate(handle);
o.RotationCurrent = (axis.X, axis.Y, axis.Z, angleDegrees);
}
}
/// <summary>Op 0x1ff: immediately replace the object's current translation matrix at obj+0x16c.</summary>
public void SetCurrentTranslation(long handle, (long X, long Y, long Z) translation)
{

View File

@@ -2398,8 +2398,10 @@ public sealed class VirtualMachine
_host.LoadSoundEffect(resourceId, channel);
return pc + 1;
}
case "u0041D050": // 0xb5 / semantics: sfx-start
_host.StartSoundEffect((int)Read(a[0])); return pc + 1;
case "u0041D050": // 0xb5 / semantics: sfx-start-once
_host.StartSoundEffect((int)Read(a[0]), 0); return pc + 1;
case "sfx-start-loop": // 0xba / same worker, logical decoder rewind at EOF
_host.StartSoundEffect((int)Read(a[0]), 1); return pc + 1;
case "u0041D080": // 0xb6 / semantics: sfx-release
{
int channel = (int)Read(a[0]);
@@ -2554,6 +2556,9 @@ public sealed class VirtualMachine
case "u00420620": // upstream ABI label
case "gfx-set-scale-current": // 0x1fd (handle)(sx%)(sy%)(sz%) -> current scale matrix
Gfx.SetCurrentScale(Read(a[0]), (Read(a[1]), Read(a[2]), Read(a[3]))); return pc + 1;
case "set-current-rotation-axis-angle": // 0x1fe (handle)(axis x/y/z)(angle degrees)
Gfx.SetCurrentRotation(Read(a[0]), (Read(a[1]), Read(a[2]), Read(a[3])), Read(a[4]));
return pc + 1;
case "set-adv-wait-indicator-handle": // 0x212 (layout)(retained handle)
{
TextHistory.SetWaitIndicatorObjectHandle((int)Read(a[0]), Read(a[1]));