<commit_before>#include "opengl.hpp"

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

#include "SDL.h"

// Include standard headers
#include <iostream> // std::cout, std::cin, std::cerr

namespace yli
{
    namespace opengl
    {
        bool init_window()
        {
            if (SDL_Init(SDL_INIT_VIDEO) < 0)
            {
                std::cerr << "Failed to initialize SDL.\n";
                return false;
            }

            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
            return true;
        }

        SDL_Window* create_window(const int window_width, const int window_height, const char* const title)
        {
            return SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_width, window_height, SDL_WINDOW_OPENGL);
        }

        int set_window_windowed(SDL_Window* window)
        {
            SDL_SetWindowFullscreen(window, 0);
        }

        void make_context_current(SDL_Window* window, SDL_GLContext context)
        {
            SDL_GL_MakeCurrent(window, context);
        }

        bool init_glew()
        {
            if (glewInit() != GLEW_OK)
            {
                std::cerr << "Failed to initialize GLEW.\n";
                return false;
            }
            return true;
        }

        void enable_depth_test()
        {
            // Enable depth test.
            glEnable(GL_DEPTH_TEST);
        }

        void disable_depth_test()
        {
            // Disable depth test.
            glDisable(GL_DEPTH_TEST);
        }

        void set_depth_func_to_less()
        {
            // Accept a fragment if it closer to the camera than the former one.
            glDepthFunc(GL_LESS);
        }

        void cull_triangles()
        {
            // Cull triangles whose normal is not towards the camera.
            glEnable(GL_CULL_FACE);
        }

        void set_background_color(const float red, const float green, const float blue, const float alpha)
        {
            glClearColor(
                    static_cast<GLclampf>(red),
                    static_cast<GLclampf>(green),
                    static_cast<GLclampf>(blue),
                    static_cast<GLclampf>(alpha));
        }

        void set_wireframe(const bool wireframe)
        {
            if (wireframe)
            {
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
            }
            else
            {
                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
            }
        }
    }
}
<commit_msg>Bugfix: `yli::opengl::set_window_windowed`: `return` value.<commit_after>#include "opengl.hpp"

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

#include "SDL.h"

// Include standard headers
#include <iostream> // std::cout, std::cin, std::cerr

namespace yli
{
    namespace opengl
    {
        bool init_window()
        {
            if (SDL_Init(SDL_INIT_VIDEO) < 0)
            {
                std::cerr << "Failed to initialize SDL.\n";
                return false;
            }

            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
            return true;
        }

        SDL_Window* create_window(const int window_width, const int window_height, const char* const title)
        {
            return SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_width, window_height, SDL_WINDOW_OPENGL);
        }

        int set_window_windowed(SDL_Window* window)
        {
            return SDL_SetWindowFullscreen(window, 0);
        }

        void make_context_current(SDL_Window* window, SDL_GLContext context)
        {
            SDL_GL_MakeCurrent(window, context);
        }

        bool init_glew()
        {
            if (glewInit() != GLEW_OK)
            {
                std::cerr << "Failed to initialize GLEW.\n";
                return false;
            }
            return true;
        }

        void enable_depth_test()
        {
            // Enable depth test.
            glEnable(GL_DEPTH_TEST);
        }

        void disable_depth_test()
        {
            // Disable depth test.
            glDisable(GL_DEPTH_TEST);
        }

        void set_depth_func_to_less()
        {
            // Accept a fragment if it closer to the camera than the former one.
            glDepthFunc(GL_LESS);
        }

        void cull_triangles()
        {
            // Cull triangles whose normal is not towards the camera.
            glEnable(GL_CULL_FACE);
        }

        void set_background_color(const float red, const float green, const float blue, const float alpha)
        {
            glClearColor(
                    static_cast<GLclampf>(red),
                    static_cast<GLclampf>(green),
                    static_cast<GLclampf>(blue),
                    static_cast<GLclampf>(alpha));
        }

        void set_wireframe(const bool wireframe)
        {
            if (wireframe)
            {
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
            }
            else
            {
                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
            }
        }
    }
}
<|endoftext|>


<commit_before>/*!
 * \copy
 *     Copyright (c)  2009-2013, Cisco Systems
 *     All rights reserved.
 *
 *     Redistribution and use in source and binary forms, with or without
 *     modification, are permitted provided that the following conditions
 *     are met:
 *
 *        * Redistributions of source code must retain the above copyright
 *          notice, this list of conditions and the following disclaimer.
 *
 *        * Redistributions in binary form must reproduce the above copyright
 *          notice, this list of conditions and the following disclaimer in
 *          the documentation and/or other materials provided with the
 *          distribution.
 *
 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *     POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * \file	crt_utils_safe_x.cpp
 *
 * \brief	common tool/function utilization
 *
 * \date	03/10/2009 Created
 *
 *************************************************************************************
 */

#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#if defined(_WIN32)
#include <windows.h>
#include <sys/types.h>
#include <sys/timeb.h>
#ifndef _MSC_VER
#include <sys/time.h>
#endif //!_MSC_VER
#else
#include <sys/time.h>
#include <sys/timeb.h>
#endif //_WIN32

#include "macros.h"
#include "crt_util_safe_x.h"	// Safe CRT routines like utils for cross platforms

#if  defined(_WIN32) && defined(_MSC_VER)

#if  defined(_MSC_VER) && (_MSC_VER>=1500)

int32_t WelsSnprintf (str_t* pBuffer,  int32_t iSizeOfBuffer, const str_t* kpFormat, ...) {
  va_list  pArgPtr;
  int32_t  iRc;

  va_start (pArgPtr, kpFormat);

  iRc = vsnprintf_s (pBuffer, iSizeOfBuffer, _TRUNCATE, kpFormat, pArgPtr);

  va_end (pArgPtr);

  return iRc;
}

str_t* WelsStrncpy (str_t* pDest, int32_t iSizeInBytes, const str_t* kpSrc, int32_t iCount) {
  strncpy_s (pDest, iSizeInBytes, kpSrc, iCount);

  return pDest;
}

int32_t WelsVsnprintf (str_t* pBuffer, int32_t iSizeOfBuffer, const str_t* kpFormat, va_list pArgPtr) {
  return vsnprintf_s (pBuffer, iSizeOfBuffer, _TRUNCATE, kpFormat, pArgPtr);
}

WelsFileHandle* WelsFopen (const str_t* kpFilename,  const str_t* kpMode) {
  WelsFileHandle* pFp = NULL;
  if (fopen_s (&pFp, kpFilename, kpMode) != 0) {
    return NULL;
  }

  return pFp;
}

int32_t WelsFclose (WelsFileHandle* pFp) {
  return fclose (pFp);
}

int32_t WelsGetTimeOfDay (SWelsTime* pTp) {
  return _ftime_s (pTp);
}

int32_t WelsStrftime (str_t* pBuffer, int32_t iSize, const str_t* kpFormat, const SWelsTime* kpTp) {
  struct tm   sTimeNow;
  int32_t iRc;

  localtime_s (&sTimeNow, &kpTp->time);

  iRc = strftime (pBuffer, iSize, kpFormat, &sTimeNow);
  if (iRc == 0)
      pBuffer[0] = '\0';
  return iRc;
}

#else

int32_t WelsSnprintf (str_t* pBuffer,  int32_t iSizeOfBuffer, const str_t* kpFormat, ...) {
  va_list pArgPtr;
  int32_t iRc;

  va_start (pArgPtr, kpFormat);

  iRc = vsnprintf (pBuffer, iSizeOfBuffer, kpFormat, pArgPtr); //confirmed_safe_unsafe_usage
  if (iRc < 0)
    pBuffer[iSizeOfBuffer - 1] = '\0';

  va_end (pArgPtr);

  return iRc;
}

str_t* WelsStrncpy (str_t* pDest, int32_t iSizeInBytes, const str_t* kpSrc, int32_t iCount) {
  strncpy (pDest, kpSrc, iCount); //confirmed_safe_unsafe_usage

  return pDest;
}

int32_t WelsVsnprintf (str_t* pBuffer, int32_t iSizeOfBuffer, const str_t* kpFormat, va_list pArgPtr) {
  int32_t iRc = vsnprintf (pBuffer, iSizeOfBuffer, kpFormat, pArgPtr); //confirmed_safe_unsafe_usage
  if (iRc < 0)
    pBuffer[iSizeOfBuffer - 1] = '\0';
  return iRc;
}

WelsFileHandle* WelsFopen (const str_t* kpFilename,  const str_t* kpMode) {
  return fopen (kpFilename, kpMode);
}

int32_t WelsFclose (WelsFileHandle* pFp) {
  return fclose (pFp);
}

int32_t WelsGetTimeOfDay (SWelsTime* pTp) {
  _ftime (pTp);
  return 0;
}

int32_t WelsStrftime (str_t* pBuffer, int32_t iSize, const str_t* kpFormat, const SWelsTime* kpTp) {
  struct tm*   pTnow;
  int32_t iRc;

  pTnow = localtime (&kpTp->time);

  iRc = strftime (pBuffer, iSize, kpFormat, pTnow);
  if (iRc == 0)
      pBuffer[0] = '\0';
  return iRc;
}

#endif // _MSC_VER

#else  //GCC

int32_t WelsSnprintf (str_t* pBuffer,  int32_t iSizeOfBuffer, const str_t* kpFormat, ...) {
  va_list pArgPtr;
  int32_t iRc;

  va_start (pArgPtr, kpFormat);

  iRc = vsnprintf (pBuffer, iSizeOfBuffer, kpFormat, pArgPtr);

  va_end (pArgPtr);

  return iRc;
}

str_t* WelsStrncpy (str_t* pDest, int32_t iSizeInBytes, const str_t* kpSrc, int32_t iCount) {
  return strncpy (pDest, kpSrc, iCount); //confirmed_safe_unsafe_usage
}

int32_t WelsVsnprintf (str_t* pBuffer, int32_t iSizeOfBuffer, const str_t* kpFormat, va_list pArgPtr) {
  return vsnprintf (pBuffer, iSizeOfBuffer, kpFormat, pArgPtr); //confirmed_safe_unsafe_usage
}

WelsFileHandle* WelsFopen (const str_t* kpFilename,  const str_t* kpMode) {
  return fopen (kpFilename, kpMode);
}

int32_t WelsFclose (WelsFileHandle*   pFp) {
  return fclose (pFp);
}

int32_t WelsGetTimeOfDay (SWelsTime* pTp) {
  struct timeval  sTv;

  if (gettimeofday (&sTv, NULL)) {
    return -1;
  }

  pTp->time = sTv.tv_sec;
  pTp->millitm = (uint16_t)sTv.tv_usec / 1000;

  return 0;
}

int32_t WelsStrftime (str_t* pBuffer, int32_t iSize, const str_t* kpFormat, const SWelsTime* kpTp) {
  struct tm*   pTnow;
  int32_t iRc;

  pTnow = localtime (&kpTp->time);

  iRc = strftime (pBuffer, iSize, kpFormat, pTnow);
  if (iRc == 0)
      pBuffer[0] = '\0';
  return iRc;
}

#endif

int32_t WelsFwrite (const void_t* kpBuffer, int32_t iSize, int32_t iCount, WelsFileHandle* pFp) {
  return fwrite (kpBuffer, iSize, iCount, pFp);
}

uint16_t WelsGetMillisecond (const SWelsTime* kpTp) {
  return kpTp->millitm;
}

int32_t WelsFseek (WelsFileHandle* fp, int32_t offset, int32_t origin) {
  return fseek(fp, offset, origin);
}

int32_t WelsFflush (WelsFileHandle* pFp) {
  return fflush (pFp);
}
<commit_msg>Fix the implementations of WelsStrncpy<commit_after>/*!
 * \copy
 *     Copyright (c)  2009-2013, Cisco Systems
 *     All rights reserved.
 *
 *     Redistribution and use in source and binary forms, with or without
 *     modification, are permitted provided that the following conditions
 *     are met:
 *
 *        * Redistributions of source code must retain the above copyright
 *          notice, this list of conditions and the following disclaimer.
 *
 *        * Redistributions in binary form must reproduce the above copyright
 *          notice, this list of conditions and the following disclaimer in
 *          the documentation and/or other materials provided with the
 *          distribution.
 *
 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *     POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * \file	crt_utils_safe_x.cpp
 *
 * \brief	common tool/function utilization
 *
 * \date	03/10/2009 Created
 *
 *************************************************************************************
 */

#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#if defined(_WIN32)
#include <windows.h>
#include <sys/types.h>
#include <sys/timeb.h>
#ifndef _MSC_VER
#include <sys/time.h>
#endif //!_MSC_VER
#else
#include <sys/time.h>
#include <sys/timeb.h>
#endif //_WIN32

#include "macros.h"
#include "crt_util_safe_x.h"	// Safe CRT routines like utils for cross platforms

#if  defined(_WIN32) && defined(_MSC_VER)

#if  defined(_MSC_VER) && (_MSC_VER>=1500)

int32_t WelsSnprintf (str_t* pBuffer,  int32_t iSizeOfBuffer, const str_t* kpFormat, ...) {
  va_list  pArgPtr;
  int32_t  iRc;

  va_start (pArgPtr, kpFormat);

  iRc = vsnprintf_s (pBuffer, iSizeOfBuffer, _TRUNCATE, kpFormat, pArgPtr);

  va_end (pArgPtr);

  return iRc;
}

str_t* WelsStrncpy (str_t* pDest, int32_t iSizeInBytes, const str_t* kpSrc, int32_t iCount) {
  strncpy_s (pDest, iSizeInBytes, kpSrc, _TRUNCATE);

  return pDest;
}

int32_t WelsVsnprintf (str_t* pBuffer, int32_t iSizeOfBuffer, const str_t* kpFormat, va_list pArgPtr) {
  return vsnprintf_s (pBuffer, iSizeOfBuffer, _TRUNCATE, kpFormat, pArgPtr);
}

WelsFileHandle* WelsFopen (const str_t* kpFilename,  const str_t* kpMode) {
  WelsFileHandle* pFp = NULL;
  if (fopen_s (&pFp, kpFilename, kpMode) != 0) {
    return NULL;
  }

  return pFp;
}

int32_t WelsFclose (WelsFileHandle* pFp) {
  return fclose (pFp);
}

int32_t WelsGetTimeOfDay (SWelsTime* pTp) {
  return _ftime_s (pTp);
}

int32_t WelsStrftime (str_t* pBuffer, int32_t iSize, const str_t* kpFormat, const SWelsTime* kpTp) {
  struct tm   sTimeNow;
  int32_t iRc;

  localtime_s (&sTimeNow, &kpTp->time);

  iRc = strftime (pBuffer, iSize, kpFormat, &sTimeNow);
  if (iRc == 0)
      pBuffer[0] = '\0';
  return iRc;
}

#else

int32_t WelsSnprintf (str_t* pBuffer,  int32_t iSizeOfBuffer, const str_t* kpFormat, ...) {
  va_list pArgPtr;
  int32_t iRc;

  va_start (pArgPtr, kpFormat);

  iRc = vsnprintf (pBuffer, iSizeOfBuffer, kpFormat, pArgPtr); //confirmed_safe_unsafe_usage
  if (iRc < 0)
    pBuffer[iSizeOfBuffer - 1] = '\0';

  va_end (pArgPtr);

  return iRc;
}

str_t* WelsStrncpy (str_t* pDest, int32_t iSizeInBytes, const str_t* kpSrc, int32_t iCount) {
  strncpy (pDest, kpSrc, iSizeInBytes); //confirmed_safe_unsafe_usage
  pDest[iSizeInBytes - 1] = '\0';

  return pDest;
}

int32_t WelsVsnprintf (str_t* pBuffer, int32_t iSizeOfBuffer, const str_t* kpFormat, va_list pArgPtr) {
  int32_t iRc = vsnprintf (pBuffer, iSizeOfBuffer, kpFormat, pArgPtr); //confirmed_safe_unsafe_usage
  if (iRc < 0)
    pBuffer[iSizeOfBuffer - 1] = '\0';
  return iRc;
}

WelsFileHandle* WelsFopen (const str_t* kpFilename,  const str_t* kpMode) {
  return fopen (kpFilename, kpMode);
}

int32_t WelsFclose (WelsFileHandle* pFp) {
  return fclose (pFp);
}

int32_t WelsGetTimeOfDay (SWelsTime* pTp) {
  _ftime (pTp);
  return 0;
}

int32_t WelsStrftime (str_t* pBuffer, int32_t iSize, const str_t* kpFormat, const SWelsTime* kpTp) {
  struct tm*   pTnow;
  int32_t iRc;

  pTnow = localtime (&kpTp->time);

  iRc = strftime (pBuffer, iSize, kpFormat, pTnow);
  if (iRc == 0)
      pBuffer[0] = '\0';
  return iRc;
}

#endif // _MSC_VER

#else  //GCC

int32_t WelsSnprintf (str_t* pBuffer,  int32_t iSizeOfBuffer, const str_t* kpFormat, ...) {
  va_list pArgPtr;
  int32_t iRc;

  va_start (pArgPtr, kpFormat);

  iRc = vsnprintf (pBuffer, iSizeOfBuffer, kpFormat, pArgPtr);

  va_end (pArgPtr);

  return iRc;
}

str_t* WelsStrncpy (str_t* pDest, int32_t iSizeInBytes, const str_t* kpSrc, int32_t iCount) {
  strncpy (pDest, kpSrc, iSizeInBytes); //confirmed_safe_unsafe_usage
  pDest[iSizeInBytes - 1] = '\0';
  return pDest;
}

int32_t WelsVsnprintf (str_t* pBuffer, int32_t iSizeOfBuffer, const str_t* kpFormat, va_list pArgPtr) {
  return vsnprintf (pBuffer, iSizeOfBuffer, kpFormat, pArgPtr); //confirmed_safe_unsafe_usage
}

WelsFileHandle* WelsFopen (const str_t* kpFilename,  const str_t* kpMode) {
  return fopen (kpFilename, kpMode);
}

int32_t WelsFclose (WelsFileHandle*   pFp) {
  return fclose (pFp);
}

int32_t WelsGetTimeOfDay (SWelsTime* pTp) {
  struct timeval  sTv;

  if (gettimeofday (&sTv, NULL)) {
    return -1;
  }

  pTp->time = sTv.tv_sec;
  pTp->millitm = (uint16_t)sTv.tv_usec / 1000;

  return 0;
}

int32_t WelsStrftime (str_t* pBuffer, int32_t iSize, const str_t* kpFormat, const SWelsTime* kpTp) {
  struct tm*   pTnow;
  int32_t iRc;

  pTnow = localtime (&kpTp->time);

  iRc = strftime (pBuffer, iSize, kpFormat, pTnow);
  if (iRc == 0)
      pBuffer[0] = '\0';
  return iRc;
}

#endif

int32_t WelsFwrite (const void_t* kpBuffer, int32_t iSize, int32_t iCount, WelsFileHandle* pFp) {
  return fwrite (kpBuffer, iSize, iCount, pFp);
}

uint16_t WelsGetMillisecond (const SWelsTime* kpTp) {
  return kpTp->millitm;
}

int32_t WelsFseek (WelsFileHandle* fp, int32_t offset, int32_t origin) {
  return fseek(fp, offset, origin);
}

int32_t WelsFflush (WelsFileHandle* pFp) {
  return fflush (pFp);
}
<|endoftext|>


<commit_before>//=- LiveVariables.cpp - Live Variable Analysis for Source CFGs -*- C++ --*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Live Variables analysis for source-level CFGs.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Basic/SourceManager.h"
#include "clang/AST/Expr.h"
#include "clang/AST/CFG.h"
#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
#include "clang/Analysis/FlowSensitive/DataflowSolver.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Compiler.h"

#include <string.h>
#include <stdio.h>

using namespace clang;

//===----------------------------------------------------------------------===//
// Dataflow initialization logic.
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN RegisterDecls
  : public CFGRecStmtDeclVisitor<RegisterDecls> {

  LiveVariables::AnalysisDataTy& AD;
public:
  RegisterDecls(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
  void VisitVarDecl(VarDecl* VD) { AD.Register(VD); }
  CFG& getCFG() { return AD.getCFG(); }
};
} // end anonymous namespace

LiveVariables::LiveVariables(CFG& cfg, FunctionDecl& FD) {
  getAnalysisData().setCFG(&cfg);

  for (FunctionDecl::param_iterator I=FD.param_begin(), E=FD.param_end();
       I !=E; ++I)
    getAnalysisData().Register(*I);

  // Now register all the other VarDecls;
  RegisterDecls R(getAnalysisData());
  cfg.VisitBlockStmts(R);
}

//===----------------------------------------------------------------------===//
// Transfer functions.
//===----------------------------------------------------------------------===//

namespace {

static const bool Alive = true;
static const bool Dead = false;

class VISIBILITY_HIDDEN TransferFuncs : public CFGRecStmtVisitor<TransferFuncs>{
  LiveVariables::AnalysisDataTy& AD;
  LiveVariables::ValTy LiveState;
public:
  TransferFuncs(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}

  LiveVariables::ValTy& getVal() { return LiveState; }
  CFG& getCFG() { return AD.getCFG(); }

  void VisitDeclRefExpr(DeclRefExpr* DR);
  void VisitBinaryOperator(BinaryOperator* B);
  void VisitAssign(BinaryOperator* B);
  void VisitDeclStmt(DeclStmt* DS);
  void VisitUnaryOperator(UnaryOperator* U);
  void Visit(Stmt *S);
};

void TransferFuncs::Visit(Stmt *S) {
  if (AD.Observer)
    AD.Observer->ObserveStmt(S,AD,LiveState);

  if (S == getCurrentBlkStmt()) {
    if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead;
    StmtVisitor<TransferFuncs,void>::Visit(S);
  }
  else if (!getCFG().isBlkExpr(S))
    StmtVisitor<TransferFuncs,void>::Visit(S);
  else
    // For block-level expressions, mark that they are live.
    LiveState(S,AD) = Alive;
}

void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
  if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
    LiveState(V,AD) = Alive;
}

void TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
  if (B->isAssignmentOp()) VisitAssign(B);
  else VisitStmt(B);
}

void TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
  Expr *E = U->getSubExpr();

  switch (U->getOpcode()) {
  case UnaryOperator::SizeOf: return;
  case UnaryOperator::PostInc:
  case UnaryOperator::PostDec:
  case UnaryOperator::PreInc:
  case UnaryOperator::PreDec:
  case UnaryOperator::AddrOf:
    // Walk through the subexpressions, blasting through ParenExprs
    // until we either find a DeclRefExpr or some non-DeclRefExpr
    // expression.
    if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E->IgnoreParens())) {
      // Treat the --/++/& operator as a kill.
      LiveState(DR->getDecl(),AD) = Dead;
      if (AD.Observer) { AD.Observer->ObserverKill(DR); }
      return VisitDeclRefExpr(DR);
    }

    // Fall-through.

  default:
    return Visit(E);
  }
}

void TransferFuncs::VisitAssign(BinaryOperator* B) {
  Expr* LHS = B->getLHS();

  // Assigning to a variable?
  if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParens())) {
    LiveState(DR->getDecl(),AD) = Dead;
    if (AD.Observer) { AD.Observer->ObserverKill(DR); }

    // Handle things like +=, etc., which also generate "uses"
    // of a variable.  Do this just by visiting the subexpression.
    if (B->getOpcode() != BinaryOperator::Assign)
      VisitDeclRefExpr(DR);
  }
  else // Not assigning to a variable.  Process LHS as usual.
    Visit(LHS);

  Visit(B->getRHS());
}

void TransferFuncs::VisitDeclStmt(DeclStmt* DS) {
  // Declarations effectively "kill" a variable since they cannot
  // possibly be live before they are declared.
  for (ScopedDecl* D = DS->getDecl(); D != NULL; D = D->getNextDeclarator())
    LiveState(D,AD) = Dead;
}

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Merge operator: if something is live on any successor block, it is live
//  in the current block (a set union).
//===----------------------------------------------------------------------===//

namespace {
typedef DeclBitVector_Types::Union Merge;
typedef DataflowSolver<LiveVariables,TransferFuncs,Merge> Solver;
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// External interface to run Liveness analysis.
//===----------------------------------------------------------------------===//

void LiveVariables::runOnCFG(CFG& cfg) {
  Solver S(*this);
  S.runOnCFG(cfg);
}

void LiveVariables::runOnAllBlocks(const CFG& cfg,
                                   LiveVariables::ObserverTy* Obs,
                                   bool recordStmtValues) {
  Solver S(*this);
  ObserverTy* OldObserver = getAnalysisData().Observer;
  getAnalysisData().Observer = Obs;
  S.runOnAllBlocks(cfg, recordStmtValues);
  getAnalysisData().Observer = OldObserver;
}

//===----------------------------------------------------------------------===//
// liveness queries
//

bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const {
  return getBlockData(B)(D,getAnalysisData());
}

bool LiveVariables::isLive(const ValTy& Live, const VarDecl* D) const {
  return Live(D,getAnalysisData());
}

bool LiveVariables::isLive(const Stmt* Loc, const Stmt* StmtVal) const {
  return getStmtData(Loc)(StmtVal,getAnalysisData());
}

bool LiveVariables::isLive(const Stmt* Loc, const VarDecl* D) const {
  return getStmtData(Loc)(D,getAnalysisData());
}

//===----------------------------------------------------------------------===//
// printing liveness state for debugging
//

void LiveVariables::dumpLiveness(const ValTy& V, SourceManager& SM) const {
  const AnalysisDataTy& AD = getAnalysisData();

  for (AnalysisDataTy::decl_iterator I = AD.begin_decl(),
                                     E = AD.end_decl(); I!=E; ++I)
    if (V.getDeclBit(I->second)) {
      SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation());

      fprintf(stderr, "  %s <%s:%u:%u>\n",
              I->first->getIdentifier()->getName(),
              SM.getSourceName(PhysLoc),
              SM.getLineNumber(PhysLoc),
              SM.getColumnNumber(PhysLoc));
    }
}

void LiveVariables::dumpBlockLiveness(SourceManager& M) const {
  for (BlockDataMapTy::iterator I = getBlockDataMap().begin(),
       E = getBlockDataMap().end(); I!=E; ++I) {
    fprintf(stderr, "\n[ B%d (live variables at block exit) ]\n",
            I->first->getBlockID());

    dumpLiveness(I->second,M);
  }

  fprintf(stderr,"\n");
}
<commit_msg>Fixed bug in LiveVariables analysis where Block-level exprs appearing as the initializers for DeclStmts were not being registered as being live at the start of the DeclStmt.<commit_after>//=- LiveVariables.cpp - Live Variable Analysis for Source CFGs -*- C++ --*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Live Variables analysis for source-level CFGs.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Basic/SourceManager.h"
#include "clang/AST/Expr.h"
#include "clang/AST/CFG.h"
#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
#include "clang/Analysis/FlowSensitive/DataflowSolver.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Compiler.h"

#include <string.h>
#include <stdio.h>

using namespace clang;

//===----------------------------------------------------------------------===//
// Dataflow initialization logic.
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN RegisterDecls
  : public CFGRecStmtDeclVisitor<RegisterDecls> {

  LiveVariables::AnalysisDataTy& AD;
public:
  RegisterDecls(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
  void VisitVarDecl(VarDecl* VD) { AD.Register(VD); }
  CFG& getCFG() { return AD.getCFG(); }
};
} // end anonymous namespace

LiveVariables::LiveVariables(CFG& cfg, FunctionDecl& FD) {
  getAnalysisData().setCFG(&cfg);

  for (FunctionDecl::param_iterator I=FD.param_begin(), E=FD.param_end();
       I !=E; ++I)
    getAnalysisData().Register(*I);

  // Now register all the other VarDecls;
  RegisterDecls R(getAnalysisData());
  cfg.VisitBlockStmts(R);
}

//===----------------------------------------------------------------------===//
// Transfer functions.
//===----------------------------------------------------------------------===//

namespace {

static const bool Alive = true;
static const bool Dead = false;

class VISIBILITY_HIDDEN TransferFuncs : public CFGRecStmtVisitor<TransferFuncs>{
  LiveVariables::AnalysisDataTy& AD;
  LiveVariables::ValTy LiveState;
public:
  TransferFuncs(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}

  LiveVariables::ValTy& getVal() { return LiveState; }
  CFG& getCFG() { return AD.getCFG(); }

  void VisitDeclRefExpr(DeclRefExpr* DR);
  void VisitBinaryOperator(BinaryOperator* B);
  void VisitAssign(BinaryOperator* B);
  void VisitDeclStmt(DeclStmt* DS);
  void VisitUnaryOperator(UnaryOperator* U);
  void Visit(Stmt *S);
};

void TransferFuncs::Visit(Stmt *S) {
  if (AD.Observer)
    AD.Observer->ObserveStmt(S,AD,LiveState);

  if (S == getCurrentBlkStmt()) {
    if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead;
    StmtVisitor<TransferFuncs,void>::Visit(S);
  }
  else if (!getCFG().isBlkExpr(S))
    StmtVisitor<TransferFuncs,void>::Visit(S);
  else
    // For block-level expressions, mark that they are live.
    LiveState(S,AD) = Alive;
}

void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
  if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
    LiveState(V,AD) = Alive;
}

void TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
  if (B->isAssignmentOp()) VisitAssign(B);
  else VisitStmt(B);
}

void TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
  Expr *E = U->getSubExpr();

  switch (U->getOpcode()) {
  case UnaryOperator::SizeOf: return;
  case UnaryOperator::PostInc:
  case UnaryOperator::PostDec:
  case UnaryOperator::PreInc:
  case UnaryOperator::PreDec:
  case UnaryOperator::AddrOf:
    // Walk through the subexpressions, blasting through ParenExprs
    // until we either find a DeclRefExpr or some non-DeclRefExpr
    // expression.
    if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E->IgnoreParens())) {
      // Treat the --/++/& operator as a kill.
      LiveState(DR->getDecl(),AD) = Dead;
      if (AD.Observer) { AD.Observer->ObserverKill(DR); }
      return VisitDeclRefExpr(DR);
    }

    // Fall-through.

  default:
    return Visit(E);
  }
}

void TransferFuncs::VisitAssign(BinaryOperator* B) {
  Expr* LHS = B->getLHS();

  // Assigning to a variable?
  if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParens())) {
    LiveState(DR->getDecl(),AD) = Dead;
    if (AD.Observer) { AD.Observer->ObserverKill(DR); }

    // Handle things like +=, etc., which also generate "uses"
    // of a variable.  Do this just by visiting the subexpression.
    if (B->getOpcode() != BinaryOperator::Assign)
      VisitDeclRefExpr(DR);
  }
  else // Not assigning to a variable.  Process LHS as usual.
    Visit(LHS);

  Visit(B->getRHS());
}

void TransferFuncs::VisitDeclStmt(DeclStmt* DS) {
  // Declarations effectively "kill" a variable since they cannot
  // possibly be live before they are declared.
  for (ScopedDecl* D = DS->getDecl(); D != NULL; D = D->getNextDeclarator()) {
    LiveState(D,AD) = Dead;

    if (VarDecl* VD = dyn_cast<VarDecl>(D))
      if (Expr* Init = VD->getInit())
        Visit(Init);
  }
}

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Merge operator: if something is live on any successor block, it is live
//  in the current block (a set union).
//===----------------------------------------------------------------------===//

namespace {
typedef DeclBitVector_Types::Union Merge;
typedef DataflowSolver<LiveVariables,TransferFuncs,Merge> Solver;
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// External interface to run Liveness analysis.
//===----------------------------------------------------------------------===//

void LiveVariables::runOnCFG(CFG& cfg) {
  Solver S(*this);
  S.runOnCFG(cfg);
}

void LiveVariables::runOnAllBlocks(const CFG& cfg,
                                   LiveVariables::ObserverTy* Obs,
                                   bool recordStmtValues) {
  Solver S(*this);
  ObserverTy* OldObserver = getAnalysisData().Observer;
  getAnalysisData().Observer = Obs;
  S.runOnAllBlocks(cfg, recordStmtValues);
  getAnalysisData().Observer = OldObserver;
}

//===----------------------------------------------------------------------===//
// liveness queries
//

bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const {
  return getBlockData(B)(D,getAnalysisData());
}

bool LiveVariables::isLive(const ValTy& Live, const VarDecl* D) const {
  return Live(D,getAnalysisData());
}

bool LiveVariables::isLive(const Stmt* Loc, const Stmt* StmtVal) const {
  return getStmtData(Loc)(StmtVal,getAnalysisData());
}

bool LiveVariables::isLive(const Stmt* Loc, const VarDecl* D) const {
  return getStmtData(Loc)(D,getAnalysisData());
}

//===----------------------------------------------------------------------===//
// printing liveness state for debugging
//

void LiveVariables::dumpLiveness(const ValTy& V, SourceManager& SM) const {
  const AnalysisDataTy& AD = getAnalysisData();

  for (AnalysisDataTy::decl_iterator I = AD.begin_decl(),
                                     E = AD.end_decl(); I!=E; ++I)
    if (V.getDeclBit(I->second)) {
      SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation());

      fprintf(stderr, "  %s <%s:%u:%u>\n",
              I->first->getIdentifier()->getName(),
              SM.getSourceName(PhysLoc),
              SM.getLineNumber(PhysLoc),
              SM.getColumnNumber(PhysLoc));
    }
}

void LiveVariables::dumpBlockLiveness(SourceManager& M) const {
  for (BlockDataMapTy::iterator I = getBlockDataMap().begin(),
       E = getBlockDataMap().end(); I!=E; ++I) {
    fprintf(stderr, "\n[ B%d (live variables at block exit) ]\n",
            I->first->getBlockID());

    dumpLiveness(I->second,M);
  }

  fprintf(stderr,"\n");
}
<|endoftext|>


<commit_before>#include "mouse/mouse_cmd.h"

#include "logconsole.h"
#include "entity_system.h"

#include "srv_mouse_cmd.h"

#include "components/basic_info.h"
#include "components/destination.h"
#include "components/position.h"
#include "components/target.h"

#include <cmath>

using namespace RoseCommon;
using namespace RoseCommon::Packet;

void Mouse::mouse_cmd(EntitySystem& entitySystem, Entity entity, const CliMouseCmd& packet) {
    auto logger = Core::CLog::GetLogger(Core::log_type::GENERAL).lock();
    logger->trace("Mouse::mouse_cmd");
    logger->trace("entity {}, target {} x {} y {}", entity, packet.get_targetId(), packet.get_x(), packet.get_y());

    const auto& basicInfo = entitySystem.get_component<Component::BasicInfo>(entity);
    const auto& pos = entitySystem.get_component<Component::Position>(entity);
    // TODO: add target component
    auto& dest = entitySystem.add_or_replace_component<Component::Destination>(entity);

    dest.x = packet.get_x();
    dest.y = packet.get_y();
    dest.z = 0;

    const float dx = pos.x - dest.x;
    const float dy = pos.y - dest.y;
    dest.dist = std::sqrt(dx * dx + dy * dy);

    // TODO: add smooth update of position somehow

    auto p = SrvMouseCmd::create(basicInfo.id);
    p.set_targetId(packet.get_targetId());
    p.set_x(packet.get_x());
    p.set_y(packet.get_y());
    entitySystem.send_nearby(entity, p);
}
<commit_msg>Update mouse_cmd.cpp<commit_after>#include "mouse/mouse_cmd.h"

#include "logconsole.h"
#include "entity_system.h"

#include "srv_mouse_cmd.h"

#include "components/basic_info.h"
#include "components/destination.h"
#include "components/position.h"
#include "components/target.h"

#include <cmath>

using namespace RoseCommon;
using namespace RoseCommon::Packet;

void Mouse::mouse_cmd(EntitySystem& entitySystem, Entity entity, const CliMouseCmd& packet) {
    auto logger = Core::CLog::GetLogger(Core::log_type::GENERAL).lock();
    logger->trace("Mouse::mouse_cmd");
    logger->trace("entity {}, target {} x {} y {}", entity, packet.get_targetId(), packet.get_x(), packet.get_y());

    const auto& basicInfo = entitySystem.get_component<Component::BasicInfo>(entity);
    const auto& pos = entitySystem.get_component<Component::Position>(entity);
    // TODO: add target component
    auto& dest = entitySystem.add_or_replace_component<Component::Destination>(entity);

    dest.x = packet.get_x();
    dest.y = packet.get_y();
    dest.z = 0;

    const float dx = pos.x - dest.x;
    const float dy = pos.y - dest.y;
    dest.dist = std::sqrt(dx * dx + dy * dy);

    if (packet.get_target() && (auto t = entitySystem.get_entity_from_id(packet.get_target())) != entt::null) {
        auto& target = entitySystem.add_or_replace_component<Component::Target>(entity);
        target.target = t;
    } else {
        entitySystem.remove_component<Component::Target>(entity);
    }

    auto p = SrvMouseCmd::create(basicInfo.id);
    p.set_targetId(packet.get_targetId());
    p.set_x(packet.get_x());
    p.set_y(packet.get_y());
    entitySystem.send_nearby(entity, p);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <map>

std::map<std::string, std::string> suits{
	{"п", "Spades"},
	{"ч", "Hearts"},
	{"б", "Diamonds"},
	{"к", "Clubs"}
};

std::map<std::string, std::string> ranks{
	{"6", "Six"},
	{"7", "Seven"},
	{"8", "Eight"},
	{"9", "Nine"},
	{"X", "Ten"},
	{"В", "Jack"},
	{"Д", "Queen"},
	{"К", "King"},
	{"Т", "Ace"}
};

void Guess(const std::string& line, std::size_t &pos, const std::map<std::string, std::string>& map, std::string& result){
	if (pos > line.size())
		return ;
	for (auto &pair : map){
		auto &name = pair.first;
		if (line.compare(pos, name.size(), name) == 0){
			result = pair.second;
			pos += name.size();
			break;
		}
	}
}

int main(int argc, char **argv){
	std::string argument;
	for (int i = 1; i < argc; ++i){
		if (i != 1)
			argument += ' ';
		argument += argv[i];
	}
	std::size_t N = argument.size();
	std::string result("{");
	bool first(true);
	for (std::size_t i = 0; i < N; ++i){
		std::string guessedRank, guessedSuit;
		Guess(argument, i, ranks, guessedRank);
		if (guessedRank.empty()){
			std::cout << "Can't find a rank at " << "(" << argument.substr(i, 9) << ")" << "\n";
			break ;
		}
		Guess(argument, i, suits, guessedSuit);
		if (guessedSuit.empty()){
			std::cout << "Can't find a suit at " << "(" << argument.substr(i, 9) << ")" << "\n";
			break ;
		}

		if (first) first = false; else result += ", ";
		result += "{" + guessedRank + ", " + guessedSuit + "}";
	}
	std::cout << result << "}\n";
	return 0;
}

<commit_msg>If can't convert symbol, then skip it<commit_after>#include <iostream>
#include <string>
#include <map>

std::map<std::string, std::string> suits{
	{"п", "Spades"},
	{"ч", "Hearts"},
	{"б", "Diamonds"},
	{"к", "Clubs"}
};

std::map<std::string, std::string> ranks{
	{"6", "Six"},
	{"7", "Seven"},
	{"8", "Eight"},
	{"9", "Nine"},
	{"X", "Ten"},
	{"В", "Jack"},
	{"Д", "Queen"},
	{"К", "King"},
	{"Т", "Ace"}
};

void Guess(const std::string& line, std::size_t &pos, const std::map<std::string, std::string>& map, std::string& result){
	if (pos > line.size())
		return ;
	for (auto &pair : map){
		auto &name = pair.first;
		if (line.compare(pos, name.size(), name) == 0){
			result = pair.second;
			pos += name.size();
			break;
		}
	}
}

int main(int argc, char **argv){
	std::string argument;
	for (int i = 1; i < argc; ++i){
		if (i != 1)
			argument += ' ';
		argument += argv[i];
	}
	std::size_t N = argument.size();
	std::string result("{");
	bool first(true);
	for (std::size_t i = 0; i < N; ++i){
		std::string guessedRank, guessedSuit;
		Guess(argument, i, ranks, guessedRank);
		if (guessedRank.empty())
			continue;
		Guess(argument, i, suits, guessedSuit);
		if (guessedSuit.empty())
			continue;
		if (first) first = false; else result += ", ";
		result += "{" + guessedRank + ", " + guessedSuit + "}";
	}
	std::cout << result << "}\n";
	return 0;
}

<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     rthpi.cpp
* @author   Chiran Doshi <chiran.doshi@childrens.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     June, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Chiran Doshi and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of the Massachusetts General Hospital nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MASSACHUSETTS GENERAL HOSPITAL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Contains the implementation of the RtHpi class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================
#include <Eigen/Dense>
#include <iostream>
#include "rthpi.h"
#include "FormFiles/rthpisetupwidget.h"

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtCore/QtPlugin>
#include <QDebug>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace RtHpiPlugin;
using namespace MNEX;
using namespace XMEASLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

RtHpi::RtHpi()
: m_bIsRunning(false)
, m_bProcessData(false)
, m_pRTMSAInput(NULL)
, m_pRTMSAOutput(NULL)
, m_pRtHpiBuffer(CircularMatrixBuffer<double>::SPtr())
{
}

//*************************************************************************************************************

RtHpi::~RtHpi()
{
    if(this->isRunning())
        stop();
}

//*************************************************************************************************************

QSharedPointer<IPlugin> RtHpi::clone() const
{
    QSharedPointer<RtHpi> pRtHpiClone(new RtHpi);
    return pRtHpiClone;
}

//*************************************************************************************************************
//=============================================================================================================
// Creating required display instances and set configurations
//=============================================================================================================

void RtHpi::init()
{
    // Input
    m_pRTMSAInput = PluginInputData<NewRealTimeMultiSampleArray>::create(this, "Rt HPI In", "RT HPI input data");
    connect(m_pRTMSAInput.data(), &PluginInputConnector::notify, this, &RtHpi::update, Qt::DirectConnection);
    m_inputConnectors.append(m_pRTMSAInput);

    // Output
    m_pRTMSAOutput = PluginOutputData<NewRealTimeMultiSampleArray>::create(this, "Rt HPI Out", "RT HPI output data");
    m_outputConnectors.append(m_pRTMSAOutput);

    m_pRTMSAOutput->data()->setMultiArraySize(100);
    m_pRTMSAOutput->data()->setVisibility(true);

    //init channels when fiff info is available
    connect(this, &RtHpi::fiffInfoAvailable, this, &RtHpi::initConnector);

    //Delete Buffer - will be initailzed with first incoming data
    if(!m_pRtHpiBuffer.isNull())
        m_pRtHpiBuffer = CircularMatrixBuffer<double>::SPtr();
}

//*************************************************************************************************************

void RtHpi::initConnector()
{
    qDebug() << "void RtHpi::initConnector()";
    if(m_pFiffInfo)
        m_pRTMSAOutput->data()->initFromFiffInfo(m_pFiffInfo);
}

//*************************************************************************************************************

bool RtHpi::start()
{
    //Check if the thread is already or still running. This can happen if the start button is pressed immediately after the stop button was pressed. In this case the stopping process is not finished yet but the start process is initiated.
    if(this->isRunning())
        QThread::wait();

    m_bIsRunning = true;

    // Start threads
    QThread::start();

    return true;
}

//*************************************************************************************************************

bool RtHpi::stop()
{
    //Wait until this thread is stopped
    m_bIsRunning = false;

    if(m_bProcessData)
    {
        //In case the semaphore blocks the thread -> Release the QSemaphore and let it exit from the pop function (acquire statement)
        m_pRtHpiBuffer->releaseFromPop();
        m_pRtHpiBuffer->releaseFromPush();

        m_pRtHpiBuffer->clear();

        m_pRTMSAOutput->data()->clear();
    }

    return true;
}

//*************************************************************************************************************

IPlugin::PluginType RtHpi::getType() const
{
    return _IAlgorithm;
}

//*************************************************************************************************************

QString RtHpi::getName() const
{
    return "RtHpi Toolbox";
}

//*************************************************************************************************************

QWidget* RtHpi::setupWidget()
{
    RtHpiSetupWidget* setupWidget = new RtHpiSetupWidget(this);//widget is later distroyed by CentralWidget - so it has to be created everytime new
    return setupWidget;
}

//*************************************************************************************************************

void RtHpi::update(XMEASLIB::NewMeasurement::SPtr pMeasurement)
{
    QSharedPointer<NewRealTimeMultiSampleArray> pRTMSA = pMeasurement.dynamicCast<NewRealTimeMultiSampleArray>();

    if(pRTMSA)
    {
        //Check if buffer initialized
        if(!m_pRtHpiBuffer)
            m_pRtHpiBuffer = CircularMatrixBuffer<double>::SPtr(new CircularMatrixBuffer<double>(64, pRTMSA->getNumChannels(), pRTMSA->getMultiArraySize()));

        //Fiff information
        if(!m_pFiffInfo)
        {
            m_pFiffInfo = pRTMSA->getFiffInfo();
            emit fiffInfoAvailable();
        }

        if(m_bProcessData)
        {
            MatrixXd t_mat(pRTMSA->getNumChannels(), pRTMSA->getMultiArraySize());

            for(qint32 i = 0; i < pRTMSA->getMultiArraySize(); ++i)
                t_mat.col(i) = pRTMSA->getMultiSampleArray()[i];

            m_pRtHpiBuffer->push(&t_mat);
        }
    }
}

//*************************************************************************************************************

void RtHpi::run()
{
    //
    // Read Fiff Info
    //
    while(!m_pFiffInfo)
        msleep(10);// Wait for fiff Info

    m_bProcessData = true;

    QVector<MatrixXd> buffer;

    while (m_bIsRunning)
    {
        if(m_bProcessData)
        {
            /* Dispatch the inputs */
            MatrixXd t_mat = m_pRtHpiBuffer->pop();

            buffer.push(t_mat);

            if(buffer.size() > 10)
            {
                //ToDo: Implement your algorithm here

                buffer.clear();
            }

            for(qint32 i = 0; i < t_mat.cols(); ++i)
                m_pRTMSAOutput->data()->setValue(t_mat.col(i));
        }
    }
}
<commit_msg>Changed buffer variable type<commit_after>//=============================================================================================================
/**
* @file     rthpi.cpp
* @author   Chiran Doshi <chiran.doshi@childrens.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     June, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Chiran Doshi and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of the Massachusetts General Hospital nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MASSACHUSETTS GENERAL HOSPITAL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Contains the implementation of the RtHpi class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================
#include <Eigen/Dense>
#include <iostream>
#include "rthpi.h"
#include "FormFiles/rthpisetupwidget.h"

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtCore/QtPlugin>
#include <QDebug>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace RtHpiPlugin;
using namespace MNEX;
using namespace XMEASLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

RtHpi::RtHpi()
: m_bIsRunning(false)
, m_bProcessData(false)
, m_pRTMSAInput(NULL)
, m_pRTMSAOutput(NULL)
, m_pRtHpiBuffer(CircularMatrixBuffer<double>::SPtr())
{
}

//*************************************************************************************************************

RtHpi::~RtHpi()
{
    if(this->isRunning())
        stop();
}

//*************************************************************************************************************

QSharedPointer<IPlugin> RtHpi::clone() const
{
    QSharedPointer<RtHpi> pRtHpiClone(new RtHpi);
    return pRtHpiClone;
}

//*************************************************************************************************************
//=============================================================================================================
// Creating required display instances and set configurations
//=============================================================================================================

void RtHpi::init()
{
    // Input
    m_pRTMSAInput = PluginInputData<NewRealTimeMultiSampleArray>::create(this, "Rt HPI In", "RT HPI input data");
    connect(m_pRTMSAInput.data(), &PluginInputConnector::notify, this, &RtHpi::update, Qt::DirectConnection);
    m_inputConnectors.append(m_pRTMSAInput);

    // Output
    m_pRTMSAOutput = PluginOutputData<NewRealTimeMultiSampleArray>::create(this, "Rt HPI Out", "RT HPI output data");
    m_outputConnectors.append(m_pRTMSAOutput);

    m_pRTMSAOutput->data()->setMultiArraySize(100);
    m_pRTMSAOutput->data()->setVisibility(true);

    //init channels when fiff info is available
    connect(this, &RtHpi::fiffInfoAvailable, this, &RtHpi::initConnector);

    //Delete Buffer - will be initailzed with first incoming data
    if(!m_pRtHpiBuffer.isNull())
        m_pRtHpiBuffer = CircularMatrixBuffer<double>::SPtr();
}

//*************************************************************************************************************

void RtHpi::initConnector()
{
    qDebug() << "void RtHpi::initConnector()";
    if(m_pFiffInfo)
        m_pRTMSAOutput->data()->initFromFiffInfo(m_pFiffInfo);
}

//*************************************************************************************************************

bool RtHpi::start()
{
    //Check if the thread is already or still running. This can happen if the start button is pressed immediately after the stop button was pressed. In this case the stopping process is not finished yet but the start process is initiated.
    if(this->isRunning())
        QThread::wait();

    m_bIsRunning = true;

    // Start threads
    QThread::start();

    return true;
}

//*************************************************************************************************************

bool RtHpi::stop()
{
    //Wait until this thread is stopped
    m_bIsRunning = false;

    if(m_bProcessData)
    {
        //In case the semaphore blocks the thread -> Release the QSemaphore and let it exit from the pop function (acquire statement)
        m_pRtHpiBuffer->releaseFromPop();
        m_pRtHpiBuffer->releaseFromPush();

        m_pRtHpiBuffer->clear();

        m_pRTMSAOutput->data()->clear();
    }

    return true;
}

//*************************************************************************************************************

IPlugin::PluginType RtHpi::getType() const
{
    return _IAlgorithm;
}

//*************************************************************************************************************

QString RtHpi::getName() const
{
    return "RtHpi Toolbox";
}

//*************************************************************************************************************

QWidget* RtHpi::setupWidget()
{
    RtHpiSetupWidget* setupWidget = new RtHpiSetupWidget(this);//widget is later distroyed by CentralWidget - so it has to be created everytime new
    return setupWidget;
}

//*************************************************************************************************************

void RtHpi::update(XMEASLIB::NewMeasurement::SPtr pMeasurement)
{
    QSharedPointer<NewRealTimeMultiSampleArray> pRTMSA = pMeasurement.dynamicCast<NewRealTimeMultiSampleArray>();

    if(pRTMSA)
    {
        //Check if buffer initialized
        if(!m_pRtHpiBuffer)
            m_pRtHpiBuffer = CircularMatrixBuffer<double>::SPtr(new CircularMatrixBuffer<double>(64, pRTMSA->getNumChannels(), pRTMSA->getMultiArraySize()));

        //Fiff information
        if(!m_pFiffInfo)
        {
            m_pFiffInfo = pRTMSA->getFiffInfo();
            emit fiffInfoAvailable();
        }

        if(m_bProcessData)
        {
            MatrixXd t_mat(pRTMSA->getNumChannels(), pRTMSA->getMultiArraySize());

            for(qint32 i = 0; i < pRTMSA->getMultiArraySize(); ++i)
                t_mat.col(i) = pRTMSA->getMultiSampleArray()[i];

            m_pRtHpiBuffer->push(&t_mat);
        }
    }
}

//*************************************************************************************************************

void RtHpi::run()
{
    //
    // Read Fiff Info
    //
    while(!m_pFiffInfo)
        msleep(10);// Wait for fiff Info

    m_bProcessData = true;

    MatrixXd buffer;

    while (m_bIsRunning)
    {
        if(m_bProcessData)
        {
            /* Dispatch the inputs */
            MatrixXd t_mat = m_pRtHpiBuffer->pop();

            buffer.push(t_mat);

            if(buffer.size() > 10)
            {
                //ToDo: Implement your algorithm here

                buffer.clear();
            }

            for(qint32 i = 0; i < t_mat.cols(); ++i)
                m_pRTMSAOutput->data()->setValue(t_mat.col(i));
        }
    }
}
<|endoftext|>


<commit_before>/*
 *  BuzzContainerBubble.cpp
 *  Render
 *
 *  Created by Chris on 3/8/11.
 *  Copyright 2011 csugrue. All rights reserved.
 *
 */

#include "BuzzContainerBubble.h"

BuzzContainerBubble::BuzzContainerBubble(){

	ContentBubble::ContentBubble();
}

void BuzzContainerBubble::createContainerBubble(ofxBullet * bullet, ofVec3f _pos){

	ContentBubble::createContentBubble();

	globe = new ofxBulletCompoundBody();
	globe->world = bullet->world;
	globe->compoundShape = new btCompoundShape();

	int size = 80;

	btTransform startTrans;
	startTrans.setIdentity();
	startTrans.setOrigin( btVector3(pos.x,pos.y,pos.z) );

	btVector3 btSize;
	btSize.setX( 200.f );
	btSize.setY( 1.f );//btSize.setY( 30.f );
	btSize.setZ( 200.f );

	btVector3 up(0, 1, 0);
	ofVec3f position = _pos;

	// create the sphere:
	for (int i = 1; i < 12; i++){
		for (int j = 0; j < 12; j++){

			btScalar cx = position.x + (cos(i) * sin(j) * btSize.getX() );
			btScalar cy = position.y + (cos(j) * btSize.getX());
			btScalar cz = position.z + (sin(i) * sin(j) * btSize.getX());

			btVector3 pos(cx, cy, cz);
			btVector3 dist = pos - ofVec3fToBtVec(position);
			dist.normalize();

			float theta = acos(dist.dot(up));
			btVector3 cross = up.cross(dist);
			cross.normalize();
			btQuaternion quat(cross, theta);

			btTransform t;
			t.setIdentity();
			t.setOrigin(pos);
			t.setRotation(quat);

			btCollisionShape * spherePart = new btBoxShape(btVector3(size, 1, size));
			globe->compoundShape->addChildShape(t, spherePart);
		}
	}

	globe->createCompoundBody(10, startTrans);

	// constraint to rigidBody
	btVector3 localPivot = rigidBody->body->getCenterOfMassPosition();
	p2p = new btPoint2PointConstraint(*globe->body, localPivot);
	bullet->world->addConstraint(p2p);

}

void BuzzContainerBubble::pop(){

	if(bAlive)
	{
		bAlive = false;

		int nChildren = globe->compoundShape->getNumChildShapes();

		for( int i = nChildren-1; i >= 0; i--)
		{
			globe->compoundShape->removeChildShapeByIndex(i);
		}

	}
}

void BuzzContainerBubble::updateConstraint() {

	if(bAlive && rigidBody->isBody())
	{
		btVector3 localPivot = rigidBody->body->getCenterOfMassPosition();
		p2p->setPivotB(localPivot);
	}

}

<commit_msg>buzz interaction kill fix and pop ups<commit_after>/*
 *  BuzzContainerBubble.cpp
 *  Render
 *
 *  Created by Chris on 3/8/11.
 *  Copyright 2011 csugrue. All rights reserved.
 *
 */

#include "BuzzContainerBubble.h"

BuzzContainerBubble::BuzzContainerBubble(){

	ContentBubble::ContentBubble();
}

void BuzzContainerBubble::createContainerBubble(ofxBullet * bullet, ofVec3f _pos){

	ContentBubble::createContentBubble();

	globe = new ofxBulletCompoundBody();
	globe->world = bullet->world;
	globe->compoundShape = new btCompoundShape();

	int size = 80;

	btTransform startTrans;
	startTrans.setIdentity();
	startTrans.setOrigin( btVector3(pos.x,pos.y,pos.z) );

	btVector3 btSize;
	btSize.setX( 200.f );
	btSize.setY( 1.f );//btSize.setY( 30.f );
	btSize.setZ( 200.f );

	btVector3 up(0, 1, 0);
	ofVec3f position = _pos;

	// create the sphere:
	for (int i = 1; i < 12; i++){
		for (int j = 0; j < 12; j++){

			btScalar cx = position.x + (cos(i) * sin(j) * btSize.getX() );
			btScalar cy = position.y + (cos(j) * btSize.getX());
			btScalar cz = position.z + (sin(i) * sin(j) * btSize.getX());

			btVector3 pos(cx, cy, cz);
			btVector3 dist = pos - ofVec3fToBtVec(position);
			dist.normalize();

			float theta = acos(dist.dot(up));
			btVector3 cross = up.cross(dist);
			cross.normalize();
			btQuaternion quat(cross, theta);

			btTransform t;
			t.setIdentity();
			t.setOrigin(pos);
			t.setRotation(quat);

			btCollisionShape * spherePart = new btBoxShape(btVector3(size, 1, size));
			globe->compoundShape->addChildShape(t, spherePart);
		}
	}

	globe->createCompoundBody(10, startTrans);

	// constraint to rigidBody
	btVector3 localPivot = rigidBody->body->getCenterOfMassPosition();
	p2p = new btPoint2PointConstraint(*globe->body, localPivot);
	bullet->world->addConstraint(p2p);
	//p2p->m_setting.m_damping = 1.001f;
	//p2p->m_setting.m_impulseClamp = .1;

}

void BuzzContainerBubble::pop(){

	if(bAlive)
	{
		bAlive = false;

		int nChildren = globe->compoundShape->getNumChildShapes();

		for( int i = nChildren-1; i >= 0; i--)
		{
			globe->compoundShape->removeChildShapeByIndex(i);
		}

	}
}

void BuzzContainerBubble::updateConstraint() {

	if(bAlive && rigidBody->isBody())
	{
		//btVector3 pickPos = rigidBody->body->getCenterOfMassPosition();
		//printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ());

		//btVector3 localPivot = globe->body->getCenterOfMassTransform().inverse() * pickPos;
		btVector3 localPivot = rigidBody->body->getCenterOfMassPosition();
		p2p->setPivotB(localPivot);
	}

}

<|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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 <assert.h>

#include <iostream>
#include <algorithm>

#include "os.hpp"
#include "json.hpp"
#include "image.hpp"
#include "d3d11imports.hpp"
#include "d3d10state.hpp"
#include "dxgistate.hpp"

namespace d3dstate {

static HRESULT
stageResource(ID3D11DeviceContext *pDeviceContext,
              ID3D11Resource *pResource,
              ID3D11Resource **ppStagingResource,
              UINT *pWidth, UINT *pHeight, UINT *pDepth,
              UINT *pMipLevels) {
    D3D11_USAGE Usage = D3D11_USAGE_STAGING;
    UINT BindFlags = 0;
    UINT CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    UINT MiscFlags = 0;
    union {
         ID3D11Resource *pStagingResource;
         ID3D11Buffer *pStagingBuffer;
         ID3D11Texture1D *pStagingTexture1D;
         ID3D11Texture2D *pStagingTexture2D;
         ID3D11Texture3D *pStagingTexture3D;
    };
    HRESULT hr;

    ID3D11Device *pDevice = NULL;
    pDeviceContext->GetDevice(&pDevice);

    D3D11_RESOURCE_DIMENSION Type = D3D11_RESOURCE_DIMENSION_UNKNOWN;
    pResource->GetType(&Type);
    switch (Type) {
    case D3D11_RESOURCE_DIMENSION_BUFFER:
        {
            D3D11_BUFFER_DESC Desc;
            static_cast<ID3D11Buffer *>(pResource)->GetDesc(&Desc);
            Desc.Usage = Usage;
            Desc.BindFlags = BindFlags;
            Desc.CPUAccessFlags = CPUAccessFlags;
            Desc.MiscFlags = MiscFlags;

            *pWidth = Desc.ByteWidth;
            *pHeight = 1;
            *pDepth = 1;
            *pMipLevels = 1;

            hr = pDevice->CreateBuffer(&Desc, NULL, &pStagingBuffer);
        }
        break;
    case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
        {
            D3D11_TEXTURE1D_DESC Desc;
            static_cast<ID3D11Texture1D *>(pResource)->GetDesc(&Desc);
            Desc.Usage = Usage;
            Desc.BindFlags = BindFlags;
            Desc.CPUAccessFlags = CPUAccessFlags;
            Desc.MiscFlags = MiscFlags;

            *pWidth = Desc.Width;
            *pHeight = 1;
            *pDepth = 1;
            *pMipLevels = Desc.MipLevels;

            hr = pDevice->CreateTexture1D(&Desc, NULL, &pStagingTexture1D);
        }
        break;
    case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
        {
            D3D11_TEXTURE2D_DESC Desc;
            static_cast<ID3D11Texture2D *>(pResource)->GetDesc(&Desc);
            Desc.Usage = Usage;
            Desc.BindFlags = BindFlags;
            Desc.CPUAccessFlags = CPUAccessFlags;
            Desc.MiscFlags &= D3D11_RESOURCE_MISC_TEXTURECUBE;

            *pWidth = Desc.Width;
            *pHeight = Desc.Height;
            *pDepth = 1;
            *pMipLevels = Desc.MipLevels;

            hr = pDevice->CreateTexture2D(&Desc, NULL, &pStagingTexture2D);
        }
        break;
    case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
        {
            D3D11_TEXTURE3D_DESC Desc;
            static_cast<ID3D11Texture3D *>(pResource)->GetDesc(&Desc);
            Desc.Usage = Usage;
            Desc.BindFlags = BindFlags;
            Desc.CPUAccessFlags = CPUAccessFlags;
            Desc.MiscFlags = MiscFlags;

            *pWidth = Desc.Width;
            *pHeight = Desc.Height;
            *pDepth = Desc.Depth;
            *pMipLevels = Desc.MipLevels;

            hr = pDevice->CreateTexture3D(&Desc, NULL, &pStagingTexture3D);
        }
        break;
    default:
        assert(0);
        hr = E_NOTIMPL;
        break;
    }

    if (SUCCEEDED(hr)) {
        *ppStagingResource = pStagingResource;
        pDeviceContext->CopyResource(pStagingResource, pResource);
    }

    pDevice->Release();

    return hr;
}

static image::Image *
getSubResourceImage(ID3D11DeviceContext *pDevice,
                    ID3D11Resource *pResource,
                    DXGI_FORMAT Format,
                    UINT ArraySlice,
                    UINT MipSlice)
{
    image::Image *image = NULL;
    ID3D11Resource *pStagingResource = NULL;
    UINT Width, Height, Depth;
    UINT MipLevels;
    UINT SubResource;
    D3D11_MAPPED_SUBRESOURCE MappedSubResource;
    HRESULT hr;

    if (!pResource) {
        return NULL;
    }

    hr = stageResource(pDevice, pResource, &pStagingResource, &Width, &Height, &Depth, &MipLevels);
    if (FAILED(hr)) {
        goto no_staging;
    }

    SubResource = ArraySlice*MipLevels + MipSlice;

    Width  = std::max(Width  >> MipSlice, 1U);
    Height = std::max(Height >> MipSlice, 1U);
    Depth  = std::max(Depth  >> MipSlice, 1U);

    hr = pDevice->Map(pStagingResource, SubResource, D3D11_MAP_READ, 0, &MappedSubResource);
    if (FAILED(hr)) {
        goto no_map;
    }

    image = ConvertImage(Format,
                         MappedSubResource.pData,
                         MappedSubResource.RowPitch,
                         Width, Height);

    pDevice->Unmap(pStagingResource, SubResource);
no_map:
    if (pStagingResource) {
        pStagingResource->Release();
    }
no_staging:
    if (pResource) {
        pResource->Release();
    }
    return image;
}

static void
dumpShaderResourceViewImage(JSONWriter &json,
                            ID3D11DeviceContext *pDevice,
                            ID3D11ShaderResourceView *pShaderResourceView,
                            const char *shader,
                            UINT stage) {
    D3D11_SHADER_RESOURCE_VIEW_DESC Desc;
    ID3D11Resource *pResource = NULL;

    if (!pShaderResourceView) {
        return;
    }

    pShaderResourceView->GetResource(&pResource);
    assert(pResource);

    pShaderResourceView->GetDesc(&Desc);

    UINT MipSlice = 0;
    UINT FirstArraySlice = 0;
    UINT ArraySize = 1;

    // TODO: Take the slice in consideration
    switch (Desc.ViewDimension) {
    case D3D11_SRV_DIMENSION_BUFFER:
        break;
    case D3D11_SRV_DIMENSION_TEXTURE1D:
        MipSlice = Desc.Texture1D.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
        MipSlice = Desc.Texture1DArray.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURE2D:
        MipSlice = Desc.Texture2D.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
        MipSlice = Desc.Texture2DArray.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURE2DMS:
        break;
    case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
        break;
    case D3D11_SRV_DIMENSION_TEXTURE3D:
        MipSlice = Desc.Texture3D.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURECUBE:
        MipSlice = Desc.TextureCube.MostDetailedMip;
        ArraySize = 6;
        break;
    case D3D11_SRV_DIMENSION_UNKNOWN:
    default:
        assert(0);
        return;
    }

    for (UINT ArraySlice = FirstArraySlice; ArraySlice < FirstArraySlice + ArraySize; ++ArraySlice) {

        image::Image *image;
        image = getSubResourceImage(pDevice, pResource, Desc.Format, ArraySlice, MipSlice);
        if (image) {
            char label[64];
            _snprintf(label, sizeof label,
                      "%s_RESOURCE_%u_ARRAY_%u_LEVEL_%u",
                      shader, stage, ArraySlice, MipSlice);
            json.beginMember(label);
            json.writeImage(image, "UNKNOWN");
            json.endMember(); // *_RESOURCE_*
            delete image;
        }

    }
}

static image::Image *
getRenderTargetViewImage(ID3D11DeviceContext *pDevice,
                         ID3D11RenderTargetView *pRenderTargetView) {
    D3D11_RENDER_TARGET_VIEW_DESC Desc;
    ID3D11Resource *pResource = NULL;
    UINT MipSlice;

    if (!pRenderTargetView) {
        return NULL;
    }

    pRenderTargetView->GetResource(&pResource);
    assert(pResource);

    pRenderTargetView->GetDesc(&Desc);

    // TODO: Take the slice in consideration
    switch (Desc.ViewDimension) {
    case D3D11_RTV_DIMENSION_BUFFER:
        MipSlice = 0;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE1D:
        MipSlice = Desc.Texture1D.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
        MipSlice = Desc.Texture1DArray.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE2D:
        MipSlice = Desc.Texture2D.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
        MipSlice = Desc.Texture2DArray.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE2DMS:
        MipSlice = 0;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
        MipSlice = 0;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE3D:
        MipSlice = Desc.Texture3D.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_UNKNOWN:
    default:
        assert(0);
        return NULL;
    }

    return getSubResourceImage(pDevice, pResource, Desc.Format, 0, MipSlice);
}

static image::Image *
getDepthStencilViewImage(ID3D11DeviceContext *pDevice,
                         ID3D11DepthStencilView *pDepthStencilView) {
    D3D11_DEPTH_STENCIL_VIEW_DESC Desc;
    ID3D11Resource *pResource = NULL;
    UINT MipSlice;

    if (!pDepthStencilView) {
        return NULL;
    }

    pDepthStencilView->GetResource(&pResource);
    assert(pResource);

    pDepthStencilView->GetDesc(&Desc);

    // TODO: Take the slice in consideration
    switch (Desc.ViewDimension) {
    case D3D11_DSV_DIMENSION_TEXTURE1D:
        MipSlice = Desc.Texture1D.MipSlice;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
        MipSlice = Desc.Texture1DArray.MipSlice;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE2D:
        MipSlice = Desc.Texture2D.MipSlice;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
        MipSlice = Desc.Texture2DArray.MipSlice;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE2DMS:
        MipSlice = 0;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
        MipSlice = 0;
        break;
    case D3D11_DSV_DIMENSION_UNKNOWN:
    default:
        assert(0);
        return NULL;
    }

    return getSubResourceImage(pDevice, pResource, Desc.Format, 0, MipSlice);
}

void
dumpTextures(JSONWriter &json, ID3D11DeviceContext *pDevice)
{
    json.beginMember("textures");
    json.beginObject();

    ID3D11ShaderResourceView *pShaderResourceViews[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
    pDevice->PSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);

    for (UINT i = 0; i < ARRAYSIZE(pShaderResourceViews); ++i) {
        if (!pShaderResourceViews[i]) {
            continue;
        }

        dumpShaderResourceViewImage(json, pDevice, pShaderResourceViews[i], "PS", i);

        pShaderResourceViews[i]->Release();
    }

    json.endObject();
    json.endMember(); // textures
}

image::Image *
getRenderTargetImage(ID3D11DeviceContext *pDevice) {
    ID3D11RenderTargetView *pRenderTargetView = NULL;
    pDevice->OMGetRenderTargets(1, &pRenderTargetView, NULL);

    image::Image *image = NULL;
    if (pRenderTargetView) {
        image = getRenderTargetViewImage(pDevice, pRenderTargetView);
        pRenderTargetView->Release();
    }

    return image;
}

void
dumpFramebuffer(JSONWriter &json, ID3D11DeviceContext *pDevice)
{
    json.beginMember("framebuffer");
    json.beginObject();

    ID3D11RenderTargetView *pRenderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
    ID3D11DepthStencilView *pDepthStencilView;
    pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews,
                                &pDepthStencilView);

    for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) {
        if (!pRenderTargetViews[i]) {
            continue;
        }

        image::Image *image;
        image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]);
        if (image) {
            char label[64];
            _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
            json.beginMember(label);
            json.writeImage(image, "UNKNOWN");
            json.endMember(); // RENDER_TARGET_*
            delete image;
        }

        pRenderTargetViews[i]->Release();
    }

    if (pDepthStencilView) {
        image::Image *image;
        image = getDepthStencilViewImage(pDevice, pDepthStencilView);
        if (image) {
            json.beginMember("DEPTH_STENCIL");
            json.writeImage(image, "UNKNOWN");
            json.endMember();
            delete image;
        }

        pDepthStencilView->Release();

    }

    json.endObject();
    json.endMember(); // framebuffer
}

} /* namespace d3dstate */
<commit_msg>d3dretrace: Dump all resources bound to all d3d11 shader stages.<commit_after>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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 <assert.h>

#include <iostream>
#include <algorithm>

#include "os.hpp"
#include "json.hpp"
#include "image.hpp"
#include "d3d11imports.hpp"
#include "d3d10state.hpp"
#include "dxgistate.hpp"

namespace d3dstate {

static HRESULT
stageResource(ID3D11DeviceContext *pDeviceContext,
              ID3D11Resource *pResource,
              ID3D11Resource **ppStagingResource,
              UINT *pWidth, UINT *pHeight, UINT *pDepth,
              UINT *pMipLevels) {
    D3D11_USAGE Usage = D3D11_USAGE_STAGING;
    UINT BindFlags = 0;
    UINT CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    UINT MiscFlags = 0;
    union {
         ID3D11Resource *pStagingResource;
         ID3D11Buffer *pStagingBuffer;
         ID3D11Texture1D *pStagingTexture1D;
         ID3D11Texture2D *pStagingTexture2D;
         ID3D11Texture3D *pStagingTexture3D;
    };
    HRESULT hr;

    ID3D11Device *pDevice = NULL;
    pDeviceContext->GetDevice(&pDevice);

    D3D11_RESOURCE_DIMENSION Type = D3D11_RESOURCE_DIMENSION_UNKNOWN;
    pResource->GetType(&Type);
    switch (Type) {
    case D3D11_RESOURCE_DIMENSION_BUFFER:
        {
            D3D11_BUFFER_DESC Desc;
            static_cast<ID3D11Buffer *>(pResource)->GetDesc(&Desc);
            Desc.Usage = Usage;
            Desc.BindFlags = BindFlags;
            Desc.CPUAccessFlags = CPUAccessFlags;
            Desc.MiscFlags = MiscFlags;

            *pWidth = Desc.ByteWidth;
            *pHeight = 1;
            *pDepth = 1;
            *pMipLevels = 1;

            hr = pDevice->CreateBuffer(&Desc, NULL, &pStagingBuffer);
        }
        break;
    case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
        {
            D3D11_TEXTURE1D_DESC Desc;
            static_cast<ID3D11Texture1D *>(pResource)->GetDesc(&Desc);
            Desc.Usage = Usage;
            Desc.BindFlags = BindFlags;
            Desc.CPUAccessFlags = CPUAccessFlags;
            Desc.MiscFlags = MiscFlags;

            *pWidth = Desc.Width;
            *pHeight = 1;
            *pDepth = 1;
            *pMipLevels = Desc.MipLevels;

            hr = pDevice->CreateTexture1D(&Desc, NULL, &pStagingTexture1D);
        }
        break;
    case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
        {
            D3D11_TEXTURE2D_DESC Desc;
            static_cast<ID3D11Texture2D *>(pResource)->GetDesc(&Desc);
            Desc.Usage = Usage;
            Desc.BindFlags = BindFlags;
            Desc.CPUAccessFlags = CPUAccessFlags;
            Desc.MiscFlags &= D3D11_RESOURCE_MISC_TEXTURECUBE;

            *pWidth = Desc.Width;
            *pHeight = Desc.Height;
            *pDepth = 1;
            *pMipLevels = Desc.MipLevels;

            hr = pDevice->CreateTexture2D(&Desc, NULL, &pStagingTexture2D);
        }
        break;
    case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
        {
            D3D11_TEXTURE3D_DESC Desc;
            static_cast<ID3D11Texture3D *>(pResource)->GetDesc(&Desc);
            Desc.Usage = Usage;
            Desc.BindFlags = BindFlags;
            Desc.CPUAccessFlags = CPUAccessFlags;
            Desc.MiscFlags = MiscFlags;

            *pWidth = Desc.Width;
            *pHeight = Desc.Height;
            *pDepth = Desc.Depth;
            *pMipLevels = Desc.MipLevels;

            hr = pDevice->CreateTexture3D(&Desc, NULL, &pStagingTexture3D);
        }
        break;
    default:
        assert(0);
        hr = E_NOTIMPL;
        break;
    }

    if (SUCCEEDED(hr)) {
        *ppStagingResource = pStagingResource;
        pDeviceContext->CopyResource(pStagingResource, pResource);
    }

    pDevice->Release();

    return hr;
}

static image::Image *
getSubResourceImage(ID3D11DeviceContext *pDevice,
                    ID3D11Resource *pResource,
                    DXGI_FORMAT Format,
                    UINT ArraySlice,
                    UINT MipSlice)
{
    image::Image *image = NULL;
    ID3D11Resource *pStagingResource = NULL;
    UINT Width, Height, Depth;
    UINT MipLevels;
    UINT SubResource;
    D3D11_MAPPED_SUBRESOURCE MappedSubResource;
    HRESULT hr;

    if (!pResource) {
        return NULL;
    }

    hr = stageResource(pDevice, pResource, &pStagingResource, &Width, &Height, &Depth, &MipLevels);
    if (FAILED(hr)) {
        goto no_staging;
    }

    SubResource = ArraySlice*MipLevels + MipSlice;

    Width  = std::max(Width  >> MipSlice, 1U);
    Height = std::max(Height >> MipSlice, 1U);
    Depth  = std::max(Depth  >> MipSlice, 1U);

    hr = pDevice->Map(pStagingResource, SubResource, D3D11_MAP_READ, 0, &MappedSubResource);
    if (FAILED(hr)) {
        goto no_map;
    }

    image = ConvertImage(Format,
                         MappedSubResource.pData,
                         MappedSubResource.RowPitch,
                         Width, Height);

    pDevice->Unmap(pStagingResource, SubResource);
no_map:
    if (pStagingResource) {
        pStagingResource->Release();
    }
no_staging:
    if (pResource) {
        pResource->Release();
    }
    return image;
}

static void
dumpShaderResourceViewImage(JSONWriter &json,
                            ID3D11DeviceContext *pDevice,
                            ID3D11ShaderResourceView *pShaderResourceView,
                            const char *shader,
                            UINT stage) {
    D3D11_SHADER_RESOURCE_VIEW_DESC Desc;
    ID3D11Resource *pResource = NULL;

    if (!pShaderResourceView) {
        return;
    }

    pShaderResourceView->GetResource(&pResource);
    assert(pResource);

    pShaderResourceView->GetDesc(&Desc);

    UINT MipSlice = 0;
    UINT FirstArraySlice = 0;
    UINT ArraySize = 1;

    // TODO: Take the slice in consideration
    switch (Desc.ViewDimension) {
    case D3D11_SRV_DIMENSION_BUFFER:
        break;
    case D3D11_SRV_DIMENSION_TEXTURE1D:
        MipSlice = Desc.Texture1D.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
        MipSlice = Desc.Texture1DArray.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURE2D:
        MipSlice = Desc.Texture2D.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
        MipSlice = Desc.Texture2DArray.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURE2DMS:
        break;
    case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
        break;
    case D3D11_SRV_DIMENSION_TEXTURE3D:
        MipSlice = Desc.Texture3D.MostDetailedMip;
        break;
    case D3D11_SRV_DIMENSION_TEXTURECUBE:
        MipSlice = Desc.TextureCube.MostDetailedMip;
        ArraySize = 6;
        break;
    case D3D11_SRV_DIMENSION_UNKNOWN:
    default:
        assert(0);
        return;
    }

    for (UINT ArraySlice = FirstArraySlice; ArraySlice < FirstArraySlice + ArraySize; ++ArraySlice) {

        image::Image *image;
        image = getSubResourceImage(pDevice, pResource, Desc.Format, ArraySlice, MipSlice);
        if (image) {
            char label[64];
            _snprintf(label, sizeof label,
                      "%s_RESOURCE_%u_ARRAY_%u_LEVEL_%u",
                      shader, stage, ArraySlice, MipSlice);
            json.beginMember(label);
            json.writeImage(image, "UNKNOWN");
            json.endMember(); // *_RESOURCE_*
            delete image;
        }

    }
}

static image::Image *
getRenderTargetViewImage(ID3D11DeviceContext *pDevice,
                         ID3D11RenderTargetView *pRenderTargetView) {
    D3D11_RENDER_TARGET_VIEW_DESC Desc;
    ID3D11Resource *pResource = NULL;
    UINT MipSlice;

    if (!pRenderTargetView) {
        return NULL;
    }

    pRenderTargetView->GetResource(&pResource);
    assert(pResource);

    pRenderTargetView->GetDesc(&Desc);

    // TODO: Take the slice in consideration
    switch (Desc.ViewDimension) {
    case D3D11_RTV_DIMENSION_BUFFER:
        MipSlice = 0;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE1D:
        MipSlice = Desc.Texture1D.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
        MipSlice = Desc.Texture1DArray.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE2D:
        MipSlice = Desc.Texture2D.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
        MipSlice = Desc.Texture2DArray.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE2DMS:
        MipSlice = 0;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
        MipSlice = 0;
        break;
    case D3D11_RTV_DIMENSION_TEXTURE3D:
        MipSlice = Desc.Texture3D.MipSlice;
        break;
    case D3D11_RTV_DIMENSION_UNKNOWN:
    default:
        assert(0);
        return NULL;
    }

    return getSubResourceImage(pDevice, pResource, Desc.Format, 0, MipSlice);
}

static image::Image *
getDepthStencilViewImage(ID3D11DeviceContext *pDevice,
                         ID3D11DepthStencilView *pDepthStencilView) {
    D3D11_DEPTH_STENCIL_VIEW_DESC Desc;
    ID3D11Resource *pResource = NULL;
    UINT MipSlice;

    if (!pDepthStencilView) {
        return NULL;
    }

    pDepthStencilView->GetResource(&pResource);
    assert(pResource);

    pDepthStencilView->GetDesc(&Desc);

    // TODO: Take the slice in consideration
    switch (Desc.ViewDimension) {
    case D3D11_DSV_DIMENSION_TEXTURE1D:
        MipSlice = Desc.Texture1D.MipSlice;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
        MipSlice = Desc.Texture1DArray.MipSlice;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE2D:
        MipSlice = Desc.Texture2D.MipSlice;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
        MipSlice = Desc.Texture2DArray.MipSlice;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE2DMS:
        MipSlice = 0;
        break;
    case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
        MipSlice = 0;
        break;
    case D3D11_DSV_DIMENSION_UNKNOWN:
    default:
        assert(0);
        return NULL;
    }

    return getSubResourceImage(pDevice, pResource, Desc.Format, 0, MipSlice);
}

static void
dumpStageTextures(JSONWriter &json, ID3D11DeviceContext *pDevice, const char *stageName,
                  UINT NumViews,
                  ID3D11ShaderResourceView **ppShaderResourceViews)
{
    for (UINT i = 0; i < NumViews; ++i) {
        if (!ppShaderResourceViews[i]) {
            continue;
        }

        dumpShaderResourceViewImage(json, pDevice, ppShaderResourceViews[i], stageName, i);

        ppShaderResourceViews[i]->Release();
    }
}

void
dumpTextures(JSONWriter &json, ID3D11DeviceContext *pDevice)
{
    json.beginMember("textures");
    json.beginObject();

    ID3D11ShaderResourceView *pShaderResourceViews[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];

    pDevice->PSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
    dumpStageTextures(json, pDevice, "PS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);

    pDevice->VSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
    dumpStageTextures(json, pDevice, "VS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);

    pDevice->GSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);
    dumpStageTextures(json, pDevice, "GS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews);

    json.endObject();
    json.endMember(); // textures
}

image::Image *
getRenderTargetImage(ID3D11DeviceContext *pDevice) {
    ID3D11RenderTargetView *pRenderTargetView = NULL;
    pDevice->OMGetRenderTargets(1, &pRenderTargetView, NULL);

    image::Image *image = NULL;
    if (pRenderTargetView) {
        image = getRenderTargetViewImage(pDevice, pRenderTargetView);
        pRenderTargetView->Release();
    }

    return image;
}

void
dumpFramebuffer(JSONWriter &json, ID3D11DeviceContext *pDevice)
{
    json.beginMember("framebuffer");
    json.beginObject();

    ID3D11RenderTargetView *pRenderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
    ID3D11DepthStencilView *pDepthStencilView;
    pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews,
                                &pDepthStencilView);

    for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) {
        if (!pRenderTargetViews[i]) {
            continue;
        }

        image::Image *image;
        image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]);
        if (image) {
            char label[64];
            _snprintf(label, sizeof label, "RENDER_TARGET_%u", i);
            json.beginMember(label);
            json.writeImage(image, "UNKNOWN");
            json.endMember(); // RENDER_TARGET_*
            delete image;
        }

        pRenderTargetViews[i]->Release();
    }

    if (pDepthStencilView) {
        image::Image *image;
        image = getDepthStencilViewImage(pDevice, pDepthStencilView);
        if (image) {
            json.beginMember("DEPTH_STENCIL");
            json.writeImage(image, "UNKNOWN");
            json.endMember();
            delete image;
        }

        pDepthStencilView->Release();

    }

    json.endObject();
    json.endMember(); // framebuffer
}

} /* namespace d3dstate */
<|endoftext|>


<commit_before><commit_msg>modify sizes for visibility check<commit_after><|endoftext|>


<commit_before><commit_msg>Lots more notes, hopefully handling the parity bit correctly<commit_after><|endoftext|>