Add built-in asset modules for Wolfenstein 3D v1.4 Shareware release
- Implement RetailSfxModule to map sound effects to numeric slots. - Create SharewareAssetRegistry to manage assets for the Shareware version. - Introduce SharewareEntityModule to define available enemies in Shareware. - Add SharewareMenuPicModule to handle menu pictures with runtime offset computation. - Implement SharewareMusicModule for music routing in Shareware. - Define keys for entities, HUD elements, menu pictures, and music tracks. - Create abstract modules for entity, HUD, menu picture, and music assets. - Add registry resolver to select appropriate asset registry based on game version and data version. - Update WolfensteinData to include new asset registry exports. - Modify tests to utilize the new asset registry structure for Shareware and Retail versions. Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import 'package:wolf_3d_dart/src/data_types/enemy_animation.dart';
|
||||
import 'package:wolf_3d_dart/src/registry/keys/entity_key.dart';
|
||||
|
||||
/// All version-sensitive asset data for a single entity type.
|
||||
///
|
||||
/// - [animations] is `null` for bosses that drive sprite selection with
|
||||
/// custom logic and do not use the standard [EnemyAnimationMap].
|
||||
/// - [baseSpriteIndex] is the sprite-list offset used by custom-logic bosses
|
||||
/// as the base for their manual frame calculations.
|
||||
/// - [availableInShareware] mirrors the original engine's version-exclusion
|
||||
/// flag; entities with `false` are skipped during shareware level loading.
|
||||
class EntityAssetDefinition {
|
||||
const EntityAssetDefinition({
|
||||
this.animations,
|
||||
this.baseSpriteIndex,
|
||||
this.availableInShareware = true,
|
||||
});
|
||||
|
||||
final EnemyAnimationMap? animations;
|
||||
final int? baseSpriteIndex;
|
||||
final bool availableInShareware;
|
||||
}
|
||||
|
||||
/// Owns the mapping from symbolic [EntityKey] values to version-specific
|
||||
/// [EntityAssetDefinition] objects.
|
||||
///
|
||||
/// Implement this class to provide custom sprite data for a modded or
|
||||
/// alternate game version. Pass the implementation inside a custom
|
||||
/// [AssetRegistry] when loading data.
|
||||
abstract class EntityAssetModule {
|
||||
const EntityAssetModule();
|
||||
|
||||
/// Resolves [key] to an [EntityAssetDefinition].
|
||||
///
|
||||
/// Returns `null` if the key is not recognised by this module.
|
||||
EntityAssetDefinition? resolve(EntityKey key);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import 'package:wolf_3d_dart/src/registry/keys/hud_key.dart';
|
||||
|
||||
/// The resolved reference for a HUD element: a zero-based index into
|
||||
/// [WolfensteinData.vgaImages].
|
||||
class HudAssetRef {
|
||||
const HudAssetRef(this.vgaIndex);
|
||||
|
||||
final int vgaIndex;
|
||||
|
||||
@override
|
||||
String toString() => 'HudAssetRef($vgaIndex)';
|
||||
}
|
||||
|
||||
/// Owns the mapping from symbolic [HudKey] identifiers to VGA image indices.
|
||||
///
|
||||
/// Implement this class to provide a custom HUD layout for a modded or
|
||||
/// alternate game version. Pass the implementation inside a custom
|
||||
/// [AssetRegistry] when loading data.
|
||||
abstract class HudModule {
|
||||
const HudModule();
|
||||
|
||||
/// Resolves [key] to a [HudAssetRef] containing the VGA image index.
|
||||
///
|
||||
/// Returns `null` if the key is not supported by this module.
|
||||
HudAssetRef? resolve(HudKey key);
|
||||
|
||||
/// Returns the appropriate [HudKey] for BJ's face sprite given the
|
||||
/// player's current [health].
|
||||
HudKey faceKeyForHealth(int health);
|
||||
|
||||
/// Convenience: resolves BJ's face image directly from [health].
|
||||
HudAssetRef? faceForHealth(int health) => resolve(faceKeyForHealth(health));
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import 'package:wolf_3d_dart/src/data_types/difficulty.dart';
|
||||
import 'package:wolf_3d_dart/src/registry/keys/menu_pic_key.dart';
|
||||
|
||||
/// The resolved reference for a menu picture: a zero-based index into
|
||||
/// [WolfensteinData.vgaImages].
|
||||
class MenuPicRef {
|
||||
const MenuPicRef(this.pictureIndex);
|
||||
|
||||
final int pictureIndex;
|
||||
|
||||
@override
|
||||
String toString() => 'MenuPicRef($pictureIndex)';
|
||||
}
|
||||
|
||||
/// Owns the mapping from symbolic [MenuPicKey] values to VGA picture indices.
|
||||
///
|
||||
/// Implement this class to provide custom menu art for a modded or alternate
|
||||
/// game version. Pass the implementation inside a custom [AssetRegistry] when
|
||||
/// loading data.
|
||||
abstract class MenuPicModule {
|
||||
const MenuPicModule();
|
||||
|
||||
/// Resolves [key] to a [MenuPicRef] containing the VGA picture index.
|
||||
///
|
||||
/// Returns `null` if the key is not supported by this module.
|
||||
MenuPicRef? resolve(MenuPicKey key);
|
||||
|
||||
/// Returns the [MenuPicKey] for the episode selection picture at
|
||||
/// zero-based [episodeIndex].
|
||||
MenuPicKey episodeKey(int episodeIndex);
|
||||
|
||||
/// Returns the [MenuPicKey] for the given [difficulty] selection screen.
|
||||
MenuPicKey difficultyKey(Difficulty difficulty);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import 'package:wolf_3d_dart/src/registry/keys/music_key.dart';
|
||||
|
||||
/// The resolved reference for a music track: a numeric index into
|
||||
/// [WolfensteinData.music].
|
||||
class MusicRoute {
|
||||
const MusicRoute(this.trackIndex);
|
||||
|
||||
final int trackIndex;
|
||||
|
||||
@override
|
||||
String toString() => 'MusicRoute($trackIndex)';
|
||||
}
|
||||
|
||||
/// Owns the mapping from music contexts to IMF track indices.
|
||||
///
|
||||
/// Implement this class to provide a custom music layout for a modded or
|
||||
/// alternate game version. Pass the implementation inside a custom
|
||||
/// [AssetRegistry] when loading data.
|
||||
abstract class MusicModule {
|
||||
const MusicModule();
|
||||
|
||||
/// Resolves a named [MusicKey] to a [MusicRoute].
|
||||
///
|
||||
/// Returns `null` if the key is not supported by this module.
|
||||
MusicRoute? resolve(MusicKey key);
|
||||
|
||||
/// Resolves the level music track for a given [episodeIndex] and
|
||||
/// zero-based [levelIndex].
|
||||
///
|
||||
/// This is the primary routing path for in-game level music, which the
|
||||
/// original engine mapped via a lookup table rather than per-level fields.
|
||||
MusicRoute musicForLevel(int episodeIndex, int levelIndex);
|
||||
|
||||
/// The music track to play while the main menu is shown.
|
||||
MusicRoute get menuMusic;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'package:wolf_3d_dart/src/registry/keys/sfx_key.dart';
|
||||
|
||||
/// The resolved reference for a sound effect: a numeric slot index into
|
||||
/// [WolfensteinData.sounds].
|
||||
class SoundAssetRef {
|
||||
const SoundAssetRef(this.slotIndex);
|
||||
|
||||
final int slotIndex;
|
||||
|
||||
@override
|
||||
String toString() => 'SoundAssetRef($slotIndex)';
|
||||
}
|
||||
|
||||
/// Owns the mapping from symbolic [SfxKey] identifiers to numeric sound slots.
|
||||
///
|
||||
/// Implement this class to provide a custom sound layout for a modded or
|
||||
/// alternate game version. Pass the implementation inside a custom
|
||||
/// [AssetRegistry] when loading data.
|
||||
abstract class SfxModule {
|
||||
const SfxModule();
|
||||
|
||||
/// Resolves [key] to a [SoundAssetRef] containing the numeric slot index.
|
||||
///
|
||||
/// Returns `null` if the key is not supported by this module.
|
||||
SoundAssetRef? resolve(SfxKey key);
|
||||
}
|
||||
Reference in New Issue
Block a user