{-# OPTIONS_GHC -fno-warn-tabs #-} -- Support tab indentation better, for a better default of no warning if tabs are used: https://dmitryfrank.com/articles/indent_with_tabs_align_with_spaces . -- Enable warnings: {-# OPTIONS_GHC -Wall -fno-warn-tabs #-} -- State.hs. {-# LANGUAGE Haskell2010 #-} {-# LANGUAGE TemplateHaskell #-} module Immutaball.Share.Config ( StaticConfig'(..), minClockPeriod, maxClockPeriod, maxFrameEvents, allowWireForks, maxStepFrameSize, maxResponseFrameSize, defaultStaticDataDir, defaultUserDataDir, defaultUserConfigDir, configFilename, x'cfgInitialWireWithCxt, immutaballFont, immutaballFontSize, sdlManagerStaticConfig, glManagerStaticConfig, x'cfgUseExistingSDLManager, x'cfgUseExistingGLManager, x'cfgMaxPassTextures, x'cfgPrecacheMtrls, x'cfgPrecacheMisc, x'cfgBallTriangles, x'cfgDebugFreeCamera, x'cfgVertUpKey, x'cfgVertDownKey, x'cfgFreeCameraToggleKey, x'glNearVal, x'glFarVal, x'cfgDepthScale, x'cfgViewCollapse, x'cfgCameraDistance, x'cfgCameraRaisedCircles, x'cfgMaxTilt, x'cfgGravity, x'cfgBounceReturn, x'cfgMaxFrameCollisions, x'cfgMaxFrameCollisionsDtThreshold, x'cfgMaxFrameCollisionsRDistanceThreshold, x'cfgMaxPhysicsStepTime, x'cfgRequestAlternativePhysics, defaultStaticConfig, Neverballrc, Config(..), fullscreen, display, width, height, stereo, camera, textures, reflection, multisample, mipmap, aniso, background, shadow, audioBuff, mouseSense, mouseResp, mouseInvert, mouseVsync, hmd, highdpi, mouseCamera1, mouseCamera2, mouseCameraToggle, mouseCameraL, mouseCameraR, nice, fps, soundVolume, musicVolume, joystick, joystickResp, joystickAxisX0, joystickAxisY0, joystickAxisX1, joystickAxisY1, joystickAxisX0Invert, joystickAxisY0Invert, joystickAxisX1Invert, joystickAxisY1Invert, joystickButtonA, joystickButtonB, joystickButtonX, joystickButtonY, joystickButtonL1, joystickButtonL2, joystickButtonR1, joystickButtonR2, joystickButtonSelect, joystickButtonStart, joystickDpadL, joystickDpadR, joystickDpadU, joystickDpadD, wiimoteInvertPitch, wiimoteInvertRoll, wiimotePitchSens, wiimoteRollSense, wiimoteSmoothAlpha, wiimoteHoldSideways, keyCamera1, keyCamera2, keyCamera3, keyCameraToggle, keyCameraR, keyCameraL, keyForward, keyBackward, keyLeft, keyRight, keyRestart, keyScoreNext, keyRotateFast, viewFov, viewDp, viewDc, viewDz, rotateFast, rotateSlow, cheat, stats, screenshot, lockGoals, camera1Speed, camera2Speed, camera3Speed, cameraTouchRotate, player, ballFile, wiimoteAddr, replayName, language, theme, defaultConfig ) where import Prelude () import Immutaball.Prelude import Control.Lens import qualified SDL.Raw.Enum as Raw import Immutaball.Share.ImmutaballIO.DirectoryIO import Immutaball.Share.GLManager import Immutaball.Share.GLManager.Config import Immutaball.Share.Math (tau) import Immutaball.Share.SDLManager import Immutaball.Share.SDLManager.Config data StaticConfig' initialWireWithCxt = StaticConfig { -- | Maximum FPS, including non-clock SDL events. _minClockPeriod :: Maybe Double, -- | If at least one non-clock event has been stepped, if more SDL -- events are available, delay processing those events if at least this -- much time has passed. This might also be known as ‘maxEventPeriod’ with -- respect to clock steps. _maxClockPeriod :: Maybe Double, -- | If a single frame has more than this limit events, drop all after the -- first limit tunmber. _maxFrameEvents :: Maybe Integer, -- | Drop step requests after this many requests if they are all given -- at once. Also do not send more than this many requests in one step. _maxStepFrameSize :: Maybe Integer, -- | Drop step responses after this many responses if they are all -- at once. Also do not send more than this many responses in one -- step. The wire may opt to priority queue responses exceeding the -- capacity if there's a response it doesn't want to drop. _maxResponseFrameSize :: Maybe Integer, _allowWireForks :: Bool, _defaultStaticDataDir :: Either (DirectoryIOF FilePath) FilePath, _defaultUserDataDir :: Either (DirectoryIOF FilePath) FilePath, _defaultUserConfigDir :: Either (DirectoryIOF FilePath) FilePath, _configFilename :: FilePath, _x'cfgInitialWireWithCxt :: Maybe initialWireWithCxt, -- | Relative to the static data dir. _immutaballFont :: FilePath, _immutaballFontSize :: Integer, -- | Use separate records to allow these modules to have their own static -- config. _sdlManagerStaticConfig :: SDLManagerStaticConfig, _glManagerStaticConfig :: GLManagerStaticConfig, -- | Allow tests to share a single manager. _x'cfgUseExistingSDLManager :: Maybe SDLManagerHandle, _x'cfgUseExistingGLManager :: Maybe GLManagerHandle, -- | How many textures can we use at once in a single call to -- 'glDrawElements'? _x'cfgMaxPassTextures :: Integer, -- | Request a thread is spawned in the background to precache Mtrl. _x'cfgPrecacheMtrls :: Bool, -- | Request a thread is spawned in the background to do misc precaching -- when setting up allocated textures. _x'cfgPrecacheMisc :: Bool, _x'cfgBallTriangles :: Integer, -- | Whether to allow entering debug free camera mode. _x'cfgDebugFreeCamera :: Bool, -- | Debug free camera: move vertically up and down (e.g. spacebar and c as in jump and crouch). _x'cfgVertUpKey :: Int, _x'cfgVertDownKey :: Int, _x'cfgFreeCameraToggleKey :: Int, -- | OpenGL without extensions unfortunately doesn't support disabling -- clipping by the ‘y’ coordinate (which we swap with the ‘z’ coordinate -- for OpenGL depth, so we do this ourselves). So just set to a large -- value with 'glDepthRange'. The default values are 0 and 1. _x'glNearVal :: Double, _x'glFarVal :: Double, _x'cfgDepthScale :: Double, _x'cfgViewCollapse :: Bool, -- ^ Whether to use fovPure variant. -- | How far Playing camera is from the center of the ball. World units (which is 64 .map units). _x'cfgCameraDistance :: Double, -- | Pitch in radians times tau. By what angle (preserving distance) should the camera be raised relative to level with the ball? 1 circle is 360 degrees and also tau radians. _x'cfgCameraRaisedCircles :: Double, -- | Maximum tilt angle from neutral. _x'cfgMaxTilt :: Double, -- | How many meters per second squared is gravitational acceleration? _x'cfgGravity :: Double, -- | How much of the ball's velocity is kept on a collision? _x'cfgBounceReturn :: Double, -- | In a single frame, if the physics engine has already detected this -- many collisions without a threshold amount of dt being expended, give up -- and advance the frame. This handles the squish physics mechanic. _x'cfgMaxFrameCollisions :: Integer, -- | For the squish physics mechanic, how much time has to pass before -- resetting the collision counter. _x'cfgMaxFrameCollisionsDtThreshold :: Double, -- | If this much distance (in terms of ball radius) has passed, then also reset the collision counter. _x'cfgMaxFrameCollisionsRDistanceThreshold :: Double, -- | How far in time to step the physics world at a time, at most. -- We only need this because our simplistic physics doesn't properly model -- the curves of gravity, but instead adds a sudden burst of gravity onto -- the velocity each frame (or collision within a step within a frame), -- since without it the line approximations can make the ball get too much -- gravity at once, sending it flying. Already the ball is bouncy even -- with this, however, so TODO: improve the physics to fix the bouncy -- elevator/gravity problem. _x'cfgMaxPhysicsStepTime :: Maybe Double, -- | Allow runtime configuration of the choice of physics engine. _x'cfgRequestAlternativePhysics :: Maybe String } makeLenses ''StaticConfig' -- | Default static config. defaultStaticConfig :: StaticConfig' a defaultStaticConfig = StaticConfig { _minClockPeriod = Just 0.001, -- ^ Max FPS: 1000. _maxClockPeriod = Just 0.5, -- ^ Don't let external events block the clock for more than 500ms. _maxFrameEvents = Nothing, _maxStepFrameSize = Just 8, -- ^ Don't request more than 8 at a time. _maxResponseFrameSize = Nothing, -- ^ Don't request more than 8 at a time. _allowWireForks = False, -- ^ Don't let immutaball signals fork. _defaultStaticDataDir = Right "./data", _defaultUserDataDir = Left $ GetXdgDirectoryDataSync "immutaball" id, _defaultUserConfigDir = Left $ GetXdgDirectoryConfigSync "immutaball" id, _configFilename = "neverballrc", _x'cfgInitialWireWithCxt = Nothing, _immutaballFont = "ttf/DejaVuSans-Bold.ttf", _immutaballFontSize = 256, _sdlManagerStaticConfig = defaultSDLManagerStaticConfig, _glManagerStaticConfig = defaultGLManagerStaticConfig, _x'cfgUseExistingSDLManager = Nothing, _x'cfgUseExistingGLManager = Nothing, _x'cfgMaxPassTextures = 16, _x'cfgPrecacheMtrls = True, _x'cfgPrecacheMisc = True, _x'cfgBallTriangles = 8 * 64, -- 512 -- TODO disable again after debugging by setting to False: --_x'cfgDebugFreeCamera = False, _x'cfgDebugFreeCamera = True, _x'cfgVertUpKey = fromIntegral Raw.SDLK_SPACE, _x'cfgVertDownKey = fromIntegral Raw.SDLK_c, _x'cfgFreeCameraToggleKey = fromIntegral Raw.SDLK_f, _x'glNearVal = 0.0, _x'glFarVal = 9.99e35, _x'cfgDepthScale = 1.0e-6, _x'cfgViewCollapse = True, _x'cfgCameraDistance = 2.0, _x'cfgCameraRaisedCircles = (1/4) * (1/3), _x'cfgMaxTilt = (20.0/360.00) * tau, _x'cfgGravity = 9.8, _x'cfgBounceReturn = 0.7, _x'cfgMaxFrameCollisions = 1024, -- TODO: double check if you think this is a good value for this setting. _x'cfgMaxFrameCollisionsDtThreshold = 0.001, -- TODO: double check if you think this is a good value for this setting. _x'cfgMaxFrameCollisionsRDistanceThreshold = 10.0, -- TODO: double check if you think this is a good value for this setting. --_x'cfgMaxPhysicsStepTime = Just 0.01 -- Smooths out the gravity bounce issue, but larger levels can't handle it. --_x'cfgMaxPhysicsStepTime = Just 0.2 -- More tolerant, but e.g. retour de force for me would only handle this (or even Nothing) if I -- -- disabled edge and vertices by commenting out the 2 lines in the concat list. _x'cfgMaxPhysicsStepTime = Just 0.02, _x'cfgRequestAlternativePhysics = Nothing } type Neverballrc = Config data Config = Config { _fullscreen :: Bool, -- "fullscreen" False _display :: Int, -- "display" 0 _width :: Int, -- "width" 800 _height :: Int, -- "height" 600 _stereo :: Bool, -- "stereo" False _camera :: Int, -- "camera" 0 _textures :: Bool, -- "textures" True _reflection :: Bool, -- "reflection" True _multisample :: Bool, -- "multisample" False _mipmap :: Bool, -- "mipmap" True _aniso :: Int, -- "aniso" 8 _background :: Bool, -- "background" True _shadow :: Bool, -- "shadow" True _audioBuff :: Int, -- "audio_buff" 2048 _mouseSense :: Int, -- "mouse_sense" 444 _mouseResp :: Int, -- "mouse_response" 50 _mouseInvert :: Bool, -- "mouse_invert" False _mouseVsync :: Bool, -- "vsync" True _hmd :: Bool, -- "hmd" False _highdpi :: Bool, -- "highdpi" True _mouseCamera1 :: Int, -- "mouse_camera_1" 0 _mouseCamera2 :: Int, -- "mouse_camera_1" 0 _mouseCameraToggle :: Int, -- "mouse_camera_toggle" 2 -- SDL_BUTTON_MIDDLE _mouseCameraL :: Int, -- "mouse_camera_l" 1 -- SDL_BUTTON_LEFT _mouseCameraR :: Int, -- "mouse_camera_r" 3 -- SDL_BUTTON_RIGHT _nice :: Int, -- "nice" 0 _fps :: Int, -- "fps" 0 _soundVolume :: Int, -- "sound_volume" 10 _musicVolume :: Int, -- "music_volume" 6 _joystick :: Bool, -- "joystick" True _joystickResp :: Int, -- "joystick_response" 50 _joystickAxisX0 :: Int, -- "joystick_axis_x0" 0 _joystickAxisY0 :: Int, -- "joystick_axis_x1" 1 _joystickAxisX1 :: Int, -- "joystick_axis_y0" 3 _joystickAxisY1 :: Int, -- "joystick_axis_y1" 4 _joystickAxisX0Invert :: Bool, -- "joystick_axis_x0" False _joystickAxisY0Invert :: Bool, -- "joystick_axis_x1" False _joystickAxisX1Invert :: Bool, -- "joystick_axis_y0" False _joystickAxisY1Invert :: Bool, -- "joystick_axis_y1" False _joystickButtonA :: Int, -- "joystick_button_a" 0 _joystickButtonB :: Int, -- "joystick_button_b" 1 _joystickButtonX :: Int, -- "joystick_button_x" 2 _joystickButtonY :: Int, -- "joystick_button_y" 3 _joystickButtonL1 :: Int, -- "joystick_button_l1" 4 _joystickButtonL2 :: Int, -- "joystick_button_r1" 5 _joystickButtonR1 :: Int, -- "joystick_button_l2" -1 _joystickButtonR2 :: Int, -- "joystick_button_r2" -1 _joystickButtonSelect :: Int, -- "joystick_button_select" 6 _joystickButtonStart :: Int, -- "joystick_button_start" 7 _joystickDpadL :: Int, -- "joystick_dpad_l" 8 _joystickDpadR :: Int, -- "joystick_dpad_r" 9 _joystickDpadU :: Int, -- "joystick_dpad_u" 10 _joystickDpadD :: Int, -- "joystick_dpad_d" 11 _wiimoteInvertPitch :: Bool, -- "wiimote_invert_pitch" False _wiimoteInvertRoll :: Bool, -- "wiimote_invert_roll" False _wiimotePitchSens :: Int, -- "wiimote_pitch_sensitivity" 100 _wiimoteRollSense :: Int, -- "wiimote_roll_sensitivity" 100 _wiimoteSmoothAlpha :: Int, -- "wiimote_smooth_alpha" 50 _wiimoteHoldSideways :: Bool, -- "wiimote_hold_sideways" False _keyCamera1 :: Int, -- "key_camera_1" 0x31 -- SDLK_1 _keyCamera2 :: Int, -- "key_camera_2" 0x32 -- SDLK_2 _keyCamera3 :: Int, -- "key_camera_3" 0x33 -- SDLK_3 _keyCameraToggle :: Int, -- "key_camera_toggle" 0x65 -- SDLK_e _keyCameraR :: Int, -- "key_camera_r" 0x64 -- SDLK_d _keyCameraL :: Int, -- "key_camera_l" 0x6C -- SDLK_s _keyForward :: Int, -- "key_forward" 0x40000052 -- SDLK_UP _keyBackward :: Int, -- "key_backward" 0x40000051 -- SDLK_DOWN _keyLeft :: Int, -- "key_left" 0x40000050 -- SDLK_LEFT _keyRight :: Int, -- "key_right" 0x4000004F -- SDLK_RIGHT _keyRestart :: Int, -- "key_restart" 0x72 -- SDLK_r _keyScoreNext :: Int, -- "key_score_next" 0x09 -- SDLK_TAB _keyRotateFast :: Int, -- "key_rotate_fast" 0x400000E1 -- SDLK_LSHIFT _viewFov :: Int, -- "view_fov" 50 _viewDp :: Int, -- "view_dp" 75 _viewDc :: Int, -- "view_dc" 25 _viewDz :: Int, -- "view_dz" 200 _rotateFast :: Int, -- "rotate_fast" 300 _rotateSlow :: Int, -- "rotate_slow" 300 _cheat :: Bool, -- "cheat" False _stats :: Bool, -- "stats" False _screenshot :: Bool, -- "screenshot" False _lockGoals :: Bool, -- "lock_goals" True _camera1Speed :: Int, -- "camera_1_speed" 250 _camera2Speed :: Int, -- "camera_2_speed" 0 _camera3Speed :: Int, -- "camera_3_speed" -1 _cameraTouchRotate :: Int, -- "touch_rotate" 16 _player :: String, -- "player" "" _ballFile :: String, -- "ball_file" "ball/basic-ball/basic-ball" _wiimoteAddr :: String, -- "wiimote_addr" "" _replayName :: String, -- "replay_name" "%s-%l" _language :: String, -- "language" "" _theme :: String -- "theme" "classic" } deriving (Eq, Ord, Show) makeLenses ''Config defaultConfig :: Config defaultConfig = Config { _fullscreen = False, _display = 0, _width = 800, _height = 600, _stereo = False, _camera = 0, _textures = True, _reflection = True, _multisample = False, _mipmap = True, _aniso = 8, _background = True, _shadow = True, _audioBuff = 2048, _mouseSense = 444, _mouseResp = 50, _mouseInvert = False, _mouseVsync = True, _hmd = False, _highdpi = True, _mouseCamera1 = 0, _mouseCamera2 = 0, _mouseCameraToggle = 2, -- SDL_BUTTON_MIDDLE _mouseCameraL = 1, -- SDL_BUTTON_LEFT _mouseCameraR = 3, -- SDL_BUTTON_RIGHT _nice = 0, _fps = 0, _soundVolume = 10, _musicVolume = 6, _joystick = True, _joystickResp = 50, _joystickAxisX0 = 0, _joystickAxisY0 = 1, _joystickAxisX1 = 3, _joystickAxisY1 = 4, _joystickAxisX0Invert = False, _joystickAxisY0Invert = False, _joystickAxisX1Invert = False, _joystickAxisY1Invert = False, _joystickButtonA = 0, _joystickButtonB = 1, _joystickButtonX = 2, _joystickButtonY = 3, _joystickButtonL1 = 4, _joystickButtonL2 = 5, _joystickButtonR1 = -1, _joystickButtonR2 = -1, _joystickButtonSelect = 6, _joystickButtonStart = 7, _joystickDpadL = 8, _joystickDpadR = 9, _joystickDpadU = 10, _joystickDpadD = 11, _wiimoteInvertPitch = False, _wiimoteInvertRoll = False, _wiimotePitchSens = 100, _wiimoteRollSense = 100, _wiimoteSmoothAlpha = 50, _wiimoteHoldSideways = False, _keyCamera1 = 0x31, -- SDLK_1 _keyCamera2 = 0x32, -- SDLK_2 _keyCamera3 = 0x33, -- SDLK_3 _keyCameraToggle = 0x65, -- SDLK_e _keyCameraR = 0x64, -- SDLK_d _keyCameraL = 0x6C, -- SDLK_s _keyForward = 0x40000052, -- SDLK_UP _keyBackward = 0x40000051, -- SDLK_DOWN _keyLeft = 0x40000050, -- SDLK_LEFT _keyRight = 0x4000004F, -- SDLK_RIGHT _keyRestart = 0x72, -- SDLK_r _keyScoreNext = 0x09, -- SDLK_TAB _keyRotateFast = 0x400000E1, -- SDLK_LSHIFT _viewFov = 50, _viewDp = 75, _viewDc = 25, _viewDz = 200, _rotateFast = 300, _rotateSlow = 300, _cheat = False, _stats = False, _screenshot = False, _lockGoals = True, _camera1Speed = 250, _camera2Speed = 0, _camera3Speed = -1, _cameraTouchRotate = 16, _player = "", _ballFile = "ball/basic-ball/basic-ball", _wiimoteAddr = "", _replayName = "%s-%l", _language = "", _theme = "classic" } -- TODO: print and parse.