Jazz2::ContentResolver class

Manages loading of assets.

Public static variables

static std::uint8_t LevelFile constexpr
static std::uint8_t EpisodeFile constexpr
static std::uint8_t CacheIndexFile constexpr
static std::uint8_t ConfigFile constexpr
static std::uint8_t StateFile constexpr
static std::uint8_t SfxListFile constexpr
static std::uint8_t HighscoresFile constexpr

Public static functions

static auto Get() -> ContentResolver&
Returns static instance of main content resolver.
static auto ShiftHue(std::uint32_t color, float degrees) -> std::uint32_t
Rotates the hue of a packed 0xAABBGGRR color by degrees.
static auto HueShiftDegreesForGradient(std::int32_t gradientStart) -> float
Returns the hue rotation (degrees) for the gradient starting at gradientStart when FurHueShiftFlag is set.

Constructors, destructors, conversion operators

~ContentResolver()

Public functions

void Release()
Releases all cached assets.
auto GetContentPath() const -> StringView
Returns path to "Content" directory.
auto GetCachePath() const -> StringView
Returns path to "Cache" directory.
auto GetSourcePath() const -> StringView
Returns path to "Source" directory.
auto IsHeadless() const -> bool
Returns true if the application is running in headless mode (i.e., without any display).
void SetHeadless(bool value)
Sets whether the application is running in headless mode.
void RemountPaks()
Scans the "Content" and "Cache" directories for .pak files and mounts them.
auto OpenContentFile(StringView path, std::int32_t bufferSize = 8192) -> std::unique_ptr<Stream>
Tries to find and open a file specified by the path.
auto OpenSourceFile(StringView path, std::int32_t bufferSize = 8192) -> std::unique_ptr<Stream>
Tries to open a file from the "Source" directory (case-insensitive).
void BeginLoading()
Marks beginning of the loading assets.
void EndLoading()
Marks end of the loading assets.
void OverridePathHandler(Function<String(StringView)>&& callback)
Overrides the default path handler.
void PreloadMetadataAsync(StringView path)
Preloads specified metadata and its linked assets to cache.
auto RequestMetadata(StringView path, bool forceIndexed = false) -> Metadata*
Loads specified metadata and its linked assets (cached).
auto RequestGraphics(StringView path, std::uint16_t paletteOffset, bool keepIndexed = false) -> GenericGraphicResource*
Loads specified graphics asset (cached).
void BuildPlayerColorPalette(std::uint32_t furColor, std::uint32_t* outPalette) const
Builds a 256-color palette for a player from a packed 4-byte fur color.
auto ApplyPlayerColorPalette(std::unique_ptr<Texture>& texture, std::uint32_t furColor) -> Texture*
Builds/updates a standalone 256x1 palette texture for a player fur color and returns it.
auto GetPaletteTexture() -> Texture*
Returns the shared 256x256 palette texture, uploading any rows changed since the last call.
auto AcquirePaletteOffset(std::uint32_t furColor) -> std::int32_t
Acquires a reference-counted palette offset for the given packed fur color.
void ReleasePaletteOffset(std::int32_t paletteOffset)
Releases one reference to a palette offset from AcquirePaletteOffset.
auto ConfigureSpriteShader(RenderCommand& command, bool indexed) -> bool
Configures a manually-built render command for a (possibly indexed) sprite.
void BindSpritePalette(RenderCommand& command, GLUniformBlockCache& instanceBlock, const Texture& diffuse, bool indexed, std::uint16_t paletteOffset)
Binds the diffuse (and, when indexed, the palette) textures for a sprite render command.
auto RequestTileSet(StringView path, std::uint16_t captionTileId, bool applyPalette, const std::uint8_t* paletteRemapping = nullptr) -> std::unique_ptr<Tiles::TileSet>
Loads specified tile set and its palette.
auto LevelExists(StringView levelName) -> bool
Returns true if specified level exists.
auto TryLoadLevel(StringView path, GameDifficulty difficulty, LevelDescriptor& descriptor) -> bool
Loads specified level into a level descriptor.
void ApplyDefaultPalette()
Loads default (sprite) palette.
void SetSpritePalette(ArrayView<const std::uint32_t> palette)
Overrides the active sprite palette (row 0 of the shared palette).
auto GetEpisode(StringView name, bool withImages = false) -> std::optional<Episode>
Returns specified episode by name.
auto GetEpisodeByPath(StringView path, bool withImages = false) -> std::optional<Episode>
Returns specified episode by full path.
auto GetMusic(StringView path) -> std::unique_ptr<AudioStreamPlayer>
Loads specified music.
auto GetFont(FontType fontType) -> UI::Font*
Returns specified font type.
auto GetShader(PrecompiledShader shader) -> Shader*
Returns specified precompiled shader.
void CompileShaders()
Precompiles all required shaders.
auto GetNoiseTexture() -> std::unique_ptr<Texture>
Returns a noise texture with random pixels.
auto GetPalettes() const -> StaticArrayView<PaletteCount*ColorsPerPalette, const std::uint32_t>
Returns currently loaded set of palettes.

Constants

static std::uint32_t PixelSize constexpr
Pixel size in bytes.
static std::int32_t PaletteCount constexpr
Maximum number of palettes.
static std::int32_t ColorsPerPalette constexpr
Number of colors per palette.
static std::int32_t FirstDynamicPaletteRow constexpr
First shared-palette row available for dynamic per-player allocation.
static std::int32_t InvalidValue constexpr
Invalid value.

Player recolor palette sections

static std::int32_t FurSectionCount constexpr
Number of recolorable fur sections.
static std::int32_t FurSectionSize constexpr
Number of consecutive palette indices per fur section.
static std::int32_t FurSectionStarts constexpr
Starting palette index of each fur section in the per-player palette.
static std::uint8_t FurHueShiftFlag constexpr
High bit of a fur section byte requesting its gradient be hue-shifted by HueShiftDegreesForGradient.

Function documentation

static std::uint32_t Jazz2::ContentResolver::ShiftHue(std::uint32_t color, float degrees)

Rotates the hue of a packed 0xAABBGGRR color by degrees.

Rotates in YIQ space, so the result keeps the original's perceived brightness (luma) and chroma - only the hue changes, and alpha is untouched. Used to derive the per-gradient hue-shifted fur variants.

static float Jazz2::ContentResolver::HueShiftDegreesForGradient(std::int32_t gradientStart)

Returns the hue rotation (degrees) for the gradient starting at gradientStart when FurHueShiftFlag is set.

Each selectable gradient gets its own angle, chosen so its hue-shifted twin lands where the base gradients are sparse (the sprite palette clusters into a warm wedge ~0-73° and a cool wedge ~207-335°, leaving green/cyan/indigo underrepresented). A single global angle would push ~2 of the cool gradients back onto hues that already exist; per-gradient angles spread all twins evenly. Returns 0 for the near-neutral gradients (and any unrecognized start), which barely change under rotation and so get no twin.

std::unique_ptr<Stream> Jazz2::ContentResolver::OpenSourceFile(StringView path, std::int32_t bufferSize = 8192)

Tries to open a file from the "Source" directory (case-insensitive).

Used for original/custom game files. The returned stream is invalid if the file wasn't found.

Metadata* Jazz2::ContentResolver::RequestMetadata(StringView path, bool forceIndexed = false)

Loads specified metadata and its linked assets (cached).

Parameters
path Relative path to the metadata asset
forceIndexed Load all linked graphics as indexed (palette not baked) so they can be recolored at draw time - used for the player so each player can have a custom color scheme

GenericGraphicResource* Jazz2::ContentResolver::RequestGraphics(StringView path, std::uint16_t paletteOffset, bool keepIndexed = false)

Loads specified graphics asset (cached).

Parameters
path Relative path to the graphics asset
paletteOffset Index of the first palette color used to bake the sprite (ignored when keepIndexed)
keepIndexed Keep raw palette indices in the texture (don't bake the palette) for shader recoloring

void Jazz2::ContentResolver::BuildPlayerColorPalette(std::uint32_t furColor, std::uint32_t* outPalette) const

Builds a 256-color palette for a player from a packed 4-byte fur color.

Each byte is one section: a gradient start index in the sprite palette (0 = keep the original colors). See FurSectionStarts.

Texture* Jazz2::ContentResolver::ApplyPlayerColorPalette(std::unique_ptr<Texture>& texture, std::uint32_t furColor)

Builds/updates a standalone 256x1 palette texture for a player fur color and returns it.

texture is created on first use. Used for off-screen previews (e.g. the profile menu); in-game recoloring uses AcquirePaletteOffset instead. Returns nullptr in headless mode.

Texture* Jazz2::ContentResolver::GetPaletteTexture()

Returns the shared 256x256 palette texture, uploading any rows changed since the last call.

Row 0 is the sprite palette, rows 1-2 the gems, rows FirstDynamicPaletteRow+ the dynamically allocated per-player palettes. Bound to texture unit 1 for palette shaders. Returns nullptr in headless mode. Indexed sprites that must keep their original colors sample row 0 (the default palette) via a palette offset of 0.

std::int32_t Jazz2::ContentResolver::AcquirePaletteOffset(std::uint32_t furColor)

Acquires a reference-counted palette offset for the given packed fur color.

The offset is the flat offset into the shared palette texture, passed to ActorBase::ActorRenderer::SetPalette and the palette-aware shaders. Callers with the same fur color share one palette (so e.g. many corpses of the same character cost a single row); the recolored palette is built on first use. Returns the offset, or -1 if none are free. Release it with ReleasePaletteOffset when the holder disconnects/despawns.

void Jazz2::ContentResolver::ReleasePaletteOffset(std::int32_t paletteOffset)

Releases one reference to a palette offset from AcquirePaletteOffset.

The underlying palette is returned to the pool only when the last holder releases it.

bool Jazz2::ContentResolver::ConfigureSpriteShader(RenderCommand& command, bool indexed)

Configures a manually-built render command for a (possibly indexed) sprite.

Selects the PrecompiledShader::PaletteRemap shader when indexed (recolored at draw time via the shared palette), else the plain Sprite program. When the shader changes it also reserves uniform memory, sets triangle-strip draw params, and points the diffuse/palette samplers at units 0/1. Returns whether the shader changed (use it to gate one-time per-command setup). For game-world graphics drawn outside the standard ActorRenderer.

void Jazz2::ContentResolver::BindSpritePalette(RenderCommand& command, GLUniformBlockCache& instanceBlock, const Texture& diffuse, bool indexed, std::uint16_t paletteOffset)

Binds the diffuse (and, when indexed, the palette) textures for a sprite render command.

Binds diffuse to texture unit 0 and, when indexed, the shared palette texture to unit 1 plus the per-instance palette offset on instanceBlock. Call at draw time, after the other instance uniforms.

std::unique_ptr<Tiles::TileSet> Jazz2::ContentResolver::RequestTileSet(StringView path, std::uint16_t captionTileId, bool applyPalette, const std::uint8_t* paletteRemapping = nullptr)

Loads specified tile set and its palette.

Parameters
path Relative path to the tile set
captionTileId Tile used to render the level-preview caption thumbnail
applyPalette Apply the tile set's palette to the live sprite palette
paletteRemapping Optional 256-entry table remapping each tile's palette indices

void Jazz2::ContentResolver::SetSpritePalette(ArrayView<const std::uint32_t> palette)

Overrides the active sprite palette (row 0 of the shared palette).

Takes up to ColorsPerPalette packed colors (0xAABBGGRR) and refreshes everything derived from it (gem gradients and per-player recolor rows), so the change takes effect on the next frame. No visible effect in headless mode.

Variable documentation

static std::int32_t Jazz2::ContentResolver::FirstDynamicPaletteRow constexpr

First shared-palette row available for dynamic per-player allocation.

Lower rows are reserved for the sprite palette (row 0) and the generated gem palettes (rows 1-2).

static std::int32_t Jazz2::ContentResolver::FurSectionCount constexpr

Number of recolorable fur sections.

How a player's 4-byte fur color maps to recolored palette sections

The fur color is 4 bytes, one per section (as in the original game). The low 7 bits of each byte are the starting palette index of an 8-color gradient in the sprite palette; those 8 colors are copied into the section's fixed range in the per-player palette (a byte of 0 keeps the original colors for that section). If FurHueShiftFlag is also set, the gradient's hue is rotated by HueShiftDegreesForGradient first (see ShiftHue), which roughly doubles the selectable color variants without extra gradients in the palette.

static std::uint8_t Jazz2::ContentResolver::FurHueShiftFlag constexpr

High bit of a fur section byte requesting its gradient be hue-shifted by HueShiftDegreesForGradient.

The low 7 bits stay the gradient start index (gradient starts never exceed 0x58, so this bit is always free)