110 lines
3.5 KiB
Rust
110 lines
3.5 KiB
Rust
//! Shared native launch configuration for the game and in-process editor.
|
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
use bevy::app::PluginGroupBuilder;
|
|
use bevy::asset::AssetPlugin;
|
|
use bevy::log::{LogPlugin, DEFAULT_FILTER};
|
|
use bevy::prelude::*;
|
|
use bevy::window::{CompositeAlphaMode, PresentMode, WindowMode, WindowPlugin};
|
|
|
|
/// Runtime switch for the HDR camera pass.
|
|
///
|
|
/// Set to `0`, `false`, `off`, or `no` to force the game/editor cameras through
|
|
/// the SDR path when debugging mixed HDR/SDR compositor issues.
|
|
pub const HDR_ENV_VAR: &str = "BEVY_FPS_HDR";
|
|
|
|
/// Locates the workspace `assets/` folder when the binary lives under `target/`.
|
|
pub fn resolve_assets_directory() -> String {
|
|
if let Some(path) = find_assets_directory(std::env::current_dir().ok()) {
|
|
return path;
|
|
}
|
|
if let Ok(exe) = std::env::current_exe() {
|
|
let mut dir = exe.parent().map(Path::to_path_buf);
|
|
while let Some(current) = dir {
|
|
if let Some(path) = find_assets_directory(Some(current.clone())) {
|
|
return path;
|
|
}
|
|
dir = current.parent().map(Path::to_path_buf);
|
|
}
|
|
}
|
|
"assets".into()
|
|
}
|
|
|
|
fn find_assets_directory(start: Option<PathBuf>) -> Option<String> {
|
|
let start = start?;
|
|
let assets = start.join("assets");
|
|
assets
|
|
.is_dir()
|
|
.then(|| assets.to_string_lossy().replace('\\', "/"))
|
|
}
|
|
|
|
pub fn default_plugins(title: impl Into<String>) -> PluginGroupBuilder {
|
|
DefaultPlugins
|
|
.set(LogPlugin {
|
|
// Blacksite intentionally replaces Bevy's `.scn.ron` loader with a
|
|
// schema-aware loader. Keep the expected registration warning out
|
|
// of normal startup logs; RUST_LOG still overrides this filter.
|
|
filter: format!("{DEFAULT_FILTER}bevy_asset::server::loaders=error"),
|
|
..default()
|
|
})
|
|
.set(WindowPlugin {
|
|
primary_window: Some(primary_window(title)),
|
|
..default()
|
|
})
|
|
.set(AssetPlugin {
|
|
file_path: resolve_assets_directory(),
|
|
..default()
|
|
})
|
|
}
|
|
|
|
pub fn primary_window(title: impl Into<String>) -> Window {
|
|
Window {
|
|
title: title.into(),
|
|
name: Some("bevy-fps-foundation".into()),
|
|
present_mode: PresentMode::AutoVsync,
|
|
mode: WindowMode::Windowed,
|
|
transparent: false,
|
|
// Force an opaque surface. On Wayland/Hyprland the default `Auto` mode
|
|
// can select an alpha-respecting surface, which may composite the whole
|
|
// window as transparent on SDR outputs in mixed HDR/SDR setups.
|
|
composite_alpha_mode: CompositeAlphaMode::Opaque,
|
|
..default()
|
|
}
|
|
}
|
|
|
|
pub fn hdr_enabled_from_env() -> bool {
|
|
std::env::var(HDR_ENV_VAR)
|
|
.map(|value| {
|
|
!matches!(
|
|
value.trim().to_ascii_lowercase().as_str(),
|
|
"0" | "false" | "off" | "no"
|
|
)
|
|
})
|
|
.unwrap_or(true)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::{primary_window, resolve_assets_directory};
|
|
use bevy::window::CompositeAlphaMode;
|
|
|
|
#[test]
|
|
fn primary_window_is_opaque() {
|
|
let window = primary_window("test");
|
|
|
|
assert!(!window.transparent);
|
|
assert_eq!(window.composite_alpha_mode, CompositeAlphaMode::Opaque);
|
|
}
|
|
|
|
#[test]
|
|
fn resolve_assets_directory_finds_workspace_assets() {
|
|
let cwd = std::env::current_dir().expect("cwd");
|
|
let expected = cwd.join("assets");
|
|
if !expected.is_dir() {
|
|
return;
|
|
}
|
|
assert_eq!(resolve_assets_directory(), expected.to_string_lossy());
|
|
}
|
|
}
|