<commit_before>//------------------------------------------------------------------------------
// Copyright (c) 2015-2017 John D. Haughton
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//------------------------------------------------------------------------------

#include "PLT/File.h"
#include "STB/SmallLex.h"
#include "STB/Oil.h"

namespace STB {

namespace OIL {

void Member::write(PLT::File& file, void* that) const
{
   file.print("   %s = ", name);

   if (elements > 1) file.print("{");

   for(size_t i=0; i<elements; ++i)
   {
      if (i > 0) file.print(", ");

      void* data = (uint8_t*)that + offset + size*i;

      switch(type)
      {
      case BOOL:
         file.print("%s", *(bool*)data ? "true" : "false");
         break;

      case SIGNED:
         switch(size)
         {
         case 1: file.print("%d",   *(int8_t*)data); break;
         case 2: file.print("%d",   *(int16_t*)data); break;
         case 4: file.print("%d",   *(int32_t*)data); break;
         case 8: file.print("%lld", *(int64_t*)data); break;
         default: assert(!"unexpected member size"); break;
         }
         break;

      case ENUM:
      case UNSIGNED:
      {
          bool hex = (flags & HEX) != 0;

             switch(size)
             {
             case 1: file.print(hex ? "0x%02x"    : "%u",   *(uint8_t*)data);  break;
             case 2: file.print(hex ? "0x%04x"    : "%u",   *(uint16_t*)data); break;
             case 4: file.print(hex ? "0x%08x"    : "%u",   *(uint32_t*)data); break;
             case 8: file.print(hex ? "0x%016llx" : "%llu", *(uint64_t*)data); break;
             default: assert(!"unexpected member size"); break;
             }
      }
      break;

      case FLOAT:
         switch(size)
         {
         case 4: file.print("%g", *(float*)data); break;
         case 8: file.print("%g", *(double*)data); break;
         default: assert(!"unexpected member size"); break;
         }
         break;
      }
   }

   if (elements > 1) file.print("}");

   file.print(";\n");
}

void ClassBase::write(PLT::File& file, void* that) const
{
   file.print("%s\n", name);
   file.print("{\n");

   for(const auto& member : member_list)
   {
      member.write(file, that);
   }

   file.print("}\n");
}

void ClassBase::write(void* that) const
{
   PLT::File file(name, "oil", "w");

   write(file, that);
}

bool Member::read(SmallLex& lex, void* that) const
{
   if (elements > 1)
   {
      if (!lex.match('{')) return false;
   }

   for(size_t i=0; i<elements; ++i)
   {
      if (i > 0)
      {
         if (!lex.match(',')) return false;
      }

      void* data = (uint8_t*)that + offset + size*i;

      switch(type)
      {
      case BOOL:
         if (lex.tryMatch("true"))
         {
            *(bool*)data = true;
         }
         else if (lex.tryMatch("false"))
         {
            *(bool*)data = false;
         }
         else
         {
            return lex.error("Expected boolean value");
         }
         break;

      case SIGNED:
      {
         if (!lex.matchSigned()) return false;
         int64_t value = strtoll(lex.getToken(), nullptr, 0);
         int64_t unused = value >> (size*8);
         if ((unused != 0) || (unused != -1))
         {
            return lex.error("signed integer value too big");
         }
         switch(size)
         {
         case 1: *(int8_t*)data = int8_t(value); break;
         case 2: *(int16_t*)data = int16_t(value); break;
         case 4: *(int32_t*)data = int32_t(value); break;
         case 8: *(int64_t*)data = value; break;
         }
      }
      break;

      case ENUM:
      case UNSIGNED:
      {
         if (!lex.matchUnsigned()) return false;
         uint64_t value = strtoll(lex.getToken(), nullptr, 0);
         uint64_t unused = value >> (size*8);
         if (unused != 0)
         {
            return lex.error("unsigned integer value too big");
         }
         switch(size)
         {
         case 1: *(uint8_t*)data = uint8_t(value); break;
         case 2: *(uint16_t*)data = uint32_t(value); break;
         case 4: *(uint32_t*)data = uint32_t(value); break;
         case 8: *(uint64_t*)data = value; break;
         }
      }
      break;

      case FLOAT:
      {
         if (!lex.matchFloat()) return false;
         double value = atof(lex.getToken());
         switch(size)
         {
         case 4: *(float*)data = float(value); break;
         case 8: *(double*)data = value; break;
         }
      }
      break;
      }
   }

   if (elements > 1)
   {
      if (!lex.match('}')) return false;
   }

   return true;
}

bool ClassBase::read(SmallLex& lex, void* that) const
{
   if (!lex.match(name)) return false;

   if (!lex.match('{')) return false;

   while(!lex.tryMatch('}'))
   {
      if (!lex.matchIdent()) return false;

      const Member* member = findMember(lex.getToken());
      if (member == nullptr) return lex.error("bad member name '%s'", lex.getToken());

      if (!lex.match('=')) return false;

      if (!member->read(lex, that)) return false;

      if (!lex.match(';')) return false;
   }

   return true;
}

bool ClassBase::read(void* that) const
{
   SmallLex lex(name, "oil");

   return read(lex, that);
}

} // namespace OIL

} // namespace STB
<commit_msg>Add missing cstdlib header<commit_after>//------------------------------------------------------------------------------
// Copyright (c) 2015-2017 John D. Haughton
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//------------------------------------------------------------------------------

#include "PLT/File.h"
#include "STB/SmallLex.h"
#include "STB/Oil.h"

#include <cstdlib>

namespace STB {

namespace OIL {

void Member::write(PLT::File& file, void* that) const
{
   file.print("   %s = ", name);

   if (elements > 1) file.print("{");

   for(size_t i=0; i<elements; ++i)
   {
      if (i > 0) file.print(", ");

      void* data = (uint8_t*)that + offset + size*i;

      switch(type)
      {
      case BOOL:
         file.print("%s", *(bool*)data ? "true" : "false");
         break;

      case SIGNED:
         switch(size)
         {
         case 1: file.print("%d",   *(int8_t*)data); break;
         case 2: file.print("%d",   *(int16_t*)data); break;
         case 4: file.print("%d",   *(int32_t*)data); break;
         case 8: file.print("%lld", *(int64_t*)data); break;
         default: assert(!"unexpected member size"); break;
         }
         break;

      case ENUM:
      case UNSIGNED:
      {
          bool hex = (flags & HEX) != 0;

             switch(size)
             {
             case 1: file.print(hex ? "0x%02x"    : "%u",   *(uint8_t*)data);  break;
             case 2: file.print(hex ? "0x%04x"    : "%u",   *(uint16_t*)data); break;
             case 4: file.print(hex ? "0x%08x"    : "%u",   *(uint32_t*)data); break;
             case 8: file.print(hex ? "0x%016llx" : "%llu", *(uint64_t*)data); break;
             default: assert(!"unexpected member size"); break;
             }
      }
      break;

      case FLOAT:
         switch(size)
         {
         case 4: file.print("%g", *(float*)data); break;
         case 8: file.print("%g", *(double*)data); break;
         default: assert(!"unexpected member size"); break;
         }
         break;
      }
   }

   if (elements > 1) file.print("}");

   file.print(";\n");
}

void ClassBase::write(PLT::File& file, void* that) const
{
   file.print("%s\n", name);
   file.print("{\n");

   for(const auto& member : member_list)
   {
      member.write(file, that);
   }

   file.print("}\n");
}

void ClassBase::write(void* that) const
{
   PLT::File file(name, "oil", "w");

   write(file, that);
}

bool Member::read(SmallLex& lex, void* that) const
{
   if (elements > 1)
   {
      if (!lex.match('{')) return false;
   }

   for(size_t i=0; i<elements; ++i)
   {
      if (i > 0)
      {
         if (!lex.match(',')) return false;
      }

      void* data = (uint8_t*)that + offset + size*i;

      switch(type)
      {
      case BOOL:
         if (lex.tryMatch("true"))
         {
            *(bool*)data = true;
         }
         else if (lex.tryMatch("false"))
         {
            *(bool*)data = false;
         }
         else
         {
            return lex.error("Expected boolean value");
         }
         break;

      case SIGNED:
      {
         if (!lex.matchSigned()) return false;
         int64_t value = strtoll(lex.getToken(), nullptr, 0);
         int64_t unused = value >> (size*8);
         if ((unused != 0) || (unused != -1))
         {
            return lex.error("signed integer value too big");
         }
         switch(size)
         {
         case 1: *(int8_t*)data = int8_t(value); break;
         case 2: *(int16_t*)data = int16_t(value); break;
         case 4: *(int32_t*)data = int32_t(value); break;
         case 8: *(int64_t*)data = value; break;
         }
      }
      break;

      case ENUM:
      case UNSIGNED:
      {
         if (!lex.matchUnsigned()) return false;
         uint64_t value = strtoll(lex.getToken(), nullptr, 0);
         uint64_t unused = value >> (size*8);
         if (unused != 0)
         {
            return lex.error("unsigned integer value too big");
         }
         switch(size)
         {
         case 1: *(uint8_t*)data = uint8_t(value); break;
         case 2: *(uint16_t*)data = uint32_t(value); break;
         case 4: *(uint32_t*)data = uint32_t(value); break;
         case 8: *(uint64_t*)data = value; break;
         }
      }
      break;

      case FLOAT:
      {
         if (!lex.matchFloat()) return false;
         double value = atof(lex.getToken());
         switch(size)
         {
         case 4: *(float*)data = float(value); break;
         case 8: *(double*)data = value; break;
         }
      }
      break;
      }
   }

   if (elements > 1)
   {
      if (!lex.match('}')) return false;
   }

   return true;
}

bool ClassBase::read(SmallLex& lex, void* that) const
{
   if (!lex.match(name)) return false;

   if (!lex.match('{')) return false;

   while(!lex.tryMatch('}'))
   {
      if (!lex.matchIdent()) return false;

      const Member* member = findMember(lex.getToken());
      if (member == nullptr) return lex.error("bad member name '%s'", lex.getToken());

      if (!lex.match('=')) return false;

      if (!member->read(lex, that)) return false;

      if (!lex.match(';')) return false;
   }

   return true;
}

bool ClassBase::read(void* that) const
{
   SmallLex lex(name, "oil");

   return read(lex, that);
}

} // namespace OIL

} // namespace STB
<|endoftext|>


<commit_before><commit_msg>added equation type of drift diffusion to NDA parameters for subroutine framework<commit_after><|endoftext|>


<commit_before><commit_msg>Moved SW path rendering path back to using TU/sampler #2. This reverts r3813<commit_after><|endoftext|>


<commit_before>//-------------------------------------------------------------------------------------
// SimpleMath.cpp -- Simplified C++ Math wrapper for DirectXMath
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkId=248929
//-------------------------------------------------------------------------------------

#include "pch.h"
#include "SimpleMath.h"

/****************************************************************************
 *
 * Constants
 *
 ****************************************************************************/

namespace DirectX
{
    namespace SimpleMath
    {
    #if defined(_MSC_VER) && (_MSC_VER < 1800)
        const Vector2 Vector2::Zero(0.f, 0.f);
        const Vector2 Vector2::One(1.f, 1.f);
        const Vector2 Vector2::UnitX(1.f, 0.f);
        const Vector2 Vector2::UnitY(0.f, 1.f);

        const Vector3 Vector3::Zero(0.f, 0.f, 0.f);
        const Vector3 Vector3::One(1.f, 1.f, 1.f);
        const Vector3 Vector3::UnitX(1.f, 0.f, 0.f);
        const Vector3 Vector3::UnitY(0.f, 1.f, 0.f);
        const Vector3 Vector3::UnitZ(0.f, 0.f, 1.f);
        const Vector3 Vector3::Up(0.f, 1.f, 0.f);
        const Vector3 Vector3::Down(0.f, -1.f, 0.f);
        const Vector3 Vector3::Right(1.f, 0.f, 0.f);
        const Vector3 Vector3::Left(-1.f, 0.f, 0.f);
        const Vector3 Vector3::Forward(0.f, 0.f, -1.f);
        const Vector3 Vector3::Backward(0.f, 0.f, 1.f);

        const Vector4 Vector4::Zero(0.f, 0.f, 0.f, 0.f);
        const Vector4 Vector4::One(1.f, 1.f, 1.f, 1.f);
        const Vector4 Vector4::UnitX(1.f, 0.f, 0.f, 0.f);
        const Vector4 Vector4::UnitY(0.f, 1.f, 0.f, 0.f);
        const Vector4 Vector4::UnitZ(0.f, 0.f, 1.f, 0.f);
        const Vector4 Vector4::UnitW(0.f, 0.f, 0.f, 1.f);

        const Matrix Matrix::Identity(1.f, 0.f, 0.f, 0.f,
                                      0.f, 1.f, 0.f, 0.f,
                                      0.f, 0.f, 1.f, 0.f,
                                      0.f, 0.f, 0.f, 1.f);

        const Quaternion Quaternion::Identity(0.f, 0.f, 0.f, 1.f);
    #else
        const Vector2 Vector2::Zero = { 0.f, 0.f };
        const Vector2 Vector2::One = { 1.f, 1.f };
        const Vector2 Vector2::UnitX = { 1.f, 0.f };
        const Vector2 Vector2::UnitY = { 0.f, 1.f };

        const Vector3 Vector3::Zero = { 0.f, 0.f, 0.f };
        const Vector3 Vector3::One = { 1.f, 1.f, 1.f };
        const Vector3 Vector3::UnitX = { 1.f, 0.f, 0.f };
        const Vector3 Vector3::UnitY = { 0.f, 1.f, 0.f };
        const Vector3 Vector3::UnitZ = { 0.f, 0.f, 1.f };
        const Vector3 Vector3::Up = { 0.f, 1.f, 0.f };
        const Vector3 Vector3::Down = { 0.f, -1.f, 0.f };
        const Vector3 Vector3::Right = { 1.f, 0.f, 0.f };
        const Vector3 Vector3::Left = { -1.f, 0.f, 0.f };
        const Vector3 Vector3::Forward = { 0.f, 0.f, -1.f };
        const Vector3 Vector3::Backward = { 0.f, 0.f, 1.f };

        const Vector4 Vector4::Zero = { 0.f, 0.f, 0.f, 0.f };
        const Vector4 Vector4::One = { 1.f, 1.f, 1.f, 1.f };
        const Vector4 Vector4::UnitX = { 1.f, 0.f, 0.f, 0.f };
        const Vector4 Vector4::UnitY = { 0.f, 1.f, 0.f, 0.f };
        const Vector4 Vector4::UnitZ = { 0.f, 0.f, 1.f, 0.f };
        const Vector4 Vector4::UnitW = { 0.f, 0.f, 0.f, 1.f };

        const Matrix Matrix::Identity = { 1.f, 0.f, 0.f, 0.f,
                                          0.f, 1.f, 0.f, 0.f,
                                          0.f, 0.f, 1.f, 0.f,
                                          0.f, 0.f, 0.f, 1.f };

        const Quaternion Quaternion::Identity = { 0.f, 0.f, 0.f, 1.f };
    #endif
    }
}

/****************************************************************************
 *
 * Viewport
 *
 ****************************************************************************/

static_assert(sizeof(DirectX::SimpleMath::Viewport) == sizeof(D3D11_VIEWPORT), "Size mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, x) == FIELD_OFFSET(D3D11_VIEWPORT, TopLeftX), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, y) == FIELD_OFFSET(D3D11_VIEWPORT, TopLeftY), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, width) == FIELD_OFFSET(D3D11_VIEWPORT, Width), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, height) == FIELD_OFFSET(D3D11_VIEWPORT, Height), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, minDepth) == FIELD_OFFSET(D3D11_VIEWPORT, MinDepth), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, maxDepth) == FIELD_OFFSET(D3D11_VIEWPORT, MaxDepth), "Layout mismatch");

RECT DirectX::SimpleMath::Viewport::ComputeDisplayArea(DXGI_SCALING scaling, UINT backBufferWidth, UINT backBufferHeight, int outputWidth, int outputHeight)
{
    RECT rct;

    switch (int(scaling))
    {
    case DXGI_SCALING_STRETCH:
        // Output fills the entire window area
        rct.top = 0;
        rct.left = 0;
        rct.right = outputWidth;
        rct.bottom = outputHeight;
        break;

    case 2 /*DXGI_SCALING_ASPECT_RATIO_STRETCH*/:
        // Output fills the window area but respects the original aspect ratio, using pillar boxing or letter boxing as required
        // Note: This scaling option is not supported for legacy Win32 windows swap chains
        {
            assert(backBufferHeight > 0);
            float aspectRatio = float(backBufferWidth) / float(backBufferHeight);

            // Horizontal fill
            float scaledWidth = float(outputWidth);
            float scaledHeight = float(outputWidth) / aspectRatio;
            if (scaledHeight >= outputHeight)
            {
                // Do vertical fill
                scaledWidth = float(outputHeight) * aspectRatio;
                scaledHeight = float(outputHeight);
            }

            float offsetX = (float(outputWidth) - scaledWidth) * 0.5f;
            float offsetY = (float(outputHeight) - scaledHeight) * 0.5f;

            rct.left = static_cast<LONG>( offsetX );
            rct.top = static_cast<LONG>( offsetY );
            rct.right = static_cast<LONG>( offsetX + scaledWidth );
            rct.bottom = static_cast<LONG>( offsetY + scaledHeight );

            // Clip to display window
            rct.left = std::max<LONG>( 0, rct.left );
            rct.top = std::max<LONG>( 0, rct.top );
            rct.right = std::min<LONG>( outputWidth, rct.right );
            rct.bottom = std::min<LONG>( outputHeight, rct.bottom );
        }
        break;

    case DXGI_SCALING_NONE:
    default:
        // Output is displayed in the upper left corner of the window area
        rct.top = 0;
        rct.left = 0;
        rct.right = std::min<UINT>( backBufferWidth, UINT(outputWidth) );
        rct.bottom = std::min<UINT>( backBufferHeight, UINT(outputHeight) );
        break;
    }

    return rct;
}

RECT DirectX::SimpleMath::Viewport::ComputeTitleSafeArea(UINT backBufferWidth, UINT backBufferHeight)
{
    float safew = (float(backBufferWidth) + 9.f) / 10.f;
    float safeh = (float(backBufferHeight) + 9.f) / 10.f;

    RECT rct;
    rct.left = static_cast<LONG>(safew);
    rct.top = static_cast<LONG>(safeh);
    rct.right = static_cast<LONG>(float(backBufferWidth) - safew + 0.5f);
    rct.bottom = static_cast<LONG>(float(backBufferHeight) - safeh + 0.5f);

    return rct;
}
<commit_msg>ComputeTitleSafeArea was too conservative<commit_after>//-------------------------------------------------------------------------------------
// SimpleMath.cpp -- Simplified C++ Math wrapper for DirectXMath
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkId=248929
//-------------------------------------------------------------------------------------

#include "pch.h"
#include "SimpleMath.h"

/****************************************************************************
 *
 * Constants
 *
 ****************************************************************************/

namespace DirectX
{
    namespace SimpleMath
    {
    #if defined(_MSC_VER) && (_MSC_VER < 1800)
        const Vector2 Vector2::Zero(0.f, 0.f);
        const Vector2 Vector2::One(1.f, 1.f);
        const Vector2 Vector2::UnitX(1.f, 0.f);
        const Vector2 Vector2::UnitY(0.f, 1.f);

        const Vector3 Vector3::Zero(0.f, 0.f, 0.f);
        const Vector3 Vector3::One(1.f, 1.f, 1.f);
        const Vector3 Vector3::UnitX(1.f, 0.f, 0.f);
        const Vector3 Vector3::UnitY(0.f, 1.f, 0.f);
        const Vector3 Vector3::UnitZ(0.f, 0.f, 1.f);
        const Vector3 Vector3::Up(0.f, 1.f, 0.f);
        const Vector3 Vector3::Down(0.f, -1.f, 0.f);
        const Vector3 Vector3::Right(1.f, 0.f, 0.f);
        const Vector3 Vector3::Left(-1.f, 0.f, 0.f);
        const Vector3 Vector3::Forward(0.f, 0.f, -1.f);
        const Vector3 Vector3::Backward(0.f, 0.f, 1.f);

        const Vector4 Vector4::Zero(0.f, 0.f, 0.f, 0.f);
        const Vector4 Vector4::One(1.f, 1.f, 1.f, 1.f);
        const Vector4 Vector4::UnitX(1.f, 0.f, 0.f, 0.f);
        const Vector4 Vector4::UnitY(0.f, 1.f, 0.f, 0.f);
        const Vector4 Vector4::UnitZ(0.f, 0.f, 1.f, 0.f);
        const Vector4 Vector4::UnitW(0.f, 0.f, 0.f, 1.f);

        const Matrix Matrix::Identity(1.f, 0.f, 0.f, 0.f,
                                      0.f, 1.f, 0.f, 0.f,
                                      0.f, 0.f, 1.f, 0.f,
                                      0.f, 0.f, 0.f, 1.f);

        const Quaternion Quaternion::Identity(0.f, 0.f, 0.f, 1.f);
    #else
        const Vector2 Vector2::Zero = { 0.f, 0.f };
        const Vector2 Vector2::One = { 1.f, 1.f };
        const Vector2 Vector2::UnitX = { 1.f, 0.f };
        const Vector2 Vector2::UnitY = { 0.f, 1.f };

        const Vector3 Vector3::Zero = { 0.f, 0.f, 0.f };
        const Vector3 Vector3::One = { 1.f, 1.f, 1.f };
        const Vector3 Vector3::UnitX = { 1.f, 0.f, 0.f };
        const Vector3 Vector3::UnitY = { 0.f, 1.f, 0.f };
        const Vector3 Vector3::UnitZ = { 0.f, 0.f, 1.f };
        const Vector3 Vector3::Up = { 0.f, 1.f, 0.f };
        const Vector3 Vector3::Down = { 0.f, -1.f, 0.f };
        const Vector3 Vector3::Right = { 1.f, 0.f, 0.f };
        const Vector3 Vector3::Left = { -1.f, 0.f, 0.f };
        const Vector3 Vector3::Forward = { 0.f, 0.f, -1.f };
        const Vector3 Vector3::Backward = { 0.f, 0.f, 1.f };

        const Vector4 Vector4::Zero = { 0.f, 0.f, 0.f, 0.f };
        const Vector4 Vector4::One = { 1.f, 1.f, 1.f, 1.f };
        const Vector4 Vector4::UnitX = { 1.f, 0.f, 0.f, 0.f };
        const Vector4 Vector4::UnitY = { 0.f, 1.f, 0.f, 0.f };
        const Vector4 Vector4::UnitZ = { 0.f, 0.f, 1.f, 0.f };
        const Vector4 Vector4::UnitW = { 0.f, 0.f, 0.f, 1.f };

        const Matrix Matrix::Identity = { 1.f, 0.f, 0.f, 0.f,
                                          0.f, 1.f, 0.f, 0.f,
                                          0.f, 0.f, 1.f, 0.f,
                                          0.f, 0.f, 0.f, 1.f };

        const Quaternion Quaternion::Identity = { 0.f, 0.f, 0.f, 1.f };
    #endif
    }
}

/****************************************************************************
 *
 * Viewport
 *
 ****************************************************************************/

static_assert(sizeof(DirectX::SimpleMath::Viewport) == sizeof(D3D11_VIEWPORT), "Size mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, x) == FIELD_OFFSET(D3D11_VIEWPORT, TopLeftX), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, y) == FIELD_OFFSET(D3D11_VIEWPORT, TopLeftY), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, width) == FIELD_OFFSET(D3D11_VIEWPORT, Width), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, height) == FIELD_OFFSET(D3D11_VIEWPORT, Height), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, minDepth) == FIELD_OFFSET(D3D11_VIEWPORT, MinDepth), "Layout mismatch");
static_assert(FIELD_OFFSET(DirectX::SimpleMath::Viewport, maxDepth) == FIELD_OFFSET(D3D11_VIEWPORT, MaxDepth), "Layout mismatch");

RECT DirectX::SimpleMath::Viewport::ComputeDisplayArea(DXGI_SCALING scaling, UINT backBufferWidth, UINT backBufferHeight, int outputWidth, int outputHeight)
{
    RECT rct;

    switch (int(scaling))
    {
    case DXGI_SCALING_STRETCH:
        // Output fills the entire window area
        rct.top = 0;
        rct.left = 0;
        rct.right = outputWidth;
        rct.bottom = outputHeight;
        break;

    case 2 /*DXGI_SCALING_ASPECT_RATIO_STRETCH*/:
        // Output fills the window area but respects the original aspect ratio, using pillar boxing or letter boxing as required
        // Note: This scaling option is not supported for legacy Win32 windows swap chains
        {
            assert(backBufferHeight > 0);
            float aspectRatio = float(backBufferWidth) / float(backBufferHeight);

            // Horizontal fill
            float scaledWidth = float(outputWidth);
            float scaledHeight = float(outputWidth) / aspectRatio;
            if (scaledHeight >= outputHeight)
            {
                // Do vertical fill
                scaledWidth = float(outputHeight) * aspectRatio;
                scaledHeight = float(outputHeight);
            }

            float offsetX = (float(outputWidth) - scaledWidth) * 0.5f;
            float offsetY = (float(outputHeight) - scaledHeight) * 0.5f;

            rct.left = static_cast<LONG>( offsetX );
            rct.top = static_cast<LONG>( offsetY );
            rct.right = static_cast<LONG>( offsetX + scaledWidth );
            rct.bottom = static_cast<LONG>( offsetY + scaledHeight );

            // Clip to display window
            rct.left = std::max<LONG>( 0, rct.left );
            rct.top = std::max<LONG>( 0, rct.top );
            rct.right = std::min<LONG>( outputWidth, rct.right );
            rct.bottom = std::min<LONG>( outputHeight, rct.bottom );
        }
        break;

    case DXGI_SCALING_NONE:
    default:
        // Output is displayed in the upper left corner of the window area
        rct.top = 0;
        rct.left = 0;
        rct.right = std::min<UINT>( backBufferWidth, UINT(outputWidth) );
        rct.bottom = std::min<UINT>( backBufferHeight, UINT(outputHeight) );
        break;
    }

    return rct;
}

RECT DirectX::SimpleMath::Viewport::ComputeTitleSafeArea(UINT backBufferWidth, UINT backBufferHeight)
{
    float safew = (float(backBufferWidth) + 19.f) / 20.f;
    float safeh = (float(backBufferHeight) + 19.f) / 20.f;

    RECT rct;
    rct.left = static_cast<LONG>(safew);
    rct.top = static_cast<LONG>(safeh);
    rct.right = static_cast<LONG>(float(backBufferWidth) - safew + 0.5f);
    rct.bottom = static_cast<LONG>(float(backBufferHeight) - safeh + 0.5f);

    return rct;
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "AnnEngine.hpp"
#include "AnnLogger.hpp"
using namespace Annwvyn;

AnnEngine* AnnEngine::singleton(NULL);
std::shared_ptr<AnnConsole> AnnEngine::onScreenConsole(nullptr);

AnnEngine* AnnEngine::Instance()
{
	return singleton;
}

std::string AnnEngine::getAnnwvynVersion(long long int padding)
{
	std::stringstream version;
	version << ANN_MAJOR << "." << ANN_MINOR << "." << ANN_PATCH;
	if (ANN_EXPERIMENTAL)
		version << "-experimental";
	padding -= version.str().length();
	for (int i(0); i < padding; i++)
		version << " ";
	return version.str();
}

void AnnEngine::startGameplayLoop()
{
	while (refresh());
}

AnnEngine::AnnEngine(const char title[], std::string hmdCommand) :
	renderer(nullptr),
	resourceManager(nullptr),
	sceneryManager(nullptr),
	filesystemManager(nullptr),
	audioEngine(nullptr),
	eventManager(nullptr),
	physicsEngine(nullptr),
	gameObjectManager(nullptr),
	levelManager(nullptr),
	player(nullptr),
	SceneManager(nullptr),
	vrRendererPovGameplayPlacement(nullptr),
	updateTime(-1)
{

	if (singleton)
	{
		log("Can't create 2 instances of the engine!");
		exit(ANN_ERR_MEMORY);
	}

	std::cerr << "HMD selection from command line routine retuned : " << hmdCommand << std::endl;

	//Select the correct OgreVRRender class to use :
	if (hmdCommand == "OgreOculusRender"
		|| hmdCommand == "OgreDefaultRender")
		renderer = std::make_shared<OgreOculusRender>(title);
	else if (hmdCommand == "OgreOpenVRRender")
		renderer = std::make_shared<OgreOpenVRRender>(title);
	else if (hmdCommand == "OgreNoVRRender")
		renderer = std::make_shared<OgreNoVRRender>(title);

	else
	{
		displayWin32ErrorMessage(L"Error: Cannot understand VR System you want to use!",
								 L"This program can be used with multiple VR solution.\n"
								 L"The executable should be launched via a dedicated launcher.\n"
								 L"If you're trying to launch it by hand, please check if your command line parameter is correct!\n\n"
								 L"Available command line parameter : \n"
								 L"\t-rift\n"
								 L"\t-vive\n"
								 L"\nIf you don't specify anything, the default system will be used (here it's the Oculus Rift)\n"
								 L"If you don't have (or can't use) VR Hardware, you can launch with -noVR.\n"
								 L"This will display the image on a simple window without attempting to talk to VR hardware"
		);
		exit(ANN_ERR_CANTHMD);
	}

	renderer->initOgreRoot("Annwvyn.log");
	log("===========================================================", false);
	log("| Annwvyn Game Engine - Step into the Other World         |", false);
	log("| Free/Libre C++ Game Engine designed for Virtual Reality |", false);
	log("| Copyright Arthur Brainvile (a.k.a. Ybalrid) 2013-2016   |", false);
	log("| Distributed under the terms of the MIT licence agreement|", false);
	log("| Visit http://annwvyn.org/ for more informations!        |", false);
	log("| Version : " + getAnnwvynVersion(60-13-1) + "|", false);
	log("===========================================================", false);

	srand(time(nullptr));
	singleton = this;

	player = std::make_shared< AnnPlayer>();
	renderer->initVrHmd();
	renderer->initPipeline();
	SceneManager = renderer->getSceneManager();

	renderer->showDebug(OgreVRRender::DebugMode::MONOSCOPIC);

	log("Setup Annwvyn's subsystems");

	//Element on this list will be updated in order by the engine each frame
	SubSystemList.push_back(levelManager = std::make_shared<AnnLevelManager>());
	SubSystemList.push_back(gameObjectManager = std::make_shared<AnnGameObjectManager>());

	//Physics engine needs to be declared before the event manager. But we want the physics engine to be updated after the event manager.

	/*The wanted order is
	- event happens (player input, timers...)
	- physics is ticked (stuff move)
	- audio is synced (sonds comes form where they should)
	- then the game can redraw*/

	physicsEngine = std::make_shared<AnnPhysicsEngine>(getSceneManager()->getRootSceneNode(), player, gameObjectManager->Objects, gameObjectManager->Triggers);
	SubSystemList.push_back(eventManager = std::make_shared< AnnEventManager>(renderer->getWindow()));
	SubSystemList.push_back(physicsEngine);
	SubSystemList.push_back(audioEngine = std::make_shared< AnnAudioEngine>());

	//These could be anywere
	SubSystemList.push_back(filesystemManager = std::make_shared<AnnFilesystemManager>(title));
	SubSystemList.push_back(resourceManager = std::make_shared<AnnResourceManager>());
	SubSystemList.push_back(sceneryManager = std::make_shared<AnnSceneryManager>(renderer));

	renderer->initClientHmdRendering();
	vrRendererPovGameplayPlacement = renderer->getCameraInformationNode();
	vrRendererPovGameplayPlacement->setPosition(player->getPosition() +
		AnnVect3(0.0f, player->getEyesHeight(), 0.0f));

	//This subsystem need the vrRendererPovGameplayPlacement object to be initialized. And the Resource manager because it wants a font file and an image background
	SubSystemList.push_back(onScreenConsole = std::make_shared<AnnConsole>());
}

AnnEngine::~AnnEngine()
{
	//Some cute log messsages
	log("Game engine stopped. Subsystem are shutting down...");
	log("Good luck with the real world now! :3");
}

//All theses getter are for encapsulation purpose. Calling them directly would make verry long lines of code. Note that there's a whole bunch of macro in AnnEngine.hpp to help with that
std::shared_ptr<AnnEventManager> AnnEngine::getEventManager()
{
	return eventManager;
}

std::shared_ptr<AnnResourceManager> AnnEngine::getResourceManager()
{
	return resourceManager;
}

std::shared_ptr<AnnGameObjectManager> AnnEngine::getGameObjectManager()
{
	return gameObjectManager;
}

std::shared_ptr<AnnSceneryManager> AnnEngine::getSceneryManager()
{
	return sceneryManager;
}

std::shared_ptr<OgreVRRender> AnnEngine::getVRRenderer()
{
	return renderer;
}

std::shared_ptr<AnnLevelManager> AnnEngine::getLevelManager()
{
	return levelManager;
}

std::shared_ptr<AnnPlayer> AnnEngine::getPlayer()
{
	return player;
}

std::shared_ptr<AnnFilesystemManager> AnnEngine::getFileSystemManager()
{
	return filesystemManager;
}

std::shared_ptr<AnnAudioEngine> AnnEngine::getAudioEngine()
{
	return audioEngine;
}

std::shared_ptr<AnnPhysicsEngine> AnnEngine::getPhysicsEngine()
{
	return physicsEngine;
}

//This is static, but actually needs Ogre to be running. So be carefull
void AnnEngine::log(std::string message, bool flag)
{
	Ogre::String messageForLog;

	if (flag)
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
		messageForLog += "Annwvyn - ";
	}
	else
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);

	messageForLog += message;
	Ogre::LogManager::getSingleton().logMessage(messageForLog);
	if (onScreenConsole != nullptr)
		onScreenConsole->append(message);

	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
}

//Don't ask me why this is not part of the Physics engine. Actually it just calls something on the physics engine. Will be probably deleted in the future.
void AnnEngine::initPlayerPhysics()
{
	physicsEngine->initPlayerPhysics(vrRendererPovGameplayPlacement);
}

//Need to be redone.
bool AnnEngine::requestStop()
{
	//pres ESC to quit. Stupid but efficient. I like that.
	if (isKeyDown(OIS::KC_ESCAPE))
		return true;
	//If the user quit the App from the Oculus Home
	if (renderer->shouldQuit())
		return true;
	return false;
}

//This is the most important function of the whole project. It's the heartbeat of the game or app using this engine.
bool AnnEngine::refresh()
{
	//Get the rendering delta time (should be roughly equals to 1/desiredFramerate in seconds)
	updateTime = renderer->getUpdateTime();
	player->engineUpdate(getFrameTime());

	for (auto SubSystem : SubSystemList)
		if (!SubSystem->needUpdate()) continue; //If doen't need update, swith to the next
		else SubSystem->update();				//The "else" keyword is used to not put curly braces, by lazyness and by code style.

	//Update camera from player
	syncPov();

	//Update VR form real world
	renderer->updateTracking();

	//Update view
	renderer->renderAndSubmitFrame();

	//Don't laugh
	return !requestStop();
}

//This just move a node where the other node is. Yes I know about parenting. I had reasons to do it that way, but I forgot.
inline void AnnEngine::syncPov()
{
	vrRendererPovGameplayPlacement->setPosition(player->getPosition());
	vrRendererPovGameplayPlacement->setOrientation(player->getOrientation().toQuaternion());
}

//Bad. Don't use. Register an event listener and use the KeyEvent callback.
inline bool AnnEngine::isKeyDown(OIS::KeyCode key)
{
	if (!eventManager) return false;
	return eventManager->Keyboard->isKeyDown(key);
}

Ogre::SceneNode* AnnEngine::getPlayerPovNode()
{
	return vrRendererPovGameplayPlacement;
}

Ogre::SceneManager* AnnEngine::getSceneManager()
{
	return SceneManager;
}

unsigned long AnnEngine::getTimeFromStartUp()
{
	return renderer->getTimer()->getMilliseconds();
}

double AnnEngine::getTimeFromStartupSeconds()
{
	return static_cast<double>(getTimeFromStartUp()) / 1000.0;
}

//the delta time of the last frame, not the current one
double AnnEngine::getFrameTime()
{
	return updateTime;
}

//Raw position and orientaiton of the head in world space. This is usefull if you want to mess around with weird stuff. This has been bodged when I integrated a LEAP motion in that mess.
OgrePose AnnEngine::getHmdPose()
{
	if (renderer)
		return renderer->returnPose;
	return OgrePose();
}

//Because Windows and the Win32 platform sucks.
void AnnEngine::openConsole()
{
#ifdef _WIN32

	//Allocate a console for this app
	if (AllocConsole())
	{
		//put stdout on this console;
#pragma warning(disable:4996) //Okay, so for some reason, freopen is "bad" because potentially dangerous. However, since I'm passing static strings here, unless you go hack the DLL, I don't know what harm you can do.
		freopen("CONOUT$", "w", stdout);
#pragma warning(default:4996)
	}

	//Redirect cerr to cout
	std::cerr.rdbuf(std::cout.rdbuf());

	SetConsoleTitle(L"Annwyn Debug Console");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);

#endif
}

//Well, I may make the pointer to the onScreenConsole more accessible.
void AnnEngine::toogleOnScreenConsole()
{
	if (onScreenConsole) onScreenConsole->toogle();
}

bool AnnEngine::appVisibleInHMD()
{
	if (renderer->isVisibleInHmd() == true) // why "== true" ? Because at some point it was returning an ovrBool, wich is the boolean type of the oculus SDK that doesn't cast correctly to a C++ bool. YES. I DON'T KNOW HOW THEY MANAGED TO FFFF TAHT UP.
		return true;
	return false;
}
<commit_msg>add some space on the start banner<commit_after>#include "stdafx.h"
#include "AnnEngine.hpp"
#include "AnnLogger.hpp"

using namespace Annwvyn;

AnnEngine* AnnEngine::singleton(NULL);

//Log is static. Therefore this has to be static too to be able to write to it.
std::shared_ptr<AnnConsole> AnnEngine::onScreenConsole(nullptr);

AnnEngine* AnnEngine::Instance()
{
	return singleton;
}

std::string AnnEngine::getAnnwvynVersion(long long int padding)
{
	std::stringstream version;
	version << ANN_MAJOR << "." << ANN_MINOR << "." << ANN_PATCH;
	if (ANN_EXPERIMENTAL)
		version << "-experimental";
	padding -= version.str().length();
	for (int i(0); i < padding; i++)
		version << " ";
	return version.str();
}

void AnnEngine::startGameplayLoop()
{
	while (refresh());
}

AnnEngine::AnnEngine(const char title[], std::string hmdCommand) :
	renderer(nullptr),
	resourceManager(nullptr),
	sceneryManager(nullptr),
	filesystemManager(nullptr),
	audioEngine(nullptr),
	eventManager(nullptr),
	physicsEngine(nullptr),
	gameObjectManager(nullptr),
	levelManager(nullptr),
	player(nullptr),
	SceneManager(nullptr),
	vrRendererPovGameplayPlacement(nullptr),
	updateTime(-1)
{

	if (singleton)
	{
		log("Can't create 2 instances of the engine!");
		exit(ANN_ERR_MEMORY);
	}

	std::cerr << "HMD selection from command line routine retuned : " << hmdCommand << std::endl;

	//Select the correct OgreVRRender class to use :
	if (hmdCommand == "OgreOculusRender"
		|| hmdCommand == "OgreDefaultRender")
		renderer = std::make_shared<OgreOculusRender>(title);
	else if (hmdCommand == "OgreOpenVRRender")
		renderer = std::make_shared<OgreOpenVRRender>(title);
	else if (hmdCommand == "OgreNoVRRender")
		renderer = std::make_shared<OgreNoVRRender>(title);

	else
	{
		displayWin32ErrorMessage(L"Error: Cannot understand VR System you want to use!",
								 L"This program can be used with multiple VR solution.\n"
								 L"The executable should be launched via a dedicated launcher.\n"
								 L"If you're trying to launch it by hand, please check if your command line parameter is correct!\n\n"
								 L"Available command line parameter : \n"
								 L"\t-rift\n"
								 L"\t-vive\n"
								 L"\nIf you don't specify anything, the default system will be used (here it's the Oculus Rift)\n"
								 L"If you don't have (or can't use) VR Hardware, you can launch with -noVR.\n"
								 L"This will display the image on a simple window without attempting to talk to VR hardware"
		);
		exit(ANN_ERR_CANTHMD);
	}

	renderer->initOgreRoot("Annwvyn.log");

	//Display start banner
	log("============================================================", false);
	log("| Annwvyn Game Engine - Step into the Other World          |", false);
	log("| Free/Libre C++ Game Engine designed for Virtual Reality  |", false);
	log("|                                                          |", false);
	log("| Copyright Arthur Brainvile (a.k.a. Ybalrid) 2013-2016    |", false);
	log("| Distributed under the terms of the MIT licence agreement |", false);
	log("|                                                          |", false);
	log("| Visit http://annwvyn.org/ for more informations!         |", false);
	log("| Version : " + getAnnwvynVersion(61-13-1) +              "|", false);
	log("============================================================", false);

	srand(time(nullptr));
	singleton = this;

	player = std::make_shared< AnnPlayer>();
	renderer->initVrHmd();
	renderer->initPipeline();
	SceneManager = renderer->getSceneManager();

	renderer->showDebug(OgreVRRender::DebugMode::MONOSCOPIC);

	log("Setup Annwvyn's subsystems");

	//Element on this list will be updated in order by the engine each frame
	SubSystemList.push_back(levelManager = std::make_shared<AnnLevelManager>());
	SubSystemList.push_back(gameObjectManager = std::make_shared<AnnGameObjectManager>());

	//Physics engine needs to be declared before the event manager. But we want the physics engine to be updated after the event manager.

	/*The wanted order is
	- event happens (player input, timers...)
	- physics is ticked (stuff move)
	- audio is synced (sonds comes form where they should)
	- then the game can redraw*/

	physicsEngine = std::make_shared<AnnPhysicsEngine>(getSceneManager()->getRootSceneNode(), player, gameObjectManager->Objects, gameObjectManager->Triggers);
	SubSystemList.push_back(eventManager = std::make_shared< AnnEventManager>(renderer->getWindow()));
	SubSystemList.push_back(physicsEngine);
	SubSystemList.push_back(audioEngine = std::make_shared< AnnAudioEngine>());

	//These could be anywere
	SubSystemList.push_back(filesystemManager = std::make_shared<AnnFilesystemManager>(title));
	SubSystemList.push_back(resourceManager = std::make_shared<AnnResourceManager>());
	SubSystemList.push_back(sceneryManager = std::make_shared<AnnSceneryManager>(renderer));

	renderer->initClientHmdRendering();
	vrRendererPovGameplayPlacement = renderer->getCameraInformationNode();
	vrRendererPovGameplayPlacement->setPosition(player->getPosition() +
		AnnVect3(0.0f, player->getEyesHeight(), 0.0f));

	//This subsystem need the vrRendererPovGameplayPlacement object to be initialized. And the Resource manager because it wants a font file and an image background
	SubSystemList.push_back(onScreenConsole = std::make_shared<AnnConsole>());
}

AnnEngine::~AnnEngine()
{
	//Some cute log messsages
	log("Game engine stopped. Subsystem are shutting down...");
	log("Good luck with the real world now! :3");
}

//All theses getter are for encapsulation purpose. Calling them directly would make verry long lines of code. Note that there's a whole bunch of macro in AnnEngine.hpp to help with that
std::shared_ptr<AnnEventManager> AnnEngine::getEventManager()
{
	return eventManager;
}

std::shared_ptr<AnnResourceManager> AnnEngine::getResourceManager()
{
	return resourceManager;
}

std::shared_ptr<AnnGameObjectManager> AnnEngine::getGameObjectManager()
{
	return gameObjectManager;
}

std::shared_ptr<AnnSceneryManager> AnnEngine::getSceneryManager()
{
	return sceneryManager;
}

std::shared_ptr<OgreVRRender> AnnEngine::getVRRenderer()
{
	return renderer;
}

std::shared_ptr<AnnLevelManager> AnnEngine::getLevelManager()
{
	return levelManager;
}

std::shared_ptr<AnnPlayer> AnnEngine::getPlayer()
{
	return player;
}

std::shared_ptr<AnnFilesystemManager> AnnEngine::getFileSystemManager()
{
	return filesystemManager;
}

std::shared_ptr<AnnAudioEngine> AnnEngine::getAudioEngine()
{
	return audioEngine;
}

std::shared_ptr<AnnPhysicsEngine> AnnEngine::getPhysicsEngine()
{
	return physicsEngine;
}

//This is static, but actually needs Ogre to be running. So be carefull
void AnnEngine::log(std::string message, bool flag)
{
	Ogre::String messageForLog;

	if (flag)
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
		messageForLog += "Annwvyn - ";
	}
	else
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);

	messageForLog += message;
	Ogre::LogManager::getSingleton().logMessage(messageForLog);
	if (onScreenConsole != nullptr)
		onScreenConsole->append(message);

	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
}

//Don't ask me why this is not part of the Physics engine. Actually it just calls something on the physics engine. Will be probably deleted in the future.
void AnnEngine::initPlayerPhysics()
{
	physicsEngine->initPlayerPhysics(vrRendererPovGameplayPlacement);
}

//Need to be redone.
bool AnnEngine::requestStop()
{
	//pres ESC to quit. Stupid but efficient. I like that.
	if (isKeyDown(OIS::KC_ESCAPE))
		return true;
	//If the user quit the App from the Oculus Home
	if (renderer->shouldQuit())
		return true;
	return false;
}

//This is the most important function of the whole project. It's the heartbeat of the game or app using this engine.
bool AnnEngine::refresh()
{
	//Get the rendering delta time (should be roughly equals to 1/desiredFramerate in seconds)
	updateTime = renderer->getUpdateTime();
	player->engineUpdate(getFrameTime());

	for (auto SubSystem : SubSystemList)
		if (!SubSystem->needUpdate()) continue; //If doen't need update, swith to the next
		else SubSystem->update();				//The "else" keyword is used to not put curly braces, by lazyness and by code style.

	//Update camera from player
	syncPov();

	//Update VR form real world
	renderer->updateTracking();

	//Update view
	renderer->renderAndSubmitFrame();

	//Don't laugh
	return !requestStop();
}

//This just move a node where the other node is. Yes I know about parenting. I had reasons to do it that way, but I forgot.
inline void AnnEngine::syncPov()
{
	vrRendererPovGameplayPlacement->setPosition(player->getPosition());
	vrRendererPovGameplayPlacement->setOrientation(player->getOrientation().toQuaternion());
}

//Bad. Don't use. Register an event listener and use the KeyEvent callback.
inline bool AnnEngine::isKeyDown(OIS::KeyCode key)
{
	if (!eventManager) return false;
	return eventManager->Keyboard->isKeyDown(key);
}

Ogre::SceneNode* AnnEngine::getPlayerPovNode()
{
	return vrRendererPovGameplayPlacement;
}

Ogre::SceneManager* AnnEngine::getSceneManager()
{
	return SceneManager;
}

unsigned long AnnEngine::getTimeFromStartUp()
{
	return renderer->getTimer()->getMilliseconds();
}

double AnnEngine::getTimeFromStartupSeconds()
{
	return static_cast<double>(getTimeFromStartUp()) / 1000.0;
}

//the delta time of the last frame, not the current one
double AnnEngine::getFrameTime()
{
	return updateTime;
}

//Raw position and orientaiton of the head in world space. This is usefull if you want to mess around with weird stuff. This has been bodged when I integrated a LEAP motion in that mess.
OgrePose AnnEngine::getHmdPose()
{
	if (renderer)
		return renderer->returnPose;
	return OgrePose();
}

//Because Windows and the Win32 platform sucks.
void AnnEngine::openConsole()
{
#ifdef _WIN32

	//Allocate a console for this app
	if (AllocConsole())
	{
		//put stdout on this console;
#pragma warning(disable:4996) //Okay, so for some reason, freopen is "bad" because potentially dangerous. However, since I'm passing static strings here, unless you go hack the DLL, I don't know what harm you can do.
		freopen("CONOUT$", "w", stdout);
#pragma warning(default:4996)
	}

	//Redirect cerr to cout
	std::cerr.rdbuf(std::cout.rdbuf());

	SetConsoleTitle(L"Annwyn Debug Console");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);

#endif
}

//Well, I may make the pointer to the onScreenConsole more accessible.
void AnnEngine::toogleOnScreenConsole()
{
	if (onScreenConsole) onScreenConsole->toogle();
}

bool AnnEngine::appVisibleInHMD()
{
	if (renderer->isVisibleInHmd() == true) // why "== true" ? Because at some point it was returning an ovrBool, wich is the boolean type of the oculus SDK that doesn't cast correctly to a C++ bool. YES. I DON'T KNOW HOW THEY MANAGED TO FFFF TAHT UP.
		return true;
	return false;
}
<|endoftext|>


<commit_before>// Copyright (C) 2011 Oliver Schulz <oliver.schulz@tu-dortmund.de>

// 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.

#include "Selector.h"

#include <iostream>
#include <sstream>
#include <cassert>
#include <cassert>

#include <TFile.h>
#include <TObjArray.h>
#include <TChainElement.h>
#include <TPRegexp.h>

#include "util.h"
#include "File.h"

ClassImp(froast::Selector)

using namespace std;

using namespace std;

namespace froast {

void Selector::copyObject(TDirectory *tdir, const TString &objName) {
	TObject *keepObj = 0;
	tdir->GetObject(objName.Data(), keepObj);
	if (keepObj != 0) {
		TTree *keepTree = dynamic_cast<TTree*>(keepObj);
		if (keepTree != 0) {
			TTree *cloned = keepTree->CloneTree();
			cloned->Write();
		}
	} else {
		throw runtime_error(string("Object ") + objName.Data() + " not found in TDirectory");
	}
}

void Selector::mapMulti(TChain *chain, const TString &selector, const TString &tag, const TString &keep) {
	TObjArray *chainElems = chain->GetListOfFiles();
	for (int chainEntry = 0; chainEntry < chainElems->GetEntriesFast(); ++chainEntry) {
		TChainElement *e = dynamic_cast<TChainElement*>(chainElems->At(chainEntry));
		string treeName = e->GetName();
		string inFileName = e->GetTitle();

		string outFileName = (File(inFileName).base() % tag.Data()).path();
		cerr << "Mapping " << inFileName << ":" << treeName << " to " << outFileName << endl;

		TFile inFile(inFileName.c_str(), "read");
		TTree *inTree; inFile.GetObject(treeName.c_str(), inTree);

		TFile outFile(outFileName.c_str(), "recreate");

		TSelector *sel = TSelector::GetSelector(selector.Data());
		if (sel == 0) throw runtime_error(string("Cannot load selector ") + selector.Data());
		inTree->Process(sel);
		delete sel;

		TObjArray* keeps = keep.Tokenize(",");
		for (int i = 0; i < keeps->GetEntriesFast(); ++i) {
			TString keepObjName = dynamic_cast<TObjString*>(keeps->At(i))->GetString().Strip(TString::kBoth);
			cerr << "Copying object " << keepObjName << " to output" << endl;
			copyObject(&inFile, keepObjName);
		}
		delete keeps;

		outFile.Write();
		outFile.Close();
		inFile.Close();
	}
}

void Selector::mapSingle(const TString &inFileName, const TString &mappers, const TString &outFileName, bool noRecompile) {
	TFile inFile(inFileName.Data(), "read");
	TFile outFile(outFileName.Data(), "recreate");

	TPRegexp mapperSpecExpr("^(.*)\\((.*)\\)$");
	TPRegexp xxExp("\\+\\+$");

	TObjArray* mapperNames = mappers.Tokenize(",");
	for (int mapperEntry = 0; mapperEntry < mapperNames->GetEntriesFast(); ++mapperEntry) {
		TString mapper = dynamic_cast<TObjString*>(mapperNames->At(mapperEntry))->GetString().Strip(TString::kBoth);
		TObjArray* matches = mapperSpecExpr.MatchS(mapper);
		if (matches->GetEntriesFast() == 3) {
			TString fctName = dynamic_cast<TObjString*>(matches->At(1))->GetString();
			if (noRecompile) xxExp.Substitute(fctName, "+");
			TString objName = dynamic_cast<TObjString*>(matches->At(2))->GetString();
			assert ((fctName != 0) && (objName != 0));
			delete matches;

			cerr << "Applying " << fctName << "(" << objName << ")" << endl;

			TObject *inObj; inFile.GetObject(objName.Data(), inObj);
			if (inObj != 0) {
				TTree *inTree = dynamic_cast<TTree*>(inObj);
				if (inTree != 0) {
					if (fctName == "copy") {
						TTree *copied = inTree->CloneTree();
						copied->Write();
					} else {
						TSelector *sel = TSelector::GetSelector(fctName.Data());
						if (sel == 0) throw runtime_error(string("Cannot load selector ") + fctName.Data());
						inTree->Process(sel);
						delete sel;
					}
				} else throw invalid_argument(string("Objects of type ") + inObj->Class()->GetName() + " not supported yet");
			} else {
				delete matches;
				throw runtime_error(string("Object ") + objName.Data() + " not found in TDirectory");
			}
		} else {
			delete matches;
			throw invalid_argument(string("Invalid mapper specification: \"") + mapper.Data() + "\"");
		}
	}
	delete mapperNames;

	outFile.Write();
	outFile.Close();
	inFile.Close();
}

void Selector::mapMulti(const TString &fileName, const TString &mappers, const TString &tag, bool noRecompile) {
	cerr << TString::Format("Selector::map(%s, %s, %s)", fileName.Data(), mappers.Data(), tag.Data()) << endl;

	TChain chain("");
	chain.Add(fileName.Data());
	TObjArray *chainElems = chain.GetListOfFiles();
	for (int chainEntry = 0; chainEntry < chainElems->GetEntriesFast(); ++chainEntry) {
		TChainElement *e = dynamic_cast<TChainElement*>(chainElems->At(chainEntry));
		string inFileName = e->GetTitle();

		string outFileName = (File(inFileName).base() % tag.Data()).path();
		cerr << "Mapping " << inFileName << " to " << outFileName << endl;
		// Don't recompile even if fct ends with "++" after first run:
		mapSingle(inFileName, mappers, outFileName, (chainEntry > 0) || noRecompile);
	}
	cerr << "Selector::map(...) finished" << endl;
}

} // namespace froast
<commit_msg>Changed Selector map functions to save local settings in output<commit_after>// Copyright (C) 2011 Oliver Schulz <oliver.schulz@tu-dortmund.de>

// 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.

#include "Selector.h"

#include <iostream>
#include <sstream>
#include <cassert>
#include <cassert>

#include <TFile.h>
#include <TObjArray.h>
#include <TChainElement.h>
#include <TPRegexp.h>

#include "util.h"
#include "File.h"

ClassImp(froast::Selector)

using namespace std;

using namespace std;

namespace froast {

void Selector::copyObject(TDirectory *tdir, const TString &objName) {
	TObject *keepObj = 0;
	tdir->GetObject(objName.Data(), keepObj);
	if (keepObj != 0) {
		TTree *keepTree = dynamic_cast<TTree*>(keepObj);
		if (keepTree != 0) {
			TTree *cloned = keepTree->CloneTree();
			cloned->Write();
		}
	} else {
		throw runtime_error(string("Object ") + objName.Data() + " not found in TDirectory");
	}
}

void Selector::mapMulti(TChain *chain, const TString &selector, const TString &tag, const TString &keep) {
	TObjArray *chainElems = chain->GetListOfFiles();
	for (int chainEntry = 0; chainEntry < chainElems->GetEntriesFast(); ++chainEntry) {
		TChainElement *e = dynamic_cast<TChainElement*>(chainElems->At(chainEntry));
		string treeName = e->GetName();
		string inFileName = e->GetTitle();

		string outFileName = (File(inFileName).base() % tag.Data()).path();
		cerr << "Mapping " << inFileName << ":" << treeName << " to " << outFileName << endl;

		TFile inFile(inFileName.c_str(), "read");
		TTree *inTree; inFile.GetObject(treeName.c_str(), inTree);

		TFile outFile(outFileName.c_str(), "recreate");

		TSelector *sel = TSelector::GetSelector(selector.Data());
		if (sel == 0) throw runtime_error(string("Cannot load selector ") + selector.Data());
		inTree->Process(sel);
		delete sel;

		TObjArray* keeps = keep.Tokenize(",");
		for (int i = 0; i < keeps->GetEntriesFast(); ++i) {
			TString keepObjName = dynamic_cast<TObjString*>(keeps->At(i))->GetString().Strip(TString::kBoth);
			cerr << "Copying object " << keepObjName << " to output" << endl;
			copyObject(&inFile, keepObjName);
		}
		delete keeps;

		Settings::writeToGDirectory();
		outFile.Write();
		outFile.Close();
		inFile.Close();
	}
}

void Selector::mapSingle(const TString &inFileName, const TString &mappers, const TString &outFileName, bool noRecompile) {
	TFile inFile(inFileName.Data(), "read");
	TFile outFile(outFileName.Data(), "recreate");

	TPRegexp mapperSpecExpr("^(.*)\\((.*)\\)$");
	TPRegexp xxExp("\\+\\+$");

	TObjArray* mapperNames = mappers.Tokenize(",");
	for (int mapperEntry = 0; mapperEntry < mapperNames->GetEntriesFast(); ++mapperEntry) {
		TString mapper = dynamic_cast<TObjString*>(mapperNames->At(mapperEntry))->GetString().Strip(TString::kBoth);
		TObjArray* matches = mapperSpecExpr.MatchS(mapper);
		if (matches->GetEntriesFast() == 3) {
			TString fctName = dynamic_cast<TObjString*>(matches->At(1))->GetString();
			if (noRecompile) xxExp.Substitute(fctName, "+");
			TString objName = dynamic_cast<TObjString*>(matches->At(2))->GetString();
			assert ((fctName != 0) && (objName != 0));
			delete matches;

			cerr << "Applying " << fctName << "(" << objName << ")" << endl;

			TObject *inObj; inFile.GetObject(objName.Data(), inObj);
			if (inObj != 0) {
				TTree *inTree = dynamic_cast<TTree*>(inObj);
				if (inTree != 0) {
					if (fctName == "copy") {
						TTree *copied = inTree->CloneTree();
						copied->Write();
					} else {
						TSelector *sel = TSelector::GetSelector(fctName.Data());
						if (sel == 0) throw runtime_error(string("Cannot load selector ") + fctName.Data());
						inTree->Process(sel);
						delete sel;
					}
				} else throw invalid_argument(string("Objects of type ") + inObj->Class()->GetName() + " not supported yet");
			} else {
				delete matches;
				throw runtime_error(string("Object ") + objName.Data() + " not found in TDirectory");
			}
		} else {
			delete matches;
			throw invalid_argument(string("Invalid mapper specification: \"") + mapper.Data() + "\"");
		}
	}
	delete mapperNames;

	Settings::writeToGDirectory();
	outFile.Write();
	outFile.Close();
	inFile.Close();
}

void Selector::mapMulti(const TString &fileName, const TString &mappers, const TString &tag, bool noRecompile) {
	cerr << TString::Format("Selector::map(%s, %s, %s)", fileName.Data(), mappers.Data(), tag.Data()) << endl;

	TChain chain("");
	chain.Add(fileName.Data());
	TObjArray *chainElems = chain.GetListOfFiles();
	for (int chainEntry = 0; chainEntry < chainElems->GetEntriesFast(); ++chainEntry) {
		TChainElement *e = dynamic_cast<TChainElement*>(chainElems->At(chainEntry));
		string inFileName = e->GetTitle();

		string outFileName = (File(inFileName).base() % tag.Data()).path();
		cerr << "Mapping " << inFileName << " to " << outFileName << endl;
		// Don't recompile even if fct ends with "++" after first run:
		mapSingle(inFileName, mappers, outFileName, (chainEntry > 0) || noRecompile);
	}
	cerr << "Selector::map(...) finished" << endl;
}

} // namespace froast
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <fnord-base/util/BinaryMessageReader.h>
#include <fnord-base/util/BinaryMessageWriter.h>
#include "CTRCounter.h"

using namespace fnord;

namespace cm {

CTRCounter CTRCounter::load(const Buffer& buf) {
  CTRCounter counter;

  util::BinaryMessageReader reader(buf.data(), buf.size());
  counter.num_views = *reader.readUInt64();
  counter.num_clicks = *reader.readUInt64();

  return counter;
}

void CTRCounter::write(const CTRCounter& counter, Buffer* buf) {
  util::BinaryMessageWriter writer(sizeof(CTRCounter));
  writer.appendUInt64(counter.num_views);
  writer.appendUInt64(counter.num_clicks);
  buf->append(writer.data(), writer.size());
}

CTRCounter::CTRCounter() :
    num_views(0),
    num_clicks(0) {}

void CTRCounter::merge(const CTRCounter& other) {
  num_views += other.num_views;
  num_clicks += other.num_clicks;
}

}
<commit_msg>include fix<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <fnord-base/util/binarymessagereader.h>
#include <fnord-base/util/binarymessagewriter.h>
#include "CTRCounter.h"

using namespace fnord;

namespace cm {

CTRCounter CTRCounter::load(const Buffer& buf) {
  CTRCounter counter;

  util::BinaryMessageReader reader(buf.data(), buf.size());
  counter.num_views = *reader.readUInt64();
  counter.num_clicks = *reader.readUInt64();

  return counter;
}

void CTRCounter::write(const CTRCounter& counter, Buffer* buf) {
  util::BinaryMessageWriter writer(sizeof(CTRCounter));
  writer.appendUInt64(counter.num_views);
  writer.appendUInt64(counter.num_clicks);
  buf->append(writer.data(), writer.size());
}

CTRCounter::CTRCounter() :
    num_views(0),
    num_clicks(0) {}

void CTRCounter::merge(const CTRCounter& other) {
  num_views += other.num_views;
  num_clicks += other.num_clicks;
}

}
<|endoftext|>


<commit_before>/*********************************************************************************
- Contact:    Brigitte Cheynis     b.cheynis@ipnl.in2p3.fr
- Link:       http
- Raw data test file :
- Reference run number :
- Run Type:   PHYSICS
- DA Type:    MON
- Number of events needed: >=500
- Input Files:  argument list
- Output Files: local files  VZERO_Histos.root, V0_Ped_Width_Gain.dat
                FXS file     V0_Ped_Width_Gain.dat
- Trigger types used: PHYSICS_EVENT
**********************************************************************************/

/**********************************************************************************
*                                                                                *
* VZERO Detector Algorithm used for extracting calibration parameters             *
*                                                                                *
* This program connects to the DAQ data source passed as argument.                *
* It computes calibration parameters, populates local "./V0_Ped_Width_Gain.dat"   *
* file, exports it to the FES, and stores it into DAQ DB                          *
* The program exits when being asked to shut down (daqDA_checkshutdown)           *
* or on End of Run event.                                                         *
* We have 128 channels instead of 64 as expected for V0 due to the two sets of    *
* charge integrators which are used by the FEE ...                                *
*                                                                                *
***********************************************************************************/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

//AliRoot
#include <AliVZERORawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliDAQ.h>

// standard
#include <stdio.h>
#include <stdlib.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include <TFile.h>
#include <TH1F.h>
#include <TMath.h>

Int_t GetOfflineChannel(Int_t channel);

/* Main routine --- Arguments: monitoring data source */

int main(int argc, char **argv) {

/* magic line from Cvetan */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                    "*",
                    "TStreamerInfo",
                    "RIO",
                    "TStreamerInfo()");
  int status;
  if (argc!=2) {
     printf("Wrong number of arguments\n");
     return -1;
  }

  // Online values (using FEE channel numbering):
  Double_t ADCmean[128];
  Double_t ADCsigma[128];
  Double_t PEDmean[128];
  Double_t PEDsigma[128];
  // Offline values(same but ordered as in aliroot for offliners):
  Double_t ADCmean_Off[128];
  Double_t ADCsigma_Off[128];
  Double_t PEDmean_Off[128];
  Double_t PEDsigma_Off[128];

//___________________________________________________
// Get cuts from V00DA.config file

  Int_t    kLowCut;     // = 60;   low cut on signal distribution - to be tuned
  Int_t    kHighCut;    // = 50;   high cut on pedestal distribution - to be tuned

  status = daqDA_DB_getFile("V00DA.config","./V00DA.config");
  if (status) {
      printf("Failed to get config file (V00DA.config) from DAQ DB, status=%d\n", status);
      return -1;
  }
  /* open the config file and retrieve cuts */
  FILE *fpConfig = fopen("V00DA.config","r");
  fscanf(fpConfig,"%d %d",&kLowCut,&kHighCut);
  fclose(fpConfig);

  printf("LowCut on signal = %d ; HighCut on pedestal = %d\n",kLowCut,kHighCut);

//___________________________________________________
// Book HISTOGRAMS - dynamics of p-p collisions -

  char     ADCname[6];
  char     PEDname[6];
  TH1F     *hADCname[128];
  TH1F     *hPEDname[128];

  char  texte[12];
  for (Int_t i=0; i<128; i++) {
       sprintf(ADCname,"hADC%d",i);
       sprintf(texte,"ADC cell%d",i);
       hADCname[i]  = new TH1F(ADCname,texte,1024,-0.5, 1023.5);
       sprintf(PEDname,"hPED%d",i);
       sprintf(texte,"PED cell%d",i);
       hPEDname[i]  = new TH1F(PEDname,texte,1024,-0.5, 1023.5);
  }
//___________________________________________________

  /* open result file to be exported to FES */
  FILE *fp=NULL;
  fp=fopen("./V0_Ped_Width_Gain.dat","w");
  if (fp==NULL) {
      printf("Failed to open result file\n");
      return -1;}

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
     printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
     return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* init counters on events */
  int nevents_physics=0;
  int nevents_total=0;

  /* loop on events (infinite) */
  for(;;) {
      struct eventHeaderStruct *event;
      eventTypeType eventT;

      /* check shutdown condition */
      if (daqDA_checkShutdown()) {break;}

      /* get next event (blocking call until timeout) */
      status=monitorGetEventDynamic((void **)&event);
      if (status==MON_ERR_EOF) {
          printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
      }

      if (status!=0) {
           printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
      }

      /* retry if got no event */
      if (event==NULL) continue;

      /* decode event */
      eventT=event->eventType;

      switch (event->eventType){

      case START_OF_RUN:
           break;

      case END_OF_RUN:
           printf("End Of Run detected\n");
           break;

      case PHYSICS_EVENT:
           nevents_physics++;

	   AliRawReader *rawReader = new AliRawReaderDate((void*)event);

	   AliVZERORawStream* rawStream  = new AliVZERORawStream(rawReader);
	   rawStream->Next();
           for(Int_t i=0; i<64; i++) {
	   	Int_t nFlag = 0;
		for(Int_t j=0; j<21; j++) {
		   if((rawStream->GetBBFlag(i,j)) || (rawStream->GetBGFlag(i,j))) nFlag++;
		}
		if(nFlag == 0){       // Pedestal
		   for(Int_t j=5;j<16;j++){
		       Int_t Integrator = rawStream->GetIntegratorFlag(i,j);
		       Float_t pedestal = (float)(rawStream->GetPedestal(i,j));
		       hPEDname[i + 64 * Integrator]->Fill(pedestal);
		   }
		}
		if((rawStream->GetBBFlag(i,10)) || (rawStream->GetBGFlag(i,10))){ // Charge
		    Int_t Integrator = rawStream->GetIntegratorFlag(i,10);
		    Float_t charge = (float)(rawStream->GetADC(i));
		    hADCname[i + 64 * Integrator]->Fill(charge);
		}
           }
           delete rawStream;
           rawStream = 0x0;
           delete rawReader;
           rawReader = 0x0;
      } // end of switch on event type

      nevents_total++;
      /* free resources */
      free(event);

      /* exit when last event received, no need to wait for TERM signal */
      if (eventT==END_OF_RUN) {
           printf("End Of Run event detected\n");
      break;
    }

  }  // loop over events

  printf("%d physics events processed\n",nevents_physics);

//___________________________________________________________________________
//  Computes mean values, converts FEE channels into Offline AliRoot channels
//  and dumps the ordered values into the output text file for SHUTTLE

  for(Int_t i=0; i<128; i++) {
      hPEDname[i]->GetXaxis()->SetRange(0,kHighCut);
      PEDmean[i]  = hPEDname[i]->GetMean();
      PEDsigma[i] = hPEDname[i]->GetRMS();
      hADCname[i]->GetXaxis()->SetRange(kLowCut,1024);
      ADCmean[i]  = hADCname[i]->GetMean();
      ADCsigma[i] = hADCname[i]->GetRMS();
//      printf(" i = %d, %.3f %.3f %.3f %.3f\n",i,PEDmean[i],PEDsigma[i],ADCmean[i],ADCsigma[i]);
      if (i < 64) {
          Int_t j = GetOfflineChannel(i);
          PEDmean_Off[j]  = PEDmean[i];
          PEDsigma_Off[j] = PEDsigma[i];
          ADCmean_Off[j]  = ADCmean[i];
          ADCsigma_Off[j] = ADCsigma[i]; }
      else{
          Int_t j = GetOfflineChannel(i-64);
          PEDmean_Off[j+64]  = PEDmean[i];
          PEDsigma_Off[j+64] = PEDsigma[i];
          ADCmean_Off[j+64]  = ADCmean[i];
          ADCsigma_Off[j+64] = ADCsigma[i];
      }
  }

  for(Int_t j=0; j<128; j++) {
//      printf(" j = %d, %.3f %.3f %.3f %.3f\n",j,PEDmean_Off[j],PEDsigma_Off[j],
//                                                ADCmean_Off[j],ADCsigma_Off[j]);
      fprintf(fp," %.3f %.3f %.3f %.3f\n",PEDmean_Off[j],PEDsigma_Off[j],
                                          ADCmean_Off[j],ADCsigma_Off[j]);
  }

//________________________________________________________________________
// Write root file with histos for users further check - just in case -

  TFile *histoFile = new TFile("VZERO_histos.root","RECREATE");

  for (Int_t i=0; i<128; i++) {
       hADCname[i]->GetXaxis()->SetRange(0,1024);
       hADCname[i]->Write();
       hPEDname[i]->Write(); }

  histoFile->Close();
  delete histoFile;

//________________________________________________________________________

  /* close result file */
  fclose(fp);

  /* export result file to FES */
  status=daqDA_FES_storeFile("./V0_Ped_Width_Gain.dat","V00da_results");
  if (status)    {
      printf("Failed to export file : %d\n",status);
      return -1; }

  /* store result file into Online DB */
  status=daqDA_DB_storeFile("./V0_Ped_Width_Gain.dat","V00da_results");
  if (status)    {
      printf("Failed to store file into Online DB: %d\n",status);
      return -1; }

  return status;
}

 Int_t GetOfflineChannel(Int_t channel) {

// Channel mapping Online - Offline:

 Int_t fOfflineChannel[64] = {39, 38, 37, 36, 35, 34, 33, 32,
                              47, 46, 45, 44, 43, 42, 41, 40,
			      55, 54, 53, 52, 51, 50, 49, 48,
			      63, 62, 61, 60, 59, 58, 57, 56,
			       7,  6,  5,  4,  3,  2,  1,  0,
			      15, 14, 13, 12, 11, 10,  9,  8,
			      23, 22, 21, 20, 19, 18, 17, 16,
			      31, 30, 29, 28, 27, 26, 25, 24};
 return	fOfflineChannel[channel];
}
<commit_msg>Online Pedestals dumped into local DB file<commit_after>/*********************************************************************************
- Contact:    Brigitte Cheynis     b.cheynis@ipnl.in2p3.fr
- Link:       http
- Raw data test file :
- Reference run number :
- Run Type:   PHYSICS
- DA Type:    MON
- Number of events needed: >=500
- Input Files:  argument list
- Output Files: local files  VZERO_Histos.root, V0_Pedestals.dat (Online mapping)
                FXS file     V0_Ped_Width_Gain.dat (Offline mapping)
- Trigger types used: PHYSICS_EVENT
**********************************************************************************/

/**********************************************************************************
*                                                                                *
* VZERO Detector Algorithm used for extracting calibration parameters             *
*                                                                                *
* This program connects to the DAQ data source passed as argument.                *
* It computes calibration parameters, populates local "./V0_Ped_Width_Gain.dat"   *
* file, exports it to the FES, and stores it into DAQ DB                          *
* The program exits when being asked to shut down (daqDA_checkshutdown)           *
* or on End of Run event.                                                         *
* We have 128 channels instead of 64 as expected for V0 due to the two sets of    *
* charge integrators which are used by the FEE ...                                *
*                                                                                *
***********************************************************************************/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

//AliRoot
#include <AliVZERORawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliDAQ.h>

// standard
#include <stdio.h>
#include <stdlib.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include <TFile.h>
#include <TH1F.h>
#include <TMath.h>

Int_t GetOfflineChannel(Int_t channel);

/* Main routine --- Arguments: monitoring data source */

int main(int argc, char **argv) {

/* magic line from Cvetan */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                    "*",
                    "TStreamerInfo",
                    "RIO",
                    "TStreamerInfo()");
  int status;
  if (argc!=2) {
     printf("Wrong number of arguments\n");
     return -1;
  }

  // Online values (using FEE channel numbering),
  // stored into local V0_Pedestals.dat:
  Double_t ADCmean[128];
  Double_t ADCsigma[128];
  Double_t PEDmean[128];
  Double_t PEDsigma[128];
  // Offline values(same but ordered as in aliroot for offliners)
  // stored into V0_Ped_Width_Gain.dat:
  Double_t ADCmean_Off[128];
  Double_t ADCsigma_Off[128];
  Double_t PEDmean_Off[128];
  Double_t PEDsigma_Off[128];

//___________________________________________________
// Get cuts from V00DA.config file

  Int_t    kLowCut;     // = 60;   low cut on signal distribution - to be tuned
  Int_t    kHighCut;    // = 50;   high cut on pedestal distribution - to be tuned

  status = daqDA_DB_getFile("V00DA.config","./V00DA.config");
  if (status) {
      printf("Failed to get config file (V00DA.config) from DAQ DB, status=%d\n", status);
      return -1;
  }
  /* open the config file and retrieve cuts */
  FILE *fpConfig = fopen("V00DA.config","r");
  fscanf(fpConfig,"%d %d",&kLowCut,&kHighCut);
  fclose(fpConfig);

  printf("LowCut on signal = %d ; HighCut on pedestal = %d\n",kLowCut,kHighCut);

//___________________________________________________
// Book HISTOGRAMS - dynamics of p-p collisions -

  char     ADCname[6];
  char     PEDname[6];
  TH1F     *hADCname[128];
  TH1F     *hPEDname[128];

  char  texte[12];
  for (Int_t i=0; i<128; i++) {
       sprintf(ADCname,"hADC%d",i);
       sprintf(texte,"ADC cell%d",i);
       hADCname[i]  = new TH1F(ADCname,texte,1024,-0.5, 1023.5);
       sprintf(PEDname,"hPED%d",i);
       sprintf(texte,"PED cell%d",i);
       hPEDname[i]  = new TH1F(PEDname,texte,1024,-0.5, 1023.5);
  }
//___________________________________________________

  /* open result file to be exported to FES */
  FILE *fpLocal=NULL;
  fpLocal=fopen("./V0_Pedestals.dat","w");
  if (fpLocal==NULL) {
      printf("Failed to open local result file\n");
      return -1;}

  /* open result file to be exported to FES */
  FILE *fp=NULL;
  fp=fopen("./V0_Ped_Width_Gain.dat","w");
  if (fp==NULL) {
      printf("Failed to open result file\n");
      return -1;}

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
     printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
     return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* init counters on events */
  int nevents_physics=0;
  int nevents_total=0;

  /* loop on events (infinite) */
  for(;;) {
      struct eventHeaderStruct *event;
      eventTypeType eventT;

      /* check shutdown condition */
      if (daqDA_checkShutdown()) {break;}

      /* get next event (blocking call until timeout) */
      status=monitorGetEventDynamic((void **)&event);
      if (status==MON_ERR_EOF) {
          printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
      }

      if (status!=0) {
           printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
      }

      /* retry if got no event */
      if (event==NULL) continue;

      /* decode event */
      eventT=event->eventType;

      switch (event->eventType){

      case START_OF_RUN:
           break;

      case END_OF_RUN:
           printf("End Of Run detected\n");
           break;

      case PHYSICS_EVENT:
           nevents_physics++;

	   AliRawReader *rawReader = new AliRawReaderDate((void*)event);

	   AliVZERORawStream* rawStream  = new AliVZERORawStream(rawReader);
	   rawStream->Next();
           for(Int_t i=0; i<64; i++) {
	   	Int_t nFlag = 0;
		for(Int_t j=0; j<21; j++) {
		   if((rawStream->GetBBFlag(i,j)) || (rawStream->GetBGFlag(i,j))) nFlag++;
		}
		if(nFlag == 0){       // Pedestal
		   for(Int_t j=5;j<16;j++){
		       Int_t Integrator = rawStream->GetIntegratorFlag(i,j);
		       Float_t pedestal = (float)(rawStream->GetPedestal(i,j));
		       hPEDname[i + 64 * Integrator]->Fill(pedestal);
		   }
		}
		if((rawStream->GetBBFlag(i,10)) || (rawStream->GetBGFlag(i,10))){ // Charge
		    Int_t Integrator = rawStream->GetIntegratorFlag(i,10);
		    Float_t charge = (float)(rawStream->GetADC(i));
		    hADCname[i + 64 * Integrator]->Fill(charge);
		}
           }
           delete rawStream;
           rawStream = 0x0;
           delete rawReader;
           rawReader = 0x0;
      } // end of switch on event type

      nevents_total++;
      /* free resources */
      free(event);

      /* exit when last event received, no need to wait for TERM signal */
      if (eventT==END_OF_RUN) {
           printf("End Of Run event detected\n");
      break;
    }

  }  // loop over events

  printf("%d physics events processed\n",nevents_physics);

//___________________________________________________________________________
//  Computes mean values, converts FEE channels into Offline AliRoot channels
//  and dumps the ordered values into the output text file for SHUTTLE

  for(Int_t i=0; i<128; i++) {
      hPEDname[i]->GetXaxis()->SetRange(0,kHighCut);
      PEDmean[i]  = hPEDname[i]->GetMean();
      PEDsigma[i] = hPEDname[i]->GetRMS();
      hADCname[i]->GetXaxis()->SetRange(kLowCut,1024);
      ADCmean[i]  = hADCname[i]->GetMean();
      ADCsigma[i] = hADCname[i]->GetRMS();
//      printf(" i = %d, %.3f %.3f %.3f %.3f\n",i,PEDmean[i],PEDsigma[i],ADCmean[i],ADCsigma[i]);
      fprintf(fpLocal," %.3f %.3f %.3f %.3f\n",PEDmean[i],PEDsigma[i],
                                               ADCmean[i],ADCsigma[i]);
      if (i < 64) {
          Int_t j = GetOfflineChannel(i);
          PEDmean_Off[j]  = PEDmean[i];
          PEDsigma_Off[j] = PEDsigma[i];
          ADCmean_Off[j]  = ADCmean[i];
          ADCsigma_Off[j] = ADCsigma[i]; }
      else{
          Int_t j = GetOfflineChannel(i-64);
          PEDmean_Off[j+64]  = PEDmean[i];
          PEDsigma_Off[j+64] = PEDsigma[i];
          ADCmean_Off[j+64]  = ADCmean[i];
          ADCsigma_Off[j+64] = ADCsigma[i];
      }
  }

  for(Int_t j=0; j<128; j++) {
//      printf(" j = %d, %.3f %.3f %.3f %.3f\n",j,PEDmean_Off[j],PEDsigma_Off[j],
//                                                ADCmean_Off[j],ADCsigma_Off[j]);
      fprintf(fp," %.3f %.3f %.3f %.3f\n",PEDmean_Off[j],PEDsigma_Off[j],
                                          ADCmean_Off[j],ADCsigma_Off[j]);
  }

//________________________________________________________________________
// Write root file with histos for users further check - just in case -

  TFile *histoFile = new TFile("VZERO_histos.root","RECREATE");

  for (Int_t i=0; i<128; i++) {
       hADCname[i]->GetXaxis()->SetRange(0,1024);
       hADCname[i]->Write();
       hPEDname[i]->Write(); }

  histoFile->Close();
  delete histoFile;

//________________________________________________________________________

  /* close local result file and FXS result file*/
  fclose(fpLocal);
  fclose(fp);

  /* export result file to FES */
  status=daqDA_FES_storeFile("./V0_Ped_Width_Gain.dat","V00da_results");
  if (status)    {
      printf("Failed to export file : %d\n",status);
      return -1; }

  /* store result file into Online DB */
  status=daqDA_DB_storeFile("./V0_Pedestals.dat","V00da_results");
  if (status)    {
      printf("Failed to store file into Online DB: %d\n",status);
      return -1; }

  return status;
}

 Int_t GetOfflineChannel(Int_t channel) {

// Channel mapping Online - Offline:

 Int_t fOfflineChannel[64] = {39, 38, 37, 36, 35, 34, 33, 32,
                              47, 46, 45, 44, 43, 42, 41, 40,
			      55, 54, 53, 52, 51, 50, 49, 48,
			      63, 62, 61, 60, 59, 58, 57, 56,
			       7,  6,  5,  4,  3,  2,  1,  0,
			      15, 14, 13, 12, 11, 10,  9,  8,
			      23, 22, 21, 20, 19, 18, 17, 16,
			      31, 30, 29, 28, 27, 26, 25, 24};
 return	fOfflineChannel[channel];
}
<|endoftext|>


<commit_before>//
//  Sonifier.cpp
//  PlaySPLOM
//
//  Created by Chris Sattinger on 23/10/15.
//  Copyright 2015 Chris Sattinger
//

#include <string>
#include "Sonifier.hpp"
#include "mapping.hpp"

void SynthDefMapping::init(SynthDef argSynthDef) {
    synthDef = argSynthDef;
    // guess default x y from synthDefs args
    for (auto control : synthDef.controls) {
        if (control.name == "out") {
            continue;
        }
        if (control.name == "amp") {
            continue;
        }
        if (control.name == "sustain") {
            continue;
        }
        if (control.name == "freq") {
            yArg = control.name;
            yMap = FREQ;
            continue;
        }
        if (xArg.empty()) {
            xArg = control.name;
            continue;
        }
        if (yArg.empty()) {
            yArg = control.name;
            continue;
        }
    }
    if (xArg.empty()) {
        xArg = "pan";
    }
    if (yArg.empty()) {
        yArg = "sustain";
    }
}

double SynthDefMapping::map(double v, double freqBase, string const &argName, MappingAlgo algo) {
    auto spec = synthDef.specAt(argName);
    switch (algo) {
        case FREQ:
            return expMul(freqBase, v);
            break;
        case EXP:
            // temp
            return expMul(freqBase, v);
            break;
        case LINEAR:
        default:
            return linlin(v, spec.minval, spec.maxval);
            break;
    }
}

void Sonifier::setup() {
    ofAddListener(PointsEvent::events, this, &Sonifier::pointsEntered);
}

void Sonifier::pointsEntered(PointsEvent &event) {
    if (event.type == PointsEventType::entering) {
        auto normalizedPoints = scatterPlots->normalizedPointsAtBox(event.coords);
        for (auto p : event.points) {
            std::cout << event.coords.m << "@" << event.coords.n << "::" << p << std::endl;
            sonifyPoint(normalizedPoints.at(p));
        }
    }
}

/**
  * sonify a normalized point with .x and .y
  * using current sound settings
  */
void Sonifier::sonifyPoint(ofPoint const &point) {
    SynthArgs args;
    args["out"] = 0;
    // was 0.1 or scaled to num points sounding
    args["amp"] = amp;
    // slider sustain
    args["sustain"] = sustain;

    SynthDefMapping mapping = mappings[synthDef.name];
    args[mapping.xArg] = mapping.map(point.x, freqBase, mapping.xArg, mapping.xMap);
    args[mapping.yArg] = mapping.map(point.y, freqBase, mapping.yArg, mapping.yMap);

    std::cout << synthDef.name << endl;
    superCollider->grain(synthDef.name, args);
}

void Sonifier::selectSynthDef(int i) {
    if (i < superCollider->synthDefs.size()) {
        synthDef = superCollider->synthDefs[i];
        if (mappings.count(synthDef.name) == 0) {
            SynthDefMapping sdm = SynthDefMapping();
            sdm.init(synthDef);
            mappings[synthDef.name] = sdm;
        }
    }
}

string Sonifier::sound() {
    return synthDef.name;
}
<commit_msg>fix: sonifier was mapping wrong direction; i.e. min..max => 0..1<commit_after>//
//  Sonifier.cpp
//  PlaySPLOM
//
//  Created by Chris Sattinger on 23/10/15.
//  Copyright 2015 Chris Sattinger
//

#include <string>
#include "Sonifier.hpp"
#include "mapping.hpp"

void SynthDefMapping::init(SynthDef argSynthDef) {
    synthDef = argSynthDef;
    // guess default x y from synthDefs args
    for (auto control : synthDef.controls) {
        if (control.name == "out") {
            continue;
        }
        if (control.name == "amp") {
            continue;
        }
        if (control.name == "sustain") {
            continue;
        }
        if (control.name == "freq") {
            yArg = control.name;
            yMap = FREQ;
            continue;
        }
        if (xArg.empty()) {
            xArg = control.name;
            continue;
        }
        if (yArg.empty()) {
            yArg = control.name;
            continue;
        }
    }
    if (xArg.empty()) {
        xArg = "pan";
    }
    if (yArg.empty()) {
        yArg = "sustain";
    }
}

double SynthDefMapping::map(double v, double freqBase, string const &argName, MappingAlgo algo) {
    auto spec = synthDef.specAt(argName);
    switch (algo) {
        case FREQ:
            return expMul(freqBase, v);
            break;
        case EXP:
            // temp
            return expMul(freqBase, v);
            break;
        case LINEAR:
        default:
            return linlin(v, 0.0, 1.0, spec.minval, spec.maxval);
            break;
    }
}

void Sonifier::setup() {
    ofAddListener(PointsEvent::events, this, &Sonifier::pointsEntered);
}

void Sonifier::pointsEntered(PointsEvent &event) {
    if (event.type == PointsEventType::entering) {
        auto normalizedPoints = scatterPlots->normalizedPointsAtBox(event.coords);
        for (auto p : event.points) {
            std::cout << event.coords.m << "@" << event.coords.n << "::" << p << std::endl;
            sonifyPoint(normalizedPoints.at(p));
        }
    }
}

/**
  * sonify a normalized point with .x and .y
  * using current sound settings
  */
void Sonifier::sonifyPoint(ofPoint const &point) {
    SynthArgs args;
    args["out"] = 0;
    // was 0.1 or scaled to num points sounding
    args["amp"] = amp;
    // slider sustain
    args["sustain"] = sustain;

    SynthDefMapping mapping = mappings[synthDef.name];
    args[mapping.xArg] = mapping.map(point.x, freqBase, mapping.xArg, mapping.xMap);
    args[mapping.yArg] = mapping.map(point.y, freqBase, mapping.yArg, mapping.yMap);

    std::cout << synthDef.name << endl;
    superCollider->grain(synthDef.name, args);
}

void Sonifier::selectSynthDef(int i) {
    if (i < superCollider->synthDefs.size()) {
        synthDef = superCollider->synthDefs[i];
        if (mappings.count(synthDef.name) == 0) {
            SynthDefMapping sdm = SynthDefMapping();
            sdm.init(synthDef);
            mappings[synthDef.name] = sdm;
        }
    }
}

string Sonifier::sound() {
    return synthDef.name;
}
<|endoftext|>