Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions fission/src/Synthesis.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { AnimatePresence } from "framer-motion"
// <<<<<<< HEAD
// import type React from "react"
// import { type ReactElement, useCallback, useEffect, useRef, useState } from "react"
// =======
import { SnackbarProvider } from "notistack"
import { useCallback, useEffect, useRef, useState } from "react"
import MainHUD from "@/components/MainHUD"
Expand All @@ -14,6 +18,7 @@ import { globalOpenModal } from "./ui/components/GlobalUIControls.ts"
import ProgressNotifications from "./ui/components/ProgressNotification.tsx"
import SceneOverlay from "./ui/components/SceneOverlay.tsx"
import WPILibConnectionStatus from "./ui/components/WPILibConnectionStatus.tsx"
import { applyInitialGraphicsSettings } from "./ui/helpers/GraphicsSettings.ts"
import MainMenuModal from "./ui/modals/MainMenuModal.tsx"
import { StateProvider } from "./ui/StateProvider.tsx"
import { ThemeProvider } from "./ui/ThemeProvider.tsx"
Expand All @@ -34,6 +39,8 @@ function Synthesis() {
const startSingleplayerCallback = () => {
World.initWorld()

applyInitialGraphicsSettings()

if (!PreferencesSystem.getGlobalPreference("ReportAnalytics") && !import.meta.env.DEV) {
setConsentPopupDisable(false)
}
Expand Down
2 changes: 2 additions & 0 deletions fission/src/systems/preferences/PreferenceTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type GlobalPreferences = {
MuteAllSound: boolean
SFXVolume: number
ShowCenterOfMassIndicators: boolean
GraphicsOptimizationApplied: boolean
}

export type GlobalPreference = keyof GlobalPreferences
Expand Down Expand Up @@ -66,6 +67,7 @@ export const defaultGlobalPreferences: GlobalPreferences = {
MuteAllSound: false,
SFXVolume: 25,
ShowCenterOfMassIndicators: false,
GraphicsOptimizationApplied: false,
}

export type GraphicsPreferences = {
Expand Down
110 changes: 110 additions & 0 deletions fission/src/ui/helpers/GraphicsSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import PreferencesSystem from "@/systems/preferences/PreferencesSystem"
import { globalAddToast } from "@/ui/components/GlobalUIControls"

export type GraphicsPreset = "Fast" | "Balanced" | "Fancy"

export const GRAPHICS_PRESETS: Record<
GraphicsPreset,
{
lightIntensity: number
fancyShadows: boolean
maxFar: number
cascades: number
shadowMapSize: number
antiAliasing: boolean
}
> = {
Fast: {
lightIntensity: 3.5,
fancyShadows: false,
maxFar: 20,
cascades: 3,
shadowMapSize: 1024,
antiAliasing: false,
},
Balanced: {
lightIntensity: 5,
fancyShadows: true,
maxFar: 30,
cascades: 4,
shadowMapSize: 2048,
antiAliasing: false,
},
Fancy: {
lightIntensity: 8,
fancyShadows: true,
maxFar: 40,
cascades: 6,
shadowMapSize: 8192,
antiAliasing: true,
},
}

export const isMobileDevice = (): boolean => {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
}

export const isLowEndDevice = (): boolean => {
if (isMobileDevice()) return true

const memory =
typeof navigator !== "undefined" && "deviceMemory" in navigator
? (navigator as Navigator & { deviceMemory?: number }).deviceMemory
: undefined
if (memory !== undefined && memory <= 4) return true // 4GB or less RAM

const cores = navigator.hardwareConcurrency
if (cores && cores <= 2) return true // 2 cores or less

const userAgent = navigator.userAgent.toLowerCase()
if (userAgent.includes("android") && (userAgent.includes("lite") || userAgent.includes("go"))) return true

return false
}

export const autoOptimizeGraphics = (toastType: "long" | "short" | "none" = "none"): GraphicsPreset => {
if (isLowEndDevice()) {
if (toastType === "long") {
globalAddToast?.(
"info",
"Graphics Optimized",
"We've set your graphics to 'Fast' mode for optimal performance on your device. You can change this in Graphics Settings."
)
} else if (toastType === "short") {
globalAddToast?.("info", "Success", "Auto-optimized graphics to 'Fast'.")
}
return "Fast"
} else {
if (toastType === "long") {
globalAddToast?.(
"info",
"Graphics Optimized",
"We've set your graphics to 'Balanced' mode for optimal performance on your device. You can change this in Graphics Settings."
)
} else if (toastType === "short") {
globalAddToast?.("info", "Success", "Auto-optimized graphics to 'Balanced'.")
}
return "Balanced"
}
}

export const applyInitialGraphicsSettings = (): void => {
// Check if graphics optimization has already been applied
const optimizationApplied = PreferencesSystem.getGlobalPreference("GraphicsOptimizationApplied")

// If optimization hasn't been applied yet and device should use fast mode, apply fast settings
if (!optimizationApplied) {
const presetToApply = autoOptimizeGraphics("long")
const settings = GRAPHICS_PRESETS[presetToApply]
PreferencesSystem.getGraphicsPreferences().lightIntensity = settings.lightIntensity
PreferencesSystem.getGraphicsPreferences().fancyShadows = settings.fancyShadows
PreferencesSystem.getGraphicsPreferences().maxFar = settings.maxFar
PreferencesSystem.getGraphicsPreferences().cascades = settings.cascades
PreferencesSystem.getGraphicsPreferences().shadowMapSize = settings.shadowMapSize
PreferencesSystem.getGraphicsPreferences().antiAliasing = settings.antiAliasing

// Mark that optimization has been applied
PreferencesSystem.setGlobalPreference("GraphicsOptimizationApplied", true)
PreferencesSystem.savePreferences()
}
}
6 changes: 4 additions & 2 deletions fission/src/ui/modals/configuring/SettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ const SettingsModal: React.FC<ModalImplProps<void, void>> = ({ modal }) => {
SoundPlayer.changeVolume()
}

configureScreen(modal!, { title: "Settings", allowClickAway: false }, { onBeforeAccept: save, onCancel })
}, [modal, save])
if (modal) {
configureScreen(modal, { title: "Settings", allowClickAway: false }, { onBeforeAccept: save, onCancel })
}
}, [modal, save, configureScreen])

const writePreference = <K extends GlobalPreference>(pref: K, value: GlobalPreferences[K]) => {
PreferencesSystem.setGlobalPreference(pref, value)
Expand Down
Loading
Loading