/* * Settings.cs * Authors: Adam Nabinger * Copyright (c) 2007-2008 Cornell University This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ using System; using System.Collections.Generic; using Microsoft.Xna.Framework.Graphics; namespace MaritimeDefender { /// /// Holder for 'const' values that are loaded from the config files at run time. /// public static class Settings { #region Constants // Constant for how many degrees exist in a squared radian private const double DegreesPerRadiansSquared = (180d / Math.PI) * (180d / Math.PI); #endregion #region Fields // The number of dots that will appear on the screen at one time during the dot coherence phase private static int numberDots; // The amount of dots that appear at one time per square radian during the dot coherence phase private static double dotsPerSquareRadian; // The diameter of the dots in the dot phase private static double dotDiameter; // The speed of the dots in the dot phase private static double dotSpeed; // The lifespan of the dots in the dot phase private static double dotLifeSpan; // The time between trials with a small amount of randomized jitter private static double dotRefreshDelay; // The randomized jitter added to the amount of time between trials private static double dotRefreshDelayJitter; // The time period in which late responses are still acceptable after a trial has ended private static double dotResponseWait; // The average length of a dot test trial private static double mDotTrialLength; // The amount of length between 0 and this value to be added to the dot trial length private static double mDotTrialJitter; // Whether or not the dot coherence trials should sometimes be non coherent private static bool mHaveNonCoherentTrials; internal static double mPsychophysicalSigmoidScale; internal static double mDotTrialIncorrectIgnoreThreshold; // The queue of phases used for the game progression of Maritime Defender private static MaritimeDefenderTest[] phaseQueue; #endregion #region Properties /// /// Gets the queue of phases used for the game progression of Maritime Defender /// public static Queue PhaseQueue { get { Queue ret = new Queue(); foreach (MaritimeDefenderTest test in phaseQueue) { ret.Enqueue(test); } return ret; } } /// /// Sets the number of dots per radian in the dot coherence phase /// public static double DotsPerRadian { set { dotsPerSquareRadian = value * (4 / Math.PI); } } /// /// Sets the number of dots per radian in the dot coherence phase /// public static double DotsPerDegree { set { DotsPerSquareDegree = value * (4 / Math.PI); } } /// /// Gets/Sets the amount of dots that appear at one time per square radian during the dot coherence phase /// public static double DotsPerSquareRadian { get { return dotsPerSquareRadian; } set { dotsPerSquareRadian = value; } } /// /// Gets/Sets the amount of dots that appear at one time per square degree during the dot coherence phase /// public static double DotsPerSquareDegree { get { return dotsPerSquareRadian / DegreesPerRadiansSquared; } set { dotsPerSquareRadian = value * DegreesPerRadiansSquared; } } /// /// Gets/sets the diameter of Meteor Madness dots in screen percentage at mid-depth /// public static double DotDiameter { get { return Math.Tan(dotDiameter) * Util.Settings.PhysicalScreenDistance / Util.Settings.PhysicalScreenWidth; } set { dotDiameter = value; } } /// /// Gets/sets the speed that the dots move in the dot phase of meteor madness (arbitrary units) /// public static double DotSpeed { get { return Math.Tan(dotSpeed) * Util.Settings.PhysicalScreenDistance / Util.Settings.PhysicalScreenWidth; } set { dotSpeed = value; } } /// /// Gets/sets the lifespan (in seconds) of the dots in the dot phase of meteor madness /// public static double DotLifeSpan { get { return dotLifeSpan; } set { dotLifeSpan = value; } } /// /// Gets/sets the time before a dot trial resets coherence after a user response /// public static double DotRefreshDelay { get { return dotRefreshDelay; } set { dotRefreshDelay = value; } } /// /// Gets/sets the random amount of jitter that will be added between 0 and value to the refresh delay. /// public static double DotRefreshDelayJitter { get { return dotRefreshDelayJitter; } set { dotRefreshDelayJitter = value; } } /// /// Gets/sets the period of time in which late responses are accepted after a trial ends /// public static double DotResponseWait { get { return dotResponseWait; } set { dotResponseWait = value; } } /// /// Gets/sets the average length of a dot test trial /// public static double DotTrialLength { get { return mDotTrialLength; } set { mDotTrialLength = value; } } /// /// Gets/sets the amount of length between 0 and this value to be added to the dot trial length /// public static double DotTrialJitter { get { return mDotTrialJitter; } set { mDotTrialJitter = value; } } /// /// Gets/sets the number of dots that appear at one time on screen during the dot coherence phase /// public static int NumberDots { get { return numberDots; } set { numberDots = value; } } /// /// Gets/sets whether or not the dot coherence phase contains non coherent trials /// public static bool HaveNonCoherentTrials { get { return mHaveNonCoherentTrials; } set { mHaveNonCoherentTrials = value; } } public static double PsychophysicalSigmoidScale { get { return mPsychophysicalSigmoidScale; } set { mPsychophysicalSigmoidScale = value; } } public static double DotTrialIncorrectIgnoreThreshold { get { return mDotTrialIncorrectIgnoreThreshold; } set { mDotTrialIncorrectIgnoreThreshold = value; } } #endregion #region Getters /// /// Calculates the amount of dots that need to appear on the screen at one time. /// This is used for the dot coherence test phase. /// /// Reference to the current graphics device for visual information /// The number of dots to appear on screen at one time. public static int GetNumberDots(GraphicsDevice graphicsDevice) { if (numberDots > 0) { return numberDots; } // How much space on the actual display is taken up by the window double WindowDisplayWidth = Util.Settings.PhysicalScreenWidth * (graphicsDevice.Viewport.Width / (double)graphicsDevice.DisplayMode.Width); double WindowDisplayHeight = Util.Settings.PhysicalScreenHeight * (graphicsDevice.Viewport.Height / (double)graphicsDevice.DisplayMode.Height); // visual angle occupied by the display (in radians) double horizontal = Math.Atan2(WindowDisplayWidth, Util.Settings.PhysicalScreenDistance); double vertical = Math.Atan2(WindowDisplayHeight, Util.Settings.PhysicalScreenDistance); return (int)Math.Round(DotsPerSquareRadian * horizontal * vertical, MidpointRounding.AwayFromZero); } #endregion #region Setters /// /// Creates a new phase queue or overwrites an existing phase queue for a specific minigame. /// Invalid data may not be caught until that minigame attempts to use it. /// /// The number of parameters for the specific minigame's test constructor (usually 2; phaseName, trials) /// A comma-seperated list of each phase parameter in order. ie: phaseParams = "PhaseTypeA, 1, PhaseTypeB, 5, PhaseTypeA, 2, ... public static void SetPhaseQueue(int phaseParamStride, string phaseParams) { // Split the phaseParams into an array string[] paramArray = phaseParams.Split(','); // Do some basic validation on the phase queue if (paramArray.Length < phaseParamStride) { System.Windows.Forms.MessageBox.Show("Malformed phase queue in config file for game: " + MaritimeDefenderInfo.Name + ". Phase queue must contain at least 1 test phase.", "Fatal Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } if (paramArray.Length % phaseParamStride != 0) { System.Windows.Forms.MessageBox.Show("Malformed phase queue in config file for game: " + MaritimeDefenderInfo.Name + ". Phase parameters do not agree with phase parameter stride.", "Fatal Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } // Generate a new phase queue phaseQueue = new MaritimeDefenderTest[paramArray.Length / phaseParamStride]; // Generate each test and then add it to the phaseQueue for (int i = 0; i < paramArray.Length; i += phaseParamStride) { // Get name and trials MaritimeDefenderTest test = new MaritimeDefenderTest(paramArray[i].Trim(), int.Parse(paramArray[i + 1].Trim()), null); // Get remaining params for (int j = 2; j < phaseParamStride; j++) { test.SpecificParameters.Add(paramArray[j].Trim()); } phaseQueue[i / phaseParamStride] = test; } } /// /// Sets the number of dots per square radian in the dot coherence phase to the given value /// /// The desired amount of dots per square radian public static void SetNumDotsPerSquareRadian(double value) { dotsPerSquareRadian = value; } /// /// Sets the number of dots per square degree in the dot coherence phase to the given value /// /// The desired amount of dots per square degree public static void SetNumDotsPerSquareDegree(double value) { dotsPerSquareRadian = value * DegreesPerRadiansSquared; } #endregion } }