/*
* 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
}
}