feat(core): adopt retail's SoundType catalog; retire AC2D
SoundId was not a subset of retail's table, the way its comment claimed. It was an invention: 23 acdream-local names on acdream-local values, and the values were wrong in the way that matters. FootstepDefault = 0x02 is retail's Random. SwingSword = 0x10 is retail's Death2. Death = 0x60 is retail's Explode. Anyone who reached for one of those names to compare against a wire or dat value would have got a different sound. Nothing referenced any of them by name -- grep for `SoundId.` across src and tests returns nothing -- so this was a trap rather than a live defect, the same shape the enum campaign found in DamageType. All 22 invented names are deleted and retail's 205 replace them. Three oracles agree exactly, on every name and every value: retail acclient.h:4569 enum SoundType, ACE's Sound, and DatReaderWriter's Sound. The third matters most. AudioHookSink already resolves SoundTable lookups through DatReaderWriter.Enums.Sound, so that is the enum acdream actually reads at runtime; our catalog now agrees with the values already flowing through the dat path, and a conformance test pins the two so they cannot drift apart. On the "206 sounds" figure: retail's block holds 207 entries, being 205 sounds followed by NUM_SOUND_TYPES = 0xCD and FORCE_SoundType_32_BIT. The first is a count and the second a width pin. Counting the former is where 206 came from. Neither is a member here, matching how the campaign treated NUM_ATTACK_HEIGHTS and Num_HoldKeys -- a count is not a value the wire can carry. Behaviour is unchanged and could not be otherwise: the enum had no consumers. IAudioEngine's three SoundId overloads are no-op stubs and the live path takes wave ids and DatReaderWriter values. The user's separate report that sound is "not working that good" is a triggering, selection and attenuation question rather than a catalog one, and is filed as its own Bucket B row in the post-Vulkan intake. Also in this commit, by user decision: AC2D is retired as a reference. Its clone and directory are gone and it must not be re-cloned. Everything we took from it still stands and is written down -- the FSplitNESW terrain split constants, the 0xF61C movement packet layout, the finding that a client need not compute terrain Z itself -- so CLAUDE.md's reference list, its hierarchy table, and the architecture doc's protocol row now point at docs/research/2026-04-12-movement-deep-dive.md rather than erasing the history. The reference count drops from six to five. Core tests 3907 passed / 2 skipped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
f27ad9ee43
commit
39c1737bda
7 changed files with 601 additions and 58 deletions
|
|
@ -9,37 +9,9 @@ namespace AcDream.Core.Audio;
|
|||
// Runtime backend (Silk.NET.OpenAL) lives in AcDream.App.
|
||||
// ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Enumerated retail sound IDs. See r05 §5 for the full 204-entry list.
|
||||
/// Only the commonly-fired ones are given names here.
|
||||
/// </summary>
|
||||
public enum SoundId : uint
|
||||
{
|
||||
None = 0,
|
||||
FootstepDefault = 0x02,
|
||||
FootstepGrass = 0x03,
|
||||
FootstepWater = 0x04,
|
||||
FootstepDirt = 0x05,
|
||||
FootstepStone = 0x06,
|
||||
FootstepWood = 0x07,
|
||||
SwingSword = 0x10,
|
||||
SwingAxe = 0x11,
|
||||
HitMetalOnMetal = 0x20,
|
||||
HitMetalOnLeather = 0x21,
|
||||
HitFlesh = 0x22,
|
||||
ArrowWhoosh = 0x30,
|
||||
ArrowThud = 0x31,
|
||||
SpellCastWar = 0x40,
|
||||
SpellCastLife = 0x41,
|
||||
SpellCastItem = 0x42,
|
||||
SpellCastCreature = 0x43,
|
||||
PortalWhoosh = 0x50,
|
||||
LifestoneTie = 0x51,
|
||||
Death = 0x60,
|
||||
PotionDrink = 0x70,
|
||||
BuffApplied = 0x80,
|
||||
// More constants populated during R5 audio port.
|
||||
}
|
||||
// SoundId moved to its own file on 2026-07-29, when the hand-curated
|
||||
// 23-member subset was replaced by retail's full 205-entry SoundType
|
||||
// catalog: src/AcDream.Core/Audio/SoundId.cs (same namespace).
|
||||
|
||||
/// <summary>
|
||||
/// Per-SoundId entry from the SoundTable dat (0x20000000..0x2000FFFF).
|
||||
|
|
|
|||
242
src/AcDream.Core/Audio/SoundId.cs
Normal file
242
src/AcDream.Core/Audio/SoundId.cs
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
namespace AcDream.Core.Audio;
|
||||
|
||||
/// <summary>
|
||||
/// Retail's <c>SoundType</c> catalog — the sound *slot* an object's SoundTable
|
||||
/// is indexed by, not a wave id. All 205 named members, at retail values.
|
||||
///
|
||||
/// <para>
|
||||
/// <b>2026-07-29 full adoption.</b> Until this slice the enum was a
|
||||
/// 23-member local invention: names like <c>FootstepGrass</c> and
|
||||
/// <c>BuffApplied</c> that retail does not have, on values that mean something
|
||||
/// else in retail (the old <c>FootstepDefault = 0x02</c> is retail
|
||||
/// <c>Random</c>; <c>SwingSword = 0x10</c> is retail <c>Death2</c>). Nothing
|
||||
/// referenced any of them by name, so they were a trap rather than a live
|
||||
/// defect — the same shape of trap the enum campaign found in
|
||||
/// <c>DamageType</c>. All 22 invented names are gone.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// Three oracles agree exactly, on every name and every value: retail
|
||||
/// <c>acclient.h:4569 enum SoundType</c>, ACE <c>ACE.Entity.Enum.Sound</c>, and
|
||||
/// DatReaderWriter <c>DatReaderWriter.Enums.Sound</c> — which is the enum the
|
||||
/// dat-side hook path already flows through, so this table now agrees with the
|
||||
/// values acdream actually reads at runtime.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// Retail's block holds two more entries after <c>SkillDownVoid</c>:
|
||||
/// <c>NUM_SOUND_TYPES = 0xCD</c> and <c>FORCE_SoundType_32_BIT</c>. The first
|
||||
/// is a count and the second is a width pin; neither is a sound, and neither is
|
||||
/// a member here, matching how the enum campaign treated
|
||||
/// <c>NUM_ATTACK_HEIGHTS</c> and <c>Num_HoldKeys</c>. Counting
|
||||
/// <c>NUM_SOUND_TYPES</c> is where the "206 retail sounds" figure comes from.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public enum SoundId : uint
|
||||
{
|
||||
Invalid = 0x00,
|
||||
Speak1 = 0x01,
|
||||
Random = 0x02,
|
||||
Attack1 = 0x03,
|
||||
Attack2 = 0x04,
|
||||
Attack3 = 0x05,
|
||||
SpecialAttack1 = 0x06,
|
||||
SpecialAttack2 = 0x07,
|
||||
SpecialAttack3 = 0x08,
|
||||
Damage1 = 0x09,
|
||||
Damage2 = 0x0A,
|
||||
Damage3 = 0x0B,
|
||||
Wound1 = 0x0C,
|
||||
Wound2 = 0x0D,
|
||||
Wound3 = 0x0E,
|
||||
Death1 = 0x0F,
|
||||
Death2 = 0x10,
|
||||
Death3 = 0x11,
|
||||
Grunt1 = 0x12,
|
||||
Grunt2 = 0x13,
|
||||
Grunt3 = 0x14,
|
||||
Oh1 = 0x15,
|
||||
Oh2 = 0x16,
|
||||
Oh3 = 0x17,
|
||||
Heave1 = 0x18,
|
||||
Heave2 = 0x19,
|
||||
Heave3 = 0x1A,
|
||||
Knockdown1 = 0x1B,
|
||||
Knockdown2 = 0x1C,
|
||||
Knockdown3 = 0x1D,
|
||||
Swoosh1 = 0x1E,
|
||||
Swoosh2 = 0x1F,
|
||||
Swoosh3 = 0x20,
|
||||
Thump1 = 0x21,
|
||||
Smash1 = 0x22,
|
||||
Scratch1 = 0x23,
|
||||
Spear = 0x24,
|
||||
Sling = 0x25,
|
||||
Dagger = 0x26,
|
||||
ArrowWhiz1 = 0x27,
|
||||
ArrowWhiz2 = 0x28,
|
||||
CrossbowPull = 0x29,
|
||||
CrossbowRelease = 0x2A,
|
||||
BowPull = 0x2B,
|
||||
BowRelease = 0x2C,
|
||||
ThrownWeaponRelease1 = 0x2D,
|
||||
ArrowLand = 0x2E,
|
||||
Collision = 0x2F,
|
||||
HitFlesh1 = 0x30,
|
||||
HitLeather1 = 0x31,
|
||||
HitChain1 = 0x32,
|
||||
HitPlate1 = 0x33,
|
||||
HitMissile1 = 0x34,
|
||||
HitMissile2 = 0x35,
|
||||
HitMissile3 = 0x36,
|
||||
Footstep1 = 0x37,
|
||||
Footstep2 = 0x38,
|
||||
Walk1 = 0x39,
|
||||
Dance1 = 0x3A,
|
||||
Dance2 = 0x3B,
|
||||
Dance3 = 0x3C,
|
||||
Hidden1 = 0x3D,
|
||||
Hidden2 = 0x3E,
|
||||
Hidden3 = 0x3F,
|
||||
Eat1 = 0x40,
|
||||
Drink1 = 0x41,
|
||||
Open = 0x42,
|
||||
Close = 0x43,
|
||||
OpenSlam = 0x44,
|
||||
CloseSlam = 0x45,
|
||||
Ambient1 = 0x46,
|
||||
Ambient2 = 0x47,
|
||||
Ambient3 = 0x48,
|
||||
Ambient4 = 0x49,
|
||||
Ambient5 = 0x4A,
|
||||
Ambient6 = 0x4B,
|
||||
Ambient7 = 0x4C,
|
||||
Ambient8 = 0x4D,
|
||||
Waterfall = 0x4E,
|
||||
LogOut = 0x4F,
|
||||
LogIn = 0x50,
|
||||
LifestoneOn = 0x51,
|
||||
AttribUp = 0x52,
|
||||
AttribDown = 0x53,
|
||||
SkillUp = 0x54,
|
||||
SkillDown = 0x55,
|
||||
HealthUp = 0x56,
|
||||
HealthDown = 0x57,
|
||||
ShieldUp = 0x58,
|
||||
ShieldDown = 0x59,
|
||||
EnchantUp = 0x5A,
|
||||
EnchantDown = 0x5B,
|
||||
VisionUp = 0x5C,
|
||||
VisionDown = 0x5D,
|
||||
Fizzle = 0x5E,
|
||||
Launch = 0x5F,
|
||||
Explode = 0x60,
|
||||
TransUp = 0x61,
|
||||
TransDown = 0x62,
|
||||
BreatheFlaem = 0x63,
|
||||
BreatheAcid = 0x64,
|
||||
BreatheFrost = 0x65,
|
||||
BreatheLightning = 0x66,
|
||||
Create = 0x67,
|
||||
Destroy = 0x68,
|
||||
Lockpicking = 0x69,
|
||||
UI_EnterPortal = 0x6A,
|
||||
UI_ExitPortal = 0x6B,
|
||||
UI_GeneralQuery = 0x6C,
|
||||
UI_GeneralError = 0x6D,
|
||||
UI_TransientMessage = 0x6E,
|
||||
UI_IconPickUp = 0x6F,
|
||||
UI_IconSuccessfulDrop = 0x70,
|
||||
UI_IconInvalid_Drop = 0x71,
|
||||
UI_ButtonPress = 0x72,
|
||||
UI_GrabSlider = 0x73,
|
||||
UI_ReleaseSlider = 0x74,
|
||||
UI_NewTargetSelected = 0x75,
|
||||
UI_Roar = 0x76,
|
||||
UI_Bell = 0x77,
|
||||
UI_Chant1 = 0x78,
|
||||
UI_Chant2 = 0x79,
|
||||
UI_DarkWhispers1 = 0x7A,
|
||||
UI_DarkWhispers2 = 0x7B,
|
||||
UI_DarkLaugh = 0x7C,
|
||||
UI_DarkWind = 0x7D,
|
||||
UI_DarkSpeech = 0x7E,
|
||||
UI_Drums = 0x7F,
|
||||
UI_GhostSpeak = 0x80,
|
||||
UI_Breathing = 0x81,
|
||||
UI_Howl = 0x82,
|
||||
UI_LostSouls = 0x83,
|
||||
UI_Squeal = 0x84,
|
||||
UI_Thunder1 = 0x85,
|
||||
UI_Thunder2 = 0x86,
|
||||
UI_Thunder3 = 0x87,
|
||||
UI_Thunder4 = 0x88,
|
||||
UI_Thunder5 = 0x89,
|
||||
UI_Thunder6 = 0x8A,
|
||||
RaiseTrait = 0x8B,
|
||||
WieldObject = 0x8C,
|
||||
UnwieldObject = 0x8D,
|
||||
ReceiveItem = 0x8E,
|
||||
PickUpItem = 0x8F,
|
||||
DropItem = 0x90,
|
||||
ResistSpell = 0x91,
|
||||
PicklockFail = 0x92,
|
||||
LockSuccess = 0x93,
|
||||
OpenFailDueToLock = 0x94,
|
||||
TriggerActivated = 0x95,
|
||||
SpellExpire = 0x96,
|
||||
ItemManaDepleted = 0x97,
|
||||
TriggerActivated1 = 0x98,
|
||||
TriggerActivated2 = 0x99,
|
||||
TriggerActivated3 = 0x9A,
|
||||
TriggerActivated4 = 0x9B,
|
||||
TriggerActivated5 = 0x9C,
|
||||
TriggerActivated6 = 0x9D,
|
||||
TriggerActivated7 = 0x9E,
|
||||
TriggerActivated8 = 0x9F,
|
||||
TriggerActivated9 = 0xA0,
|
||||
TriggerActivated10 = 0xA1,
|
||||
TriggerActivated11 = 0xA2,
|
||||
TriggerActivated12 = 0xA3,
|
||||
TriggerActivated13 = 0xA4,
|
||||
TriggerActivated14 = 0xA5,
|
||||
TriggerActivated15 = 0xA6,
|
||||
TriggerActivated16 = 0xA7,
|
||||
TriggerActivated17 = 0xA8,
|
||||
TriggerActivated18 = 0xA9,
|
||||
TriggerActivated19 = 0xAA,
|
||||
TriggerActivated20 = 0xAB,
|
||||
TriggerActivated21 = 0xAC,
|
||||
TriggerActivated22 = 0xAD,
|
||||
TriggerActivated23 = 0xAE,
|
||||
TriggerActivated24 = 0xAF,
|
||||
TriggerActivated25 = 0xB0,
|
||||
TriggerActivated26 = 0xB1,
|
||||
TriggerActivated27 = 0xB2,
|
||||
TriggerActivated28 = 0xB3,
|
||||
TriggerActivated29 = 0xB4,
|
||||
TriggerActivated30 = 0xB5,
|
||||
TriggerActivated31 = 0xB6,
|
||||
TriggerActivated32 = 0xB7,
|
||||
TriggerActivated33 = 0xB8,
|
||||
TriggerActivated34 = 0xB9,
|
||||
TriggerActivated35 = 0xBA,
|
||||
TriggerActivated36 = 0xBB,
|
||||
TriggerActivated37 = 0xBC,
|
||||
TriggerActivated38 = 0xBD,
|
||||
TriggerActivated39 = 0xBE,
|
||||
TriggerActivated40 = 0xBF,
|
||||
TriggerActivated41 = 0xC0,
|
||||
TriggerActivated42 = 0xC1,
|
||||
TriggerActivated43 = 0xC2,
|
||||
TriggerActivated44 = 0xC3,
|
||||
TriggerActivated45 = 0xC4,
|
||||
TriggerActivated46 = 0xC5,
|
||||
TriggerActivated47 = 0xC6,
|
||||
TriggerActivated48 = 0xC7,
|
||||
TriggerActivated49 = 0xC8,
|
||||
TriggerActivated50 = 0xC9,
|
||||
HealthDownVoid = 0xCA,
|
||||
RegenDownVoid = 0xCB,
|
||||
SkillDownVoid = 0xCC,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue