<commit_before>/*
 * Copyright (c) 2012-2013, The University of Oxford
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name of the University of Oxford 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 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.
 */

#include "apps/lib/oskar_telescope_model_element_pattern_load.h"

#include "interferometry/oskar_telescope_model_load_station_coords.h"
#include "interferometry/oskar_telescope_model_location.h"
#include "interferometry/oskar_telescope_model_type.h"
#include "interferometry/oskar_telescope_model_resize.h"
#include "station/oskar_ElementModel.h"
#include "station/oskar_element_model_copy.h"
#include "station/oskar_element_model_init.h"
#include "station/oskar_element_model_load_cst.h"
#include "station/oskar_station_model_init.h"
#include "station/oskar_station_model_load_config.h"
#include "station/oskar_station_model_resize_element_types.h"
#include "utility/oskar_log_message.h"
#include "utility/oskar_log_error.h"
#include "utility/oskar_get_error_string.h"

#include <cstdlib>
#include <QtCore/QDir>
#include <QtCore/QStringList>
#include <QtCore/QHash>

// Element pattern filenames.
static const char element_x_cst_file[] = "element_pattern_x_cst.txt";
static const char element_y_cst_file[] = "element_pattern_y_cst.txt";

// Private functions.
static void load_directories(oskar_TelescopeModel* telescope,
        oskar_Log* log, const oskar_SettingsTelescope* settings,
        const QDir& cwd, oskar_StationModel* station,
        int depth, QHash<QString, QString> files,
        QHash<QString, oskar_ElementModel*>& models, int* status);
static void load_element_patterns(oskar_Log* log,
        const oskar_SettingsTelescope* settings,
        oskar_StationModel* station, QHash<QString, QString>& data_files,
        QHash<QString, oskar_ElementModel*>& models, int* status);

extern "C"
void oskar_telescope_model_element_pattern_load(oskar_TelescopeModel* telescope,
        oskar_Log* log, const oskar_SettingsTelescope* settings, int* status)
{
    // Check all inputs.
    if (!telescope || !settings || !status)
    {
        oskar_set_invalid_argument(status);
        return;
    }

    // Check if safe to proceed.
    if (*status) return;

    if (!settings->aperture_array.element_pattern.enable_numerical_patterns)
        return;

    QHash<QString, oskar_ElementModel*> models;
    QHash<QString, QString> data_files;

    QDir telescope_dir(settings->input_directory);
    if (!telescope_dir.exists())
    {
        *status = OSKAR_ERR_FILE_IO;
        return;
    }

    // Check that the telescope model is in CPU memory.
    if (oskar_telescope_model_location(telescope) != OSKAR_LOCATION_CPU)
    {
        *status = OSKAR_ERR_BAD_LOCATION;
        return;
    }

    // Load element data by scanning the directory structure and loading
    // the element files deepest in the tree.
    load_directories(telescope, log, settings, telescope_dir, NULL,
            0, data_files, models, status);
    if (*status)
        oskar_log_error(log, "Loading element pattern files (%s).",
                oskar_get_error_string(*status));
}

// Private functions

static void load_directories(oskar_TelescopeModel* telescope,
        oskar_Log* log, const oskar_SettingsTelescope* settings,
        const QDir& cwd, oskar_StationModel* station,
        int depth, QHash<QString, QString> files,
        QHash<QString, oskar_ElementModel*>& models, int* status)
{
    // Check if safe to proceed.
    if (*status) return;

    // Update the dictionary of element files for the current station directory.
    if (cwd.exists(element_x_cst_file))
        files[QString(element_x_cst_file)] = cwd.absoluteFilePath(element_x_cst_file);
    if (cwd.exists(element_y_cst_file))
        files[QString(element_y_cst_file)] = cwd.absoluteFilePath(element_y_cst_file);

    // Get a list of the child stations.
    QStringList children;
    children = cwd.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name);
    int num_dirs = children.size();

    // If the station / child arrays haven't been allocated
    // (by oskar_telescope_load_config() for example), allocate them.
    if (depth == 0 && telescope->station == NULL)
    {
        oskar_telescope_model_resize(telescope, num_dirs, status);
    }
    else if (depth > 0 && num_dirs > 0 && station->child == NULL)
    {
        int type = oskar_telescope_model_type(telescope);
        station->child = (oskar_StationModel*) malloc(num_dirs *
                sizeof(oskar_StationModel));
        if (!station->child)
        {
            *status = OSKAR_ERR_MEMORY_ALLOC_FAILURE;
            return;
        }
        for (int i = 0; i < num_dirs; ++i)
        {
            oskar_station_model_init(&station->child[i], type,
                    OSKAR_LOCATION_CPU, 0, status);
        }
    }

    // Loop over, and descend into the child stations.
    for (int i = 0; i < num_dirs; ++i)
    {
        // Get a pointer to the child station.
        oskar_StationModel* s;
        s = (depth == 0) ? &telescope->station[i] : &station->child[i];

        // Get the child directory.
        QDir child_dir(cwd.filePath(children[i]));

        // Load this (child) station.
        load_directories(telescope, log, settings, child_dir, s,
                depth + 1, files, models, status);
    }

    // If there are no children, load the element pattern data corresponding
    // to the deepest element file found in the tree.
    if (num_dirs == 0)
    {
        if (station)
        {
            oskar_station_model_resize_element_types(station, 1, status);
            load_element_patterns(log, settings, station, files, models, status);
        }
        else
        {
            for (int i = 0; i < telescope->num_stations; ++i)
            {
                oskar_StationModel* s = &telescope->station[i];
                oskar_station_model_resize_element_types(s, 1, status);
                load_element_patterns(log, settings, s, files, models, status);
            }
        }
    }
}

static void load_element_patterns(oskar_Log* log,
        const oskar_SettingsTelescope* settings, oskar_StationModel* station,
        QHash<QString, QString>& data_files,
        QHash<QString, oskar_ElementModel*>& models, int* status)
{
    // Check if safe to proceed.
    if (*status) return;

    QByteArray element_x, element_y;
    const char *element_file_x = NULL, *element_file_y = NULL;

    if (data_files.contains(QString(element_x_cst_file)))
    {
        element_x = data_files.value(QString(element_x_cst_file)).toAscii();
        element_file_x = element_x.constData();
    }
    if (data_files.contains(QString(element_y_cst_file)))
    {
        element_y = data_files.value(QString(element_y_cst_file)).toAscii();
        element_file_y = element_y.constData();
    }

    QString files;
    if (element_file_x) files.append(element_file_x);
    if (element_file_y) files.append(element_file_y);
    if (files.length() > 0)
    {
        // Check if this file combination has already been loaded.
        if (models.contains(files))
        {
            // Copy the element pattern data.
            oskar_element_model_copy(station->element_pattern,
                    models.value(files), status);
        }
        else
        {
            // Load CST element pattern data.
            if (element_file_x)
            {
                oskar_log_message(log, 0, "Loading CST element "
                        "pattern data (X): %s", element_file_x);
                oskar_log_message(log, 0, "");
                oskar_element_model_load_cst(station->element_pattern,
                        log, 1, element_file_x,
                        &settings->aperture_array.element_pattern.fit, status);
            }
            if (element_file_y)
            {
                oskar_log_message(log, 0, "Loading CST element "
                        "pattern data (Y): %s", element_file_y);
                oskar_log_message(log, 0, "");
                oskar_element_model_load_cst(station->element_pattern,
                        log, 2, element_file_y,
                        &settings->aperture_array.element_pattern.fit, status);
            }

            // Store pointer to the element model for these files.
            models.insert(files, station->element_pattern);
        }
    }
}
<commit_msg>Marked hash as const.<commit_after>/*
 * Copyright (c) 2012-2013, The University of Oxford
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name of the University of Oxford 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 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.
 */

#include "apps/lib/oskar_telescope_model_element_pattern_load.h"

#include "interferometry/oskar_telescope_model_load_station_coords.h"
#include "interferometry/oskar_telescope_model_location.h"
#include "interferometry/oskar_telescope_model_type.h"
#include "interferometry/oskar_telescope_model_resize.h"
#include "station/oskar_ElementModel.h"
#include "station/oskar_element_model_copy.h"
#include "station/oskar_element_model_init.h"
#include "station/oskar_element_model_load_cst.h"
#include "station/oskar_station_model_init.h"
#include "station/oskar_station_model_load_config.h"
#include "station/oskar_station_model_resize_element_types.h"
#include "utility/oskar_log_message.h"
#include "utility/oskar_log_error.h"
#include "utility/oskar_get_error_string.h"

#include <cstdlib>
#include <QtCore/QDir>
#include <QtCore/QStringList>
#include <QtCore/QHash>

// Element pattern filenames.
static const char element_x_cst_file[] = "element_pattern_x_cst.txt";
static const char element_y_cst_file[] = "element_pattern_y_cst.txt";

// Private functions.
static void load_directories(oskar_TelescopeModel* telescope,
        oskar_Log* log, const oskar_SettingsTelescope* settings,
        const QDir& cwd, oskar_StationModel* station,
        int depth, QHash<QString, QString> files,
        QHash<QString, oskar_ElementModel*>& models, int* status);
static void load_element_patterns(oskar_Log* log,
        const oskar_SettingsTelescope* settings,
        oskar_StationModel* station, const QHash<QString, QString>& data_files,
        QHash<QString, oskar_ElementModel*>& models, int* status);

extern "C"
void oskar_telescope_model_element_pattern_load(oskar_TelescopeModel* telescope,
        oskar_Log* log, const oskar_SettingsTelescope* settings, int* status)
{
    // Check all inputs.
    if (!telescope || !settings || !status)
    {
        oskar_set_invalid_argument(status);
        return;
    }

    // Check if safe to proceed.
    if (*status) return;

    if (!settings->aperture_array.element_pattern.enable_numerical_patterns)
        return;

    QHash<QString, oskar_ElementModel*> models;
    QHash<QString, QString> data_files;

    QDir telescope_dir(settings->input_directory);
    if (!telescope_dir.exists())
    {
        *status = OSKAR_ERR_FILE_IO;
        return;
    }

    // Check that the telescope model is in CPU memory.
    if (oskar_telescope_model_location(telescope) != OSKAR_LOCATION_CPU)
    {
        *status = OSKAR_ERR_BAD_LOCATION;
        return;
    }

    // Load element data by scanning the directory structure and loading
    // the element files deepest in the tree.
    load_directories(telescope, log, settings, telescope_dir, NULL,
            0, data_files, models, status);
    if (*status)
        oskar_log_error(log, "Loading element pattern files (%s).",
                oskar_get_error_string(*status));
}

// Private functions

static void load_directories(oskar_TelescopeModel* telescope,
        oskar_Log* log, const oskar_SettingsTelescope* settings,
        const QDir& cwd, oskar_StationModel* station,
        int depth, QHash<QString, QString> files,
        QHash<QString, oskar_ElementModel*>& models, int* status)
{
    // Check if safe to proceed.
    if (*status) return;

    // Update the dictionary of element files for the current station directory.
    if (cwd.exists(element_x_cst_file))
        files[QString(element_x_cst_file)] = cwd.absoluteFilePath(element_x_cst_file);
    if (cwd.exists(element_y_cst_file))
        files[QString(element_y_cst_file)] = cwd.absoluteFilePath(element_y_cst_file);

    // Get a list of the child stations.
    QStringList children;
    children = cwd.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name);
    int num_dirs = children.size();

    // If the station / child arrays haven't been allocated
    // (by oskar_telescope_load_config() for example), allocate them.
    if (depth == 0 && telescope->station == NULL)
    {
        oskar_telescope_model_resize(telescope, num_dirs, status);
    }
    else if (depth > 0 && num_dirs > 0 && station->child == NULL)
    {
        int type = oskar_telescope_model_type(telescope);
        station->child = (oskar_StationModel*) malloc(num_dirs *
                sizeof(oskar_StationModel));
        if (!station->child)
        {
            *status = OSKAR_ERR_MEMORY_ALLOC_FAILURE;
            return;
        }
        for (int i = 0; i < num_dirs; ++i)
        {
            oskar_station_model_init(&station->child[i], type,
                    OSKAR_LOCATION_CPU, 0, status);
        }
    }

    // Loop over, and descend into the child stations.
    for (int i = 0; i < num_dirs; ++i)
    {
        // Get a pointer to the child station.
        oskar_StationModel* s;
        s = (depth == 0) ? &telescope->station[i] : &station->child[i];

        // Get the child directory.
        QDir child_dir(cwd.filePath(children[i]));

        // Load this (child) station.
        load_directories(telescope, log, settings, child_dir, s,
                depth + 1, files, models, status);
    }

    // If there are no children, load the element pattern data corresponding
    // to the deepest element file found in the tree.
    if (num_dirs == 0)
    {
        if (station)
        {
            oskar_station_model_resize_element_types(station, 1, status);
            load_element_patterns(log, settings, station, files, models, status);
        }
        else
        {
            for (int i = 0; i < telescope->num_stations; ++i)
            {
                oskar_StationModel* s = &telescope->station[i];
                oskar_station_model_resize_element_types(s, 1, status);
                load_element_patterns(log, settings, s, files, models, status);
            }
        }
    }
}

static void load_element_patterns(oskar_Log* log,
        const oskar_SettingsTelescope* settings, oskar_StationModel* station,
        const QHash<QString, QString>& data_files,
        QHash<QString, oskar_ElementModel*>& models, int* status)
{
    // Check if safe to proceed.
    if (*status) return;

    QByteArray element_x, element_y;
    const char *element_file_x = NULL, *element_file_y = NULL;

    if (data_files.contains(QString(element_x_cst_file)))
    {
        element_x = data_files.value(QString(element_x_cst_file)).toAscii();
        element_file_x = element_x.constData();
    }
    if (data_files.contains(QString(element_y_cst_file)))
    {
        element_y = data_files.value(QString(element_y_cst_file)).toAscii();
        element_file_y = element_y.constData();
    }

    QString files;
    if (element_file_x) files.append(element_file_x);
    if (element_file_y) files.append(element_file_y);
    if (files.length() > 0)
    {
        // Check if this file combination has already been loaded.
        if (models.contains(files))
        {
            // Copy the element pattern data.
            oskar_element_model_copy(station->element_pattern,
                    models.value(files), status);
        }
        else
        {
            // Load CST element pattern data.
            if (element_file_x)
            {
                oskar_log_message(log, 0, "Loading CST element "
                        "pattern data (X): %s", element_file_x);
                oskar_log_message(log, 0, "");
                oskar_element_model_load_cst(station->element_pattern,
                        log, 1, element_file_x,
                        &settings->aperture_array.element_pattern.fit, status);
            }
            if (element_file_y)
            {
                oskar_log_message(log, 0, "Loading CST element "
                        "pattern data (Y): %s", element_file_y);
                oskar_log_message(log, 0, "");
                oskar_element_model_load_cst(station->element_pattern,
                        log, 2, element_file_y,
                        &settings->aperture_array.element_pattern.fit, status);
            }

            // Store pointer to the element model for these files.
            models.insert(files, station->element_pattern);
        }
    }
}
<|endoftext|>


<commit_before>#include "lite/handle_syscalls.h"
#include "simulator.h"
#include "thread_manager.h"
#include "thread.h"
#include "syscall_model.h"
#include "performance_model.h"
#include "log.h"
#include "syscall_strings.h"
#include "local_storage.h"

#include <syscall.h>
#include <stdlib.h>

namespace lite
{

void handleSyscall(THREADID threadIndex, CONTEXT* ctx)
{
   // We shouldn't block on actual SYS_futex calls while inside the SyscallEntry function
   // Therefore, do all the work here, which is at INS_InsertCall(syscall, IPOINT_BEFORE)

   IntPtr syscall_number = PIN_GetContextReg (ctx, REG_GAX);
   LOG_PRINT("Syscall Number(%d)", syscall_number);
   //printf("Entering syscall %s(%ld)\n", syscall_string(syscall_number), syscall_number);

   SyscallMdl::syscall_args_t args;

#ifdef TARGET_IA32
   args.arg0 = PIN_GetContextReg (ctx, REG_GBX);
   args.arg1 = PIN_GetContextReg (ctx, REG_GCX);
   args.arg2 = PIN_GetContextReg (ctx, REG_GDX);
   args.arg3 = PIN_GetContextReg (ctx, REG_GSI);
   args.arg4 = PIN_GetContextReg (ctx, REG_GDI);
   args.arg5 = PIN_GetContextReg (ctx, REG_GBP);
#endif

#ifdef TARGET_INTEL64
   // FIXME: The LEVEL_BASE:: ugliness is required by the fact that REG_R8 etc
   // are also defined in /usr/include/sys/ucontext.h
   args.arg0 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_GDI);
   args.arg1 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_GSI);
   args.arg2 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_GDX);
   args.arg3 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_R10);
   args.arg4 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_R8);
   args.arg5 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_R9);
#endif

   if (syscall_number == SYS_clone)
   {
      localStore[threadIndex].pthread_create.tid_ptr = (void*)args.arg4;
      localStore[threadIndex].pthread_create.clear_tid = args.arg0 & CLONE_CHILD_CLEARTID ? true : false;
   }

   Thread* thread = Sim()->getThreadManager()->getCurrentThread(threadIndex);
   LOG_ASSERT_ERROR(thread != NULL, "Thread(NULL)");
   thread->getSyscallMdl()->runEnter(syscall_number, args);
}

void syscallEnterRunModel(THREADID threadIndex, CONTEXT* ctx, SYSCALL_STANDARD syscall_standard, void* v)
{
   Thread* thread = Sim()->getThreadManager()->getCurrentThread(threadIndex);
   LOG_ASSERT_ERROR(thread != NULL, "Thread(NULL)");
   if (thread->getSyscallMdl()->isEmulated())
   {
      PIN_SetSyscallNumber(ctx, syscall_standard, SYS_getpid);
   }
}

void syscallExitRunModel(THREADID threadIndex, CONTEXT* ctx, SYSCALL_STANDARD syscall_standard, void* v)
{
   Thread* thread = Sim()->getThreadManager()->getCurrentThread(threadIndex);
   LOG_ASSERT_ERROR(thread != NULL, "Thread(NULL)");

   if (thread->getSyscallMdl()->isEmulated())
   {
      IntPtr old_return_val = PIN_GetSyscallReturn (ctx, syscall_standard);
      IntPtr syscall_return = thread->getSyscallMdl()->runExit(old_return_val);
      PIN_SetContextReg(ctx, REG_GAX, syscall_return);

      LOG_PRINT("Syscall returned (%p)", syscall_return);
   }
   else
   {
      thread->getSyscallMdl()->runExit(0);
   }
}

bool interceptSignal(THREADID threadIndex, INT32 signal, CONTEXT *ctx, BOOL hasHandler, const EXCEPTION_INFO *pExceptInfo, void* v)
{
   ADDRINT eip = PIN_GetContextReg(ctx, REG_INST_PTR);
   fprintf(stderr, "Application received fatal signal %u at eip %p\n", signal, (void*)eip);

   INT32 column, line;
   string fileName;
   PIN_GetSourceLocation(eip, &column, &line, &fileName);
   fprintf(stderr, "in %s:%u\n", fileName.c_str(), line);

   switch(PIN_GetDebugStatus())
   {
      case DEBUG_STATUS_CONNECTED:
         // A debugger is already connected, it should just break
         break;
      // TODO: This is supposed to work in a future Pin version. Right now, a fatal signal will kill Pin & the application
      case DEBUG_STATUS_UNCONNECTED:
         // The -appdebug_enable switch was used, but no debugger is currently connected
         // Instruct the user to do this now
         DEBUG_CONNECTION_INFO info;
         if (!PIN_GetDebugConnectionInfo(&info) || info._type != DEBUG_CONNECTION_TYPE_TCP_SERVER)
            break;
         fprintf(stderr, "\nStart GDB and enter this command:\n  target remote :%d\n\n", info._tcpServer._tcpPort);
         PIN_WaitForDebuggerToConnect(0);
         break;
      case DEBUG_STATUS_UNCONNECTABLE:
         // Application debugging is enabled, but it is too early to allow a debugger to connect
         fprintf(stderr, "\nApplication debugging is enabled, but it is too early to allow a debugger to connect.\n\n");
         exit(0);
      case DEBUG_STATUS_DISABLED:
         // No -appdebug* switch given to Pin, nothing we can do
         fprintf(stderr, "\nApplication debugging is currently disabled.\nTo enable it, start Sniper with the --appdebug or --appdebug-wait command line switch.\n\n");
         exit(0);
   }

   return true;
}

}
<commit_msg>[PATCH 12/51] [pin] On SYS_clone, tid_ptr argument is in arg3, not arg4<commit_after>#include "lite/handle_syscalls.h"
#include "simulator.h"
#include "thread_manager.h"
#include "thread.h"
#include "syscall_model.h"
#include "performance_model.h"
#include "log.h"
#include "syscall_strings.h"
#include "local_storage.h"

#include <syscall.h>
#include <stdlib.h>

namespace lite
{

void handleSyscall(THREADID threadIndex, CONTEXT* ctx)
{
   // We shouldn't block on actual SYS_futex calls while inside the SyscallEntry function
   // Therefore, do all the work here, which is at INS_InsertCall(syscall, IPOINT_BEFORE)

   IntPtr syscall_number = PIN_GetContextReg (ctx, REG_GAX);
   LOG_PRINT("Syscall Number(%d)", syscall_number);
   //printf("Entering syscall %s(%ld)\n", syscall_string(syscall_number), syscall_number);

   SyscallMdl::syscall_args_t args;

#ifdef TARGET_IA32
   args.arg0 = PIN_GetContextReg (ctx, REG_GBX);
   args.arg1 = PIN_GetContextReg (ctx, REG_GCX);
   args.arg2 = PIN_GetContextReg (ctx, REG_GDX);
   args.arg3 = PIN_GetContextReg (ctx, REG_GSI);
   args.arg4 = PIN_GetContextReg (ctx, REG_GDI);
   args.arg5 = PIN_GetContextReg (ctx, REG_GBP);
#endif

#ifdef TARGET_INTEL64
   // FIXME: The LEVEL_BASE:: ugliness is required by the fact that REG_R8 etc
   // are also defined in /usr/include/sys/ucontext.h
   args.arg0 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_GDI);
   args.arg1 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_GSI);
   args.arg2 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_GDX);
   args.arg3 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_R10);
   args.arg4 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_R8);
   args.arg5 = PIN_GetContextReg (ctx, LEVEL_BASE::REG_R9);
#endif

   if (syscall_number == SYS_clone)
   {
      localStore[threadIndex].pthread_create.tid_ptr = (void*)args.arg3;
      localStore[threadIndex].pthread_create.clear_tid = args.arg0 & CLONE_CHILD_CLEARTID ? true : false;
   }

   Thread* thread = Sim()->getThreadManager()->getCurrentThread(threadIndex);
   LOG_ASSERT_ERROR(thread != NULL, "Thread(NULL)");
   thread->getSyscallMdl()->runEnter(syscall_number, args);
}

void syscallEnterRunModel(THREADID threadIndex, CONTEXT* ctx, SYSCALL_STANDARD syscall_standard, void* v)
{
   Thread* thread = Sim()->getThreadManager()->getCurrentThread(threadIndex);
   LOG_ASSERT_ERROR(thread != NULL, "Thread(NULL)");
   if (thread->getSyscallMdl()->isEmulated())
   {
      PIN_SetSyscallNumber(ctx, syscall_standard, SYS_getpid);
   }
}

void syscallExitRunModel(THREADID threadIndex, CONTEXT* ctx, SYSCALL_STANDARD syscall_standard, void* v)
{
   Thread* thread = Sim()->getThreadManager()->getCurrentThread(threadIndex);
   LOG_ASSERT_ERROR(thread != NULL, "Thread(NULL)");

   if (thread->getSyscallMdl()->isEmulated())
   {
      IntPtr old_return_val = PIN_GetSyscallReturn (ctx, syscall_standard);
      IntPtr syscall_return = thread->getSyscallMdl()->runExit(old_return_val);
      PIN_SetContextReg(ctx, REG_GAX, syscall_return);

      LOG_PRINT("Syscall returned (%p)", syscall_return);
   }
   else
   {
      thread->getSyscallMdl()->runExit(0);
   }
}

bool interceptSignal(THREADID threadIndex, INT32 signal, CONTEXT *ctx, BOOL hasHandler, const EXCEPTION_INFO *pExceptInfo, void* v)
{
   ADDRINT eip = PIN_GetContextReg(ctx, REG_INST_PTR);
   fprintf(stderr, "Application received fatal signal %u at eip %p\n", signal, (void*)eip);

   INT32 column, line;
   string fileName;
   PIN_GetSourceLocation(eip, &column, &line, &fileName);
   fprintf(stderr, "in %s:%u\n", fileName.c_str(), line);

   switch(PIN_GetDebugStatus())
   {
      case DEBUG_STATUS_CONNECTED:
         // A debugger is already connected, it should just break
         break;
      // TODO: This is supposed to work in a future Pin version. Right now, a fatal signal will kill Pin & the application
      case DEBUG_STATUS_UNCONNECTED:
         // The -appdebug_enable switch was used, but no debugger is currently connected
         // Instruct the user to do this now
         DEBUG_CONNECTION_INFO info;
         if (!PIN_GetDebugConnectionInfo(&info) || info._type != DEBUG_CONNECTION_TYPE_TCP_SERVER)
            break;
         fprintf(stderr, "\nStart GDB and enter this command:\n  target remote :%d\n\n", info._tcpServer._tcpPort);
         PIN_WaitForDebuggerToConnect(0);
         break;
      case DEBUG_STATUS_UNCONNECTABLE:
         // Application debugging is enabled, but it is too early to allow a debugger to connect
         fprintf(stderr, "\nApplication debugging is enabled, but it is too early to allow a debugger to connect.\n\n");
         exit(0);
      case DEBUG_STATUS_DISABLED:
         // No -appdebug* switch given to Pin, nothing we can do
         fprintf(stderr, "\nApplication debugging is currently disabled.\nTo enable it, start Sniper with the --appdebug or --appdebug-wait command line switch.\n\n");
         exit(0);
   }

   return true;
}

}
<|endoftext|>


<commit_before>
/*
 * Copyright 2010 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrTemplates.h"
#include "SkGr.h"
#include "SkDescriptor.h"
#include "SkGlyphCache.h"

class SkGrDescKey : public GrKey {
public:
    explicit SkGrDescKey(const SkDescriptor& desc);
    virtual ~SkGrDescKey();

protected:
    // overrides
    virtual bool lt(const GrKey& rh) const;
    virtual bool eq(const GrKey& rh) const;

private:
    SkDescriptor* fDesc;
    enum {
        kMaxStorageInts = 16
    };
    uint32_t fStorage[kMaxStorageInts];
};

///////////////////////////////////////////////////////////////////////////////

SkGrDescKey::SkGrDescKey(const SkDescriptor& desc) : GrKey(desc.getChecksum()) {
    size_t size = desc.getLength();
    if (size <= sizeof(fStorage)) {
        fDesc = GrTCast<SkDescriptor*>(fStorage);
    } else {
        fDesc = SkDescriptor::Alloc(size);
    }
    memcpy(fDesc, &desc, size);
}

SkGrDescKey::~SkGrDescKey() {
    if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
        SkDescriptor::Free(fDesc);
    }
}

bool SkGrDescKey::lt(const GrKey& rh) const {
    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
    size_t lenLH = fDesc->getLength();
    size_t lenRH = srcDesc->getLength();
    int cmp = memcmp(fDesc, srcDesc, SkMin32(lenLH, lenRH));
    if (0 == cmp) {
        return lenLH < lenRH;
    } else {
        return cmp < 0;
    }
}

bool SkGrDescKey::eq(const GrKey& rh) const {
    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
    return fDesc->equals(*srcDesc);
}

///////////////////////////////////////////////////////////////////////////////

SkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) {
    fStrike = strike;
    fKey = NULL;
}

SkGrFontScaler::~SkGrFontScaler() {
    GrSafeUnref(fKey);
}

GrMaskFormat SkGrFontScaler::getMaskFormat() {
    SkMask::Format format = fStrike->getMaskFormat();
    switch (format) {
        case SkMask::kBW_Format:
            // fall through to kA8 -- we store BW glyphs in our 8-bit cache
        case SkMask::kA8_Format:
            return kA8_GrMaskFormat;
        case SkMask::kLCD16_Format:
            return kA565_GrMaskFormat;
        case SkMask::kLCD32_Format:
            return kA888_GrMaskFormat;
        default:
            GrAssert(!"unsupported SkMask::Format");
            return kA8_GrMaskFormat;
    }
}

const GrKey* SkGrFontScaler::getKey() {
    if (NULL == fKey) {
        fKey = SkNEW_ARGS(SkGrDescKey, (fStrike->getDescriptor()));
    }
    return fKey;
}

bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed,
                                          GrIRect* bounds) {
    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
                                              GrGlyph::UnpackFixedX(packed),
                                              GrGlyph::UnpackFixedY(packed));
    bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
    return true;

}

namespace {
// expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a BW glyph mask to
// A8, RGB565, or RGBA8888.
template <typename INT_TYPE>
void expand_bits(INT_TYPE* dst,
                 const uint8_t* src,
                 int width,
                 int height,
                 int dstRowBytes,
                 int srcRowBytes) {
    for (int i = 0; i < height; ++i) {
        int rowWritesLeft = width;
        const uint8_t* s = src;
        INT_TYPE* d = dst;
        while (rowWritesLeft > 0) {
            unsigned mask = *s++;
            for (int i = 7; i >= 0 && rowWritesLeft; --i, --rowWritesLeft) {
                *d++ = (mask & (1 << i)) ? (INT_TYPE)(~0UL) : 0;
            }
        }
        dst = reinterpret_cast<INT_TYPE*>(reinterpret_cast<intptr_t>(dst) + dstRowBytes);
        src += srcRowBytes;
    }
}
}

bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
                                         int width, int height,
                                         int dstRB, void* dst) {
    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
                                              GrGlyph::UnpackFixedX(packed),
                                              GrGlyph::UnpackFixedY(packed));
    GrAssert(glyph.fWidth == width);
    GrAssert(glyph.fHeight == height);
    const void* src = fStrike->findImage(glyph);
    if (NULL == src) {
        return false;
    }

    int srcRB = glyph.rowBytes();
    // The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to
    // check the glyph's format, not the strike's format, and to be able to convert to any of the
    // GrMaskFormats.
    if (SkMask::kBW_Format == glyph.fMaskFormat) {
        // expand bits to our mask type
        const uint8_t* bits = reinterpret_cast<const uint8_t*>(src);
        switch (this->getMaskFormat()) {
            case kA8_GrMaskFormat:{
                uint8_t* bytes = reinterpret_cast<uint8_t*>(dst);
                expand_bits(bytes, bits, width, height, dstRB, srcRB);
                break;
            }
            case kA565_GrMaskFormat: {
                uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst);
                expand_bits(rgb565, bits, width, height, dstRB, srcRB);
                break;
            }
            case kA888_GrMaskFormat: {
                uint32_t* rgba8888 = reinterpret_cast<uint32_t*>(dst);
                expand_bits(rgba8888, bits, width, height, dstRB, srcRB);
                break;
            }
        }
    } else if (srcRB == dstRB) {
        memcpy(dst, src, dstRB * height);
    } else {
        const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat());
        for (int y = 0; y < height; y++) {
            memcpy(dst, src, width * bbp);
            src = (const char*)src + srcRB;
            dst = (char*)dst + dstRB;
        }
    }
    return true;
}

// we should just return const SkPath* (NULL means false)
bool SkGrFontScaler::getGlyphPath(uint16_t glyphID, SkPath* path) {

    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
    const SkPath* skPath = fStrike->findPath(glyph);
    if (skPath) {
        *path = *skPath;
        return true;
    }
    return false;
}

<commit_msg>Fix for DEPS compiler issue in SkGrFontScaler.cpp<commit_after>
/*
 * Copyright 2010 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrTemplates.h"
#include "SkGr.h"
#include "SkDescriptor.h"
#include "SkGlyphCache.h"

class SkGrDescKey : public GrKey {
public:
    explicit SkGrDescKey(const SkDescriptor& desc);
    virtual ~SkGrDescKey();

protected:
    // overrides
    virtual bool lt(const GrKey& rh) const;
    virtual bool eq(const GrKey& rh) const;

private:
    SkDescriptor* fDesc;
    enum {
        kMaxStorageInts = 16
    };
    uint32_t fStorage[kMaxStorageInts];
};

///////////////////////////////////////////////////////////////////////////////

SkGrDescKey::SkGrDescKey(const SkDescriptor& desc) : GrKey(desc.getChecksum()) {
    size_t size = desc.getLength();
    if (size <= sizeof(fStorage)) {
        fDesc = GrTCast<SkDescriptor*>(fStorage);
    } else {
        fDesc = SkDescriptor::Alloc(size);
    }
    memcpy(fDesc, &desc, size);
}

SkGrDescKey::~SkGrDescKey() {
    if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
        SkDescriptor::Free(fDesc);
    }
}

bool SkGrDescKey::lt(const GrKey& rh) const {
    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
    size_t lenLH = fDesc->getLength();
    size_t lenRH = srcDesc->getLength();
    int cmp = memcmp(fDesc, srcDesc, SkMin32(lenLH, lenRH));
    if (0 == cmp) {
        return lenLH < lenRH;
    } else {
        return cmp < 0;
    }
}

bool SkGrDescKey::eq(const GrKey& rh) const {
    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
    return fDesc->equals(*srcDesc);
}

///////////////////////////////////////////////////////////////////////////////

SkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) {
    fStrike = strike;
    fKey = NULL;
}

SkGrFontScaler::~SkGrFontScaler() {
    GrSafeUnref(fKey);
}

GrMaskFormat SkGrFontScaler::getMaskFormat() {
    SkMask::Format format = fStrike->getMaskFormat();
    switch (format) {
        case SkMask::kBW_Format:
            // fall through to kA8 -- we store BW glyphs in our 8-bit cache
        case SkMask::kA8_Format:
            return kA8_GrMaskFormat;
        case SkMask::kLCD16_Format:
            return kA565_GrMaskFormat;
        case SkMask::kLCD32_Format:
            return kA888_GrMaskFormat;
        default:
            GrAssert(!"unsupported SkMask::Format");
            return kA8_GrMaskFormat;
    }
}

const GrKey* SkGrFontScaler::getKey() {
    if (NULL == fKey) {
        fKey = SkNEW_ARGS(SkGrDescKey, (fStrike->getDescriptor()));
    }
    return fKey;
}

bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed,
                                          GrIRect* bounds) {
    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
                                              GrGlyph::UnpackFixedX(packed),
                                              GrGlyph::UnpackFixedY(packed));
    bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
    return true;

}

namespace {
// expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a BW glyph mask to
// A8, RGB565, or RGBA8888.
template <typename INT_TYPE>
void expand_bits(INT_TYPE* dst,
                 const uint8_t* src,
                 int width,
                 int height,
                 int dstRowBytes,
                 int srcRowBytes) {
    for (int i = 0; i < height; ++i) {
        int rowWritesLeft = width;
        const uint8_t* s = src;
        INT_TYPE* d = dst;
        while (rowWritesLeft > 0) {
            unsigned mask = *s++;
            for (int i = 7; i >= 0 && rowWritesLeft; --i, --rowWritesLeft) {
                *d++ = (mask & (1 << i)) ? (INT_TYPE)(~0UL) : 0;
            }
        }
        dst = reinterpret_cast<INT_TYPE*>(reinterpret_cast<intptr_t>(dst) + dstRowBytes);
        src += srcRowBytes;
    }
}
}

bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
                                         int width, int height,
                                         int dstRB, void* dst) {
    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
                                              GrGlyph::UnpackFixedX(packed),
                                              GrGlyph::UnpackFixedY(packed));
    GrAssert(glyph.fWidth == width);
    GrAssert(glyph.fHeight == height);
    const void* src = fStrike->findImage(glyph);
    if (NULL == src) {
        return false;
    }

    int srcRB = glyph.rowBytes();
    // The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to
    // check the glyph's format, not the strike's format, and to be able to convert to any of the
    // GrMaskFormats.
    if (SkMask::kBW_Format == glyph.fMaskFormat) {
        // expand bits to our mask type
        const uint8_t* bits = reinterpret_cast<const uint8_t*>(src);
        switch (this->getMaskFormat()) {
            case kA8_GrMaskFormat:{
                uint8_t* bytes = reinterpret_cast<uint8_t*>(dst);
                expand_bits(bytes, bits, width, height, dstRB, srcRB);
                break;
            }
            case kA565_GrMaskFormat: {
                uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst);
                expand_bits(rgb565, bits, width, height, dstRB, srcRB);
                break;
            }
            case kA888_GrMaskFormat: {
                uint32_t* rgba8888 = reinterpret_cast<uint32_t*>(dst);
                expand_bits(rgba8888, bits, width, height, dstRB, srcRB);
                break;
            }
   	    default:
 	        GrCrash("Unknown GrMaskFormat");
        }
    } else if (srcRB == dstRB) {
        memcpy(dst, src, dstRB * height);
    } else {
        const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat());
        for (int y = 0; y < height; y++) {
            memcpy(dst, src, width * bbp);
            src = (const char*)src + srcRB;
            dst = (char*)dst + dstRB;
        }
    }
    return true;
}

// we should just return const SkPath* (NULL means false)
bool SkGrFontScaler::getGlyphPath(uint16_t glyphID, SkPath* path) {

    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
    const SkPath* skPath = fStrike->findPath(glyph);
    if (skPath) {
        *path = *skPath;
        return true;
    }
    return false;
}

<|endoftext|>


<commit_before>//
// Blocks.cpp
// Clutter
//
// Created by PM Bult on 24-01-2016
// Copyright (c) P.M. Bult. All rights reserved.
//
// Version 1.0
//

#include <iostream>

#include "Blocks.h"

namespace Clutter {
    void HelpBlock::print( int tag_size, int label_size )
    {
        std::string format;
        format += "%%-" + std::to_string(tag_size) + "s ";
        format += "%%-" + std::to_string(label_size) + "s ";
        format += "%%-s\n";
        printf( format.c_str(), tag.c_str(), label.c_str(), help.c_str() );
    }
}
<commit_msg>Change HelpBlock print format<commit_after>//
// Blocks.cpp
// Clutter
//
// Created by PM Bult on 24-01-2016
// Copyright (c) P.M. Bult. All rights reserved.
//
// Version 1.0
//

#include <iostream>

#include "Blocks.h"

namespace Clutter {
    void HelpBlock::print( int tag_size, int label_size )
    {
        std::string format = "  ";
        format += "%%-" + std::to_string(tag_size) + "s; ";
        format += "%%-" + std::to_string(label_size) + "s | ";
        format += "%%s\n";
        printf( format.c_str(), tag.c_str(), label.c_str(), help.c_str() );
    }
}
<|endoftext|>


<commit_before>/*
 *  readit.cpp
 *
 *  Copyright (c) 2010 Motiejus Jakštys
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 3.

 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <cstdio>
#include <map>
#include <set>
#include <list>
#include <vector>
#include <string>
#include <string.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <jack/jack.h>

using namespace std;

#define SRC_WAV 0
#define SRC_JACK_ONE 1
#define SRC_JACK_AUTO 2
#define ACTION_DUMP 0
#define ACTION_CATCH 1
#define BUFFERSIZE 1

#define ACTION_FN_ARGS int w, double place, double len, unsigned long int b
#define ACTION_FN(func) void (*func)(ACTION_FN_ARGS)

void fatal(void * r) {
    char * msg = (char*) r;
    printf (msg);
    exit (1);
};
char errmsg[200];   // Temporary message

struct sVolumes {
    unsigned long head, tail;
	jack_default_audio_sample_t min, max;
    bool proc;
};

typedef struct {
    jack_default_audio_sample_t * buf;
    jack_nframes_t nframes;
} buffer;

class SoundPatty;
class Input {
    public:
        int SAMPLE_RATE, DATA_SIZE;
        virtual buffer * giveInput(buffer *) {
            fatal((void*)"This should never be called!!!");
        };
        virtual void test() {
            printf("Called Input\n");
        }
    protected:
        SoundPatty * _sp_inst;
};

class SoundPatty {
    public:
        SoundPatty(const char * fn) {
            gsCounter = 0;
            read_cfg(fn);
        };
        map<string, double> cfg;
        virtual void Error(void*);
        int setInput(int, void*);
        int go(int, ACTION_FN(callback));
        int WAVE, CHUNKSIZE;
        int gsCounter;
    private:
        Input * _input;
        int read_cfg(const char*);
        int source_app;
        char *input_params;
        vector<sVolumes> volume;
};

class WavInput : public Input {
    public:
        buffer * giveInput(buffer *buf_prop) {
            int16_t buf [SAMPLE_RATE * BUFFERSIZE]; // Process buffer every BUFFERSIZE secs
            if (feof(_fh)) {
                return NULL;
            }
            size_t read_size = fread(buf, 2, SAMPLE_RATE * BUFFERSIZE, _fh);

            // :HACK: fix this, do not depend on jack types where you don't need!
            jack_default_audio_sample_t buf2 [SAMPLE_RATE * BUFFERSIZE];
            for(int i = 0; i < read_size; i++) {
                buf2[i] = (jack_default_audio_sample_t)buf[i];
            }
            buf_prop->buf = buf2;
            buf_prop->nframes = read_size;
            return buf_prop;
        }

        WavInput(SoundPatty * inst, void * args) {
            _sp_inst = inst;
            char * filename = (char*) args;
            process_headers(filename);
        }
    protected:
        int process_headers(const char * infile) {/*{{{*/

            _fh = fopen(infile, "rb");
            if (_fh == NULL) {
                sprintf(errmsg, "Failed to open file %s, exiting\n", infile);
                fatal((void*)errmsg);
            }

            // Read bytes [0-3] and [8-11], they should be "RIFF" and "WAVE" in ASCII
            char header[5];
            fread(header, 1, 4, _fh);

            char sample[] = "RIFF";
            if (! check_sample(sample, header) ) {
                sprintf(errmsg, "RIFF header not found in %s, exiting\n", infile);
                fatal((void*)errmsg);
            }
            // Checking for compression code (21'st byte is 01, 22'nd - 00, little-endian notation
            uint16_t tmp[2]; // two-byte integer
            fseek(_fh, 0x14, 0); // offset = 20 bytes
            fread(&tmp, 2, 2, _fh); // Reading two two-byte samples (comp. code and no. of channels)
            if ( tmp[0] != 1 ) {
                sprintf(errmsg, "Only PCM(1) supported, compression code given: %d\n", tmp[0]);
                fatal ((void*)errmsg);
            }
            // Number of channels must be "MONO"
            if ( tmp[1] != 1 ) {
                sprintf(errmsg, "Only MONO supported, given number of channels: %d\n", tmp[1]);
                fatal ((void*)errmsg);
            }
            fread(&SAMPLE_RATE, 2, 1, _fh); // Single two-byte sample
            _sp_inst->WAVE = (int)SAMPLE_RATE * _sp_inst->cfg["minwavelen"];
            _sp_inst->CHUNKSIZE = _sp_inst->cfg["chunklen"] * (int)SAMPLE_RATE;
            fseek(_fh, 0x22, 0);
            uint16_t BitsPerSample;
            fread(&BitsPerSample, 1, 2, _fh);
            if (BitsPerSample != 16) {
                sprintf(errmsg, "Only 16-bit WAVs supported, given: %d\n", BitsPerSample);
                fatal((void*)errmsg);
            }
            // Get data chunk size here
            fread(header, 1, 4, _fh);
            strcpy(sample, "data");

            if (! check_sample(sample, header)) {
                fatal ((void*)"data chunk not found in byte offset=36, file corrupted.");
            }
            int DATA_SIZE;
            fread(&DATA_SIZE, 4, 1, _fh); // Single two-byte sample
            return 0;
        }

        bool check_sample (const char * sample, const char * b) { // My STRCPY.
            for(int i = 0; sample[i] != '\0'; i++) {
                if (sample[i] != b[i]) {
                    return false;
                }
            }
            return true;
        }/*}}}*/
    private:
        FILE *_fh;

};
void SoundPatty::Error(void * msg) {/*{{{*/
    char * mesg = (char*) msg;
    printf(mesg);
    exit(0);
}/*}}}*/
int SoundPatty::read_cfg (const char * filename) {/*{{{*/
    ifstream file;
    file.open(filename);
    string line;
    int x;
    while (! file.eof() ) {
        getline(file, line);
        x = line.find(":");
        if (x == -1) break; // Last line, exit
        istringstream i(line.substr(x+2));
        double tmp; i >> tmp;
        cfg[line.substr(0,x)] = tmp;
    }
    // Change cfg["treshold\d+_(min|max)"] to
    // something more compatible with sVolumes map
    sVolumes tmp;
    tmp.head = tmp.tail = tmp.max = tmp.min = tmp.proc = 0;
    volume.assign(cfg.size(), tmp); // Make a bit more then nescesarry
    int max_index = 0; // Number of different tresholds
    for(map<string, double>::iterator C = cfg.begin(); C != cfg.end(); C++) {
        // Failed to use boost::regex :(
        if (C->first.find("treshold") == 0) {
            istringstream tmp(C->first.substr(8));
            int i; tmp >> i;
            max_index = max(max_index, i);
            // C->second and volume[i].m{in,ax} are double
            if (C->first.find("_min") != -1) {
                volume[i].min = C->second;
            } else {
                volume[i].max = C->second;
            }
        }
    }
    volume.assign(volume.begin(), volume.begin()+max_index+1);
    return 0;
}/*}}}*/
int SoundPatty::setInput(const int source_app, void * input_params) {/*{{{*/
    if (0 <= source_app && source_app <= 2) {
        this->source_app = source_app;
    }
    switch(this->source_app) {
        case SRC_WAV:
            _input = new WavInput(this, input_params);
            break;
    }
    return 0;
}/*}}}*/

int SoundPatty::go(const int action, ACTION_FN(callback)) {/*{{{*/
    string which_timeout (action == ACTION_DUMP?"sampletimeout" : "catchtimeout");
    buffer buf;

    buf.buf = NULL;
    buf.nframes = 0;
    while (_input->giveInput(&buf) != NULL) { // Have pointer to data
        if (gsCounter/_input->SAMPLE_RATE > cfg[which_timeout]) {
            printf("Timeout reached: %.6f\n", gsCounter/_input->SAMPLE_RATE);
            return 0;
        }
    }
}

void dump_out(ACTION_FN_ARGS) {
    printf ("%d;%.6f;%.6f\n", w, place, len);
}

int main (int argc, char *argv[]) {
    if (argc < 3) {
        fatal ((void*)"Usage: ./readit config.cfg sample.wav\nor\n"
                "./readit config.cfg samplefile.txt catchable.wav\n"
                "./readit config.cfg samplefile.txt jack jack\n");
    }
    if (argc == 3) {
        SoundPatty * pat = new SoundPatty(argv[1]); // usually config.cfg
        pat->setInput(SRC_WAV, argv[2]);
        switch (pat->go(ACTION_DUMP, dump_out)) {
            case 0: // It's just over. Either timeout or eof reached
                exit(0);
        }
    }
    exit(0);
}
<commit_msg>Restructurization tested with WAV+dump_out<commit_after>/*
 *  readit.cpp
 *
 *  Copyright (c) 2010 Motiejus Jakštys
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 3.

 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <math.h>
#include <algorithm>
#include <stdlib.h>
#include <cstdio>
#include <map>
#include <set>
#include <list>
#include <vector>
#include <string>
#include <string.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <jack/jack.h>

using namespace std;

#define SRC_WAV 0
#define SRC_JACK_ONE 1
#define SRC_JACK_AUTO 2
#define ACTION_DUMP 0
#define ACTION_CATCH 1

#define BUFFERSIZE 1

#define ACTION_FN_ARGS int w, double place, double len, unsigned long int b
#define ACTION_FN(func) void (*func)(ACTION_FN_ARGS)

void fatal(void * r) {
    char * msg = (char*) r;
    printf (msg);
    exit (1);
};
char errmsg[200];   // Temporary message

struct sVolumes {
    unsigned long head, tail;
	jack_default_audio_sample_t min, max;
    bool proc;
};

typedef struct {
    jack_default_audio_sample_t * buf;
    jack_nframes_t nframes;
} buffer;

class SoundPatty;
class Input {
    public:
        int SAMPLE_RATE, DATA_SIZE;
        virtual buffer * giveInput(buffer *) {
            fatal((void*)"This should never be called!!!");
        };
        virtual void test() {
            printf("Called Input\n");
        }
    protected:
        SoundPatty * _sp_inst;
};

class SoundPatty {
    public:
        SoundPatty(const char * fn) {
            gSCounter = gMCounter = 0;
            read_cfg(fn);
        };
        map<string, double> cfg;
        virtual void Error(void*);
        int setInput(int, void*);
        int go(int, ACTION_FN(callback));
        int WAVE, CHUNKSIZE;
        unsigned long gMCounter, // How many matches we found
                      gSCounter; // How many samples we skipped
        void search_patterns (jack_default_audio_sample_t * buf, jack_nframes_t nframes, ACTION_FN(callback));
        vector<sVolumes> volume;
    private:
        Input * _input;
        int read_cfg(const char*);
        int source_app;
        char *input_params;
};

class WavInput : public Input {
    public:
        WavInput(SoundPatty * inst, void * args) {
            _sp_inst = inst;
            char * filename = (char*) args;
            process_headers(filename);
            // ------------------------------------------------------------
            // Adjust _sp_ volume
            // Jack has float (-1..1) while M$ WAV has (-2^15..2^15)
            //
            for (vector<sVolumes>::iterator vol = _sp_inst->volume.begin(); vol != _sp_inst->volume.end(); vol++) {
                vol->min *= (1<<15);
                vol->max *= (1<<15);
            }
        }

        buffer * giveInput(buffer *buf_prop) {
            int16_t buf [SAMPLE_RATE * BUFFERSIZE]; // Process buffer every BUFFERSIZE secs
            if (feof(_fh)) {
                return NULL;
            }
            size_t read_size = fread(buf, 2, SAMPLE_RATE * BUFFERSIZE, _fh);

            // :HACK: fix this, do not depend on jack types where you don't need!
            jack_default_audio_sample_t buf2 [SAMPLE_RATE * BUFFERSIZE];
            for(int i = 0; i < read_size; i++) {
                buf2[i] = (jack_default_audio_sample_t)buf[i];
            }
            buf_prop->buf = buf2;
            buf_prop->nframes = read_size;
            return buf_prop;
        }
    protected:
        int process_headers(const char * infile) {/*{{{*/

            _fh = fopen(infile, "rb");
            if (_fh == NULL) {
                sprintf(errmsg, "Failed to open file %s, exiting\n", infile);
                fatal((void*)errmsg);
            }

            // Read bytes [0-3] and [8-11], they should be "RIFF" and "WAVE" in ASCII
            char header[5];
            fread(header, 1, 4, _fh);

            char sample[] = "RIFF";
            if (! check_sample(sample, header) ) {
                sprintf(errmsg, "RIFF header not found in %s, exiting\n", infile);
                fatal((void*)errmsg);
            }
            // Checking for compression code (21'st byte is 01, 22'nd - 00, little-endian notation
            uint16_t tmp[2]; // two-byte integer
            fseek(_fh, 0x14, 0); // offset = 20 bytes
            fread(&tmp, 2, 2, _fh); // Reading two two-byte samples (comp. code and no. of channels)
            if ( tmp[0] != 1 ) {
                sprintf(errmsg, "Only PCM(1) supported, compression code given: %d\n", tmp[0]);
                fatal ((void*)errmsg);
            }
            // Number of channels must be "MONO"
            if ( tmp[1] != 1 ) {
                sprintf(errmsg, "Only MONO supported, given number of channels: %d\n", tmp[1]);
                fatal ((void*)errmsg);
            }
            fread(&SAMPLE_RATE, 2, 1, _fh); // Single two-byte sample
            _sp_inst->WAVE = (int)SAMPLE_RATE * _sp_inst->cfg["minwavelen"];
            _sp_inst->CHUNKSIZE = _sp_inst->cfg["chunklen"] * (int)SAMPLE_RATE;
            fseek(_fh, 0x22, 0);
            uint16_t BitsPerSample;
            fread(&BitsPerSample, 1, 2, _fh);
            if (BitsPerSample != 16) {
                sprintf(errmsg, "Only 16-bit WAVs supported, given: %d\n", BitsPerSample);
                fatal((void*)errmsg);
            }
            // Get data chunk size here
            fread(header, 1, 4, _fh);
            strcpy(sample, "data");

            if (! check_sample(sample, header)) {
                fatal ((void*)"data chunk not found in byte offset=36, file corrupted.");
            }
            int DATA_SIZE;
            fread(&DATA_SIZE, 4, 1, _fh); // Single two-byte sample
            return 0;
        }

        bool check_sample (const char * sample, const char * b) { // My STRCPY.
            for(int i = 0; sample[i] != '\0'; i++) {
                if (sample[i] != b[i]) {
                    return false;
                }
            }
            return true;
        }/*}}}*/
    private:
        FILE *_fh;

};
void SoundPatty::Error(void * msg) {/*{{{*/
    char * mesg = (char*) msg;
    printf(mesg);
    exit(0);
}/*}}}*/
int SoundPatty::read_cfg (const char * filename) {/*{{{*/
    ifstream file;
    file.open(filename);
    string line;
    int x;
    while (! file.eof() ) {
        getline(file, line);
        x = line.find(":");
        if (x == -1) break; // Last line, exit
        istringstream i(line.substr(x+2));
        double tmp; i >> tmp;
        cfg[line.substr(0,x)] = tmp;
    }
    // Change cfg["treshold\d+_(min|max)"] to
    // something more compatible with sVolumes map
    sVolumes tmp;
    tmp.head = tmp.tail = tmp.max = tmp.min = tmp.proc = 0;
    volume.assign(cfg.size(), tmp); // Make a bit more then nescesarry
    int max_index = 0; // Number of different tresholds
    for(map<string, double>::iterator C = cfg.begin(); C != cfg.end(); C++) {
        // Failed to use boost::regex :(
        if (C->first.find("treshold") == 0) {
            istringstream tmp(C->first.substr(8));
            int i; tmp >> i;
            max_index = max(max_index, i);
            // C->second and volume[i].m{in,ax} are double
            if (C->first.find("_min") != -1) {
                volume[i].min = C->second;
            } else {
                volume[i].max = C->second;
            }
        }
    }
    volume.assign(volume.begin(), volume.begin()+max_index+1);
    return 0;
}/*}}}*/
int SoundPatty::setInput(const int source_app, void * input_params) {/*{{{*/
    if (0 <= source_app && source_app <= 2) {
        this->source_app = source_app;
    }
    switch(this->source_app) {
        case SRC_WAV:
            _input = new WavInput(this, input_params);
            break;
    }
    return 0;
}/*}}}*/

int SoundPatty::go(const int action, ACTION_FN(callback)) {
    string which_timeout (action == ACTION_DUMP?"sampletimeout" : "catchtimeout");
    buffer buf;

    buf.buf = NULL;
    buf.nframes = 0;
    while (_input->giveInput(&buf) != NULL) { // Have pointer to data

        search_patterns(buf.buf, buf.nframes, callback);
        if (gSCounter/_input->SAMPLE_RATE > cfg[which_timeout]) {
            return 0;
        }
    }
}

void SoundPatty::search_patterns (jack_default_audio_sample_t * buf, jack_nframes_t nframes, ACTION_FN(callback)) {
    for (int i = 0; i < nframes; gSCounter++, i++) {
        jack_default_audio_sample_t cur = buf[i]<0?-buf[i]:buf[i];

        int v = 0; // Counter for volume
        for (vector<sVolumes>::iterator V = volume.begin(); V != volume.end(); V++, v++) {
            if (V->min <= cur && cur <= V->max) {
                // ------------------------------------------------------------
                // If it's first item in this wave (proc = processing started)
                //
                if (!V->proc) {
                    V->tail = gSCounter;
                    V->proc = true;
                }
                // ------------------------------------------------------------
                // Here we are just normally in the wave.
                //
                V->head = gSCounter;
            } else { // We are not in the wave
                if (V->proc && (V->min < 0.001 || gSCounter - V->head > WAVE)) {

                    //------------------------------------------------------------
                    // This wave is over
                    //
                    if (gSCounter - V->tail >= CHUNKSIZE) {
                        // ------------------------------------------------------------
                        // The previous chunk is big enough to be noticed
                        //
                        callback(v, (double)V->tail/_input->SAMPLE_RATE, (double)(V->head - V->tail)/_input->SAMPLE_RATE, gMCounter++);
                    }
                    // ------------------------------------------------------------
                    // Else it is too small, but we don't want to do anything in that case
                    // So therefore we just say that wave processing is over
                    //
                    V->proc = false;
                }
            }
        }
    }
}

void dump_out(ACTION_FN_ARGS) {
    printf ("%d;%.6f;%.6f\n", w, place, len);
}

int main (int argc, char *argv[]) {
    if (argc < 3) {
        fatal ((void*)"Usage: ./readit config.cfg sample.wav\nor\n"
                "./readit config.cfg samplefile.txt catchable.wav\n"
                "./readit config.cfg samplefile.txt jack jack\n");
    }
    if (argc == 3) {
        SoundPatty * pat = new SoundPatty(argv[1]); // usually config.cfg
        pat->setInput(SRC_WAV, argv[2]);
        switch (pat->go(ACTION_DUMP, dump_out)) {
            case 0: // It's just over. Either timeout or eof reached
                exit(0);
        }
    }
    exit(0);
}
<|endoftext|>


<commit_before>#include "stdafx.h"

static float CalcRadius(const Mesh* m)
{
	const Block& b = m->GetRawDatas();
	float maxSq = 0;
	for (auto& it : b.vertices) {
		float sq = XMVectorGetX(XMVector3LengthSq(XMLoadFloat3(&it.xyz)));
		maxSq = std::max(maxSq, sq);
	}
	return sqrt(maxSq);
}

App::App() : scale(1), lastX(-1), lastY(-1), sprite(nullptr), font(nullptr)
{
	quat = XMQuaternionIdentity();
	ZeroMemory(mesh, sizeof(mesh));
}

App::~App()
{
}

void App::Init(const char* fileName)
{
	Destroy();

	sprite = new SpriteBatch(deviceMan11.GetContext());
	font = new SpriteFont(deviceMan11.GetDevice(), L"resource\\font.spritefont");

	if (fileName) {
		const char* ext = strrchr(fileName, '.');
		if (ext && !_stricmp(ext, ".bvh")) {
			mesh[0] = new Bvh(fileName);
		} else {
			mesh[0] = new MeshX(fileName);
		}
	} else {
		mesh[0] = new Bvh("D:\\github\\aachan.bvh");
		mesh[1] = new Bvh("D:\\github\\kashiyuka.bvh");
		mesh[2] = new Bvh("D:\\github\\nocchi.bvh");
	}

	float radius = CalcRadius(mesh[0]);
	scale = 1 / std::max(0.00001f, radius);

	matrixMan.Set(MatrixMan::PROJ, XMMatrixPerspectiveFovLH(45 * XM_PI / 180, (float)SCR_W / SCR_H, 0.1f, 1000.0f));
}

void App::MouseWheel(float delta)
{
	if (delta > 0) {
		scale *= 1.1f;
	}
	if (delta < 0) {
		scale /= 1.1f;
	}
}

void App::LButtonDown(float x, float y)
{
	lastX = x;
	lastY = y;
}

void App::LButtonUp(float x, float y)
{
	MouseMove(x, y);
	lastX = lastY = -1;
}

void App::MouseMove(float x, float y)
{
	if (lastX < 0 || lastY < 0) {
		return;
	}
	float dx = x - lastX;
	float dy = - (y - lastY);

	lastX = x;
	lastY = y;

	XMVECTOR axis = XMVectorSet(-dy, dx, 0, 0);
	float len = XMVectorGetX(XMVector2Length(axis));
	if (!len) {
		return;
	}

	XMVECTOR q = XMQuaternionRotationAxis(axis, len * -2 * XM_PI);
	quat = XMQuaternionMultiply(quat, q);
}

inline XMFLOAT2 GetScreenPos(const XMMATRIX& mLocal)
{
	XMFLOAT4X4 mViewport;
	XMMATRIX mW, mV, mP;
	matrixMan.Get(MatrixMan::WORLD, mW);
	matrixMan.Get(MatrixMan::VIEW, mV);
	matrixMan.Get(MatrixMan::PROJ, mP);
	XMStoreFloat4x4(&mViewport, XMMatrixIdentity());
	mViewport._11 = SCR_W / 2;
	mViewport._22 = -SCR_H / 2;
	mViewport._41 = SCR_W / 2;
	mViewport._42 = SCR_H / 2;

	XMMATRIX m = mLocal * mW * mV * mP * XMLoadFloat4x4(&mViewport);

	XMFLOAT2 p;
	p.x = XMVectorGetX(m.r[3]) / XMVectorGetW(m.r[3]);
	p.y = XMVectorGetY(m.r[3]) / XMVectorGetW(m.r[3]);
	return p;
}

void App::DrawBoneNames(Bvh* bvh)
{
	const std::vector<BvhFrame>& frames = bvh->GetFrames();
	for (auto& it : frames) {
		XMFLOAT2 pos = GetScreenPos(XMLoadFloat4x4(&it.result));

		WCHAR wname[MAX_PATH];
		MultiByteToWideChar(CP_ACP, 0, it.name, -1, wname, dimof(wname));
		font->DrawString(sprite, wname, pos);
	}
}

void App::Draw()
{
	LARGE_INTEGER t, f;
	QueryPerformanceCounter(&t);
	QueryPerformanceFrequency(&f);
	float time = (float)((double)t.QuadPart / f.QuadPart);

//	XMMATRIX mRot = XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMVectorSet(1, 0, 0, 0), time / 2 * XM_PI));
	XMMATRIX mRot = XMMatrixRotationQuaternion(quat);
	XMMATRIX mScale = XMMatrixScaling(scale, scale, scale);

	matrixMan.Set(MatrixMan::WORLD, mScale * mRot);

	float dist = 3;
//	float rot = time / 5 * XM_PI;
	float rot = XM_PI;
	matrixMan.Set(MatrixMan::VIEW, XMMatrixLookAtLH(XMVectorSet(sin(rot) * dist, 0, cos(rot) * dist, 1), XMVectorSet(0, 0, 0, 0), XMVectorSet(0, 1, 0, 0)));

    sprite->Begin();

	for (auto& it : mesh) {
		if (it) {
			it->Draw(0, time);

			Bvh* bvh = dynamic_cast<Bvh*>(it);
			if (bvh) {
				DrawBoneNames(bvh);
			}
		}
	}

	sprite->End();
}

void App::Destroy()
{
	SAFE_DELETE(mesh[0]);
	SAFE_DELETE(mesh[1]);
	SAFE_DELETE(mesh[2]);
	SAFE_DELETE(font);
	SAFE_DELETE(sprite);
}
<commit_msg>centering<commit_after>#include "stdafx.h"

static float CalcRadius(const Mesh* m)
{
	const Block& b = m->GetRawDatas();
	float maxSq = 0;
	for (auto& it : b.vertices) {
		float sq = XMVectorGetX(XMVector3LengthSq(XMLoadFloat3(&it.xyz)));
		maxSq = std::max(maxSq, sq);
	}
	return sqrt(maxSq);
}

App::App() : scale(1), lastX(-1), lastY(-1), sprite(nullptr), font(nullptr)
{
	quat = XMQuaternionIdentity();
	ZeroMemory(mesh, sizeof(mesh));
}

App::~App()
{
}

void App::Init(const char* fileName)
{
	Destroy();

	sprite = new SpriteBatch(deviceMan11.GetContext());
	font = new SpriteFont(deviceMan11.GetDevice(), L"resource\\font.spritefont");

	if (fileName) {
		const char* ext = strrchr(fileName, '.');
		if (ext && !_stricmp(ext, ".bvh")) {
			mesh[0] = new Bvh(fileName);
		} else {
			mesh[0] = new MeshX(fileName);
		}
	} else {
		mesh[0] = new Bvh("D:\\github\\aachan.bvh");
		mesh[1] = new Bvh("D:\\github\\kashiyuka.bvh");
		mesh[2] = new Bvh("D:\\github\\nocchi.bvh");
	}

	float radius = CalcRadius(mesh[0]);
	scale = 1 / std::max(0.00001f, radius);

	matrixMan.Set(MatrixMan::PROJ, XMMatrixPerspectiveFovLH(45 * XM_PI / 180, (float)SCR_W / SCR_H, 0.1f, 1000.0f));
}

void App::MouseWheel(float delta)
{
	if (delta > 0) {
		scale *= 1.1f;
	}
	if (delta < 0) {
		scale /= 1.1f;
	}
}

void App::LButtonDown(float x, float y)
{
	lastX = x;
	lastY = y;
}

void App::LButtonUp(float x, float y)
{
	MouseMove(x, y);
	lastX = lastY = -1;
}

void App::MouseMove(float x, float y)
{
	if (lastX < 0 || lastY < 0) {
		return;
	}
	float dx = x - lastX;
	float dy = - (y - lastY);

	lastX = x;
	lastY = y;

	XMVECTOR axis = XMVectorSet(-dy, dx, 0, 0);
	float len = XMVectorGetX(XMVector2Length(axis));
	if (!len) {
		return;
	}

	XMVECTOR q = XMQuaternionRotationAxis(axis, len * -2 * XM_PI);
	quat = XMQuaternionMultiply(quat, q);
}

inline XMFLOAT2 GetScreenPos(const XMMATRIX& mLocal)
{
	XMFLOAT4X4 mViewport;
	XMMATRIX mW, mV, mP;
	matrixMan.Get(MatrixMan::WORLD, mW);
	matrixMan.Get(MatrixMan::VIEW, mV);
	matrixMan.Get(MatrixMan::PROJ, mP);
	XMStoreFloat4x4(&mViewport, XMMatrixIdentity());
	mViewport._11 = SCR_W / 2;
	mViewport._22 = -SCR_H / 2;
	mViewport._41 = SCR_W / 2;
	mViewport._42 = SCR_H / 2;

	XMMATRIX m = mLocal * mW * mV * mP * XMLoadFloat4x4(&mViewport);

	XMFLOAT2 p;
	p.x = XMVectorGetX(m.r[3]) / XMVectorGetW(m.r[3]);
	p.y = XMVectorGetY(m.r[3]) / XMVectorGetW(m.r[3]);
	return p;
}

void App::DrawBoneNames(Bvh* bvh)
{
	const std::vector<BvhFrame>& frames = bvh->GetFrames();
	for (auto& it : frames) {
		if (it.childId < 0) {
			continue;
		}
		XMFLOAT2 pos = GetScreenPos(XMLoadFloat4x4(&it.result));

		WCHAR wname[MAX_PATH];
		MultiByteToWideChar(CP_ACP, 0, it.name, -1, wname, dimof(wname));

		XMVECTOR size = font->MeasureString(wname);
		pos.x -= XMVectorGetX(size) / 2;
		pos.y -= XMVectorGetY(size) / 2;
		font->DrawString(sprite, wname, pos);
	}
}

void App::Draw()
{
	LARGE_INTEGER t, f;
	QueryPerformanceCounter(&t);
	QueryPerformanceFrequency(&f);
	float time = (float)((double)t.QuadPart / f.QuadPart);

//	XMMATRIX mRot = XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMVectorSet(1, 0, 0, 0), time / 2 * XM_PI));
	XMMATRIX mRot = XMMatrixRotationQuaternion(quat);
	XMMATRIX mScale = XMMatrixScaling(scale, scale, scale);

	matrixMan.Set(MatrixMan::WORLD, mScale * mRot);

	float dist = 3;
//	float rot = time / 5 * XM_PI;
	float rot = XM_PI;
	matrixMan.Set(MatrixMan::VIEW, XMMatrixLookAtLH(XMVectorSet(sin(rot) * dist, 0, cos(rot) * dist, 1), XMVectorSet(0, 0, 0, 0), XMVectorSet(0, 1, 0, 0)));

    sprite->Begin();

	for (auto& it : mesh) {
		if (it) {
			it->Draw(0, time);

			Bvh* bvh = dynamic_cast<Bvh*>(it);
			if (bvh) {
				DrawBoneNames(bvh);
			}
		}
	}

	sprite->End();
}

void App::Destroy()
{
	SAFE_DELETE(mesh[0]);
	SAFE_DELETE(mesh[1]);
	SAFE_DELETE(mesh[2]);
	SAFE_DELETE(font);
	SAFE_DELETE(sprite);
}
<|endoftext|>


<commit_before>#include "stdafx.h"

#ifndef _MSC_VER
static int GetKeyState(char) {
	return 0x01;
}
#define VK_RETURN 0x0D
#endif

static float CalcRadius(const Mesh* m)
{
	const Block& b = m->GetRawDatas();
	float maxSq = 0;
	for (auto& it : b.vertices) {
		float sq = lengthSq(it.xyz);
		maxSq = std::max(maxSq, sq);
	}
	return sqrt(maxSq);
}

App::App() : radius(1), animationNumber(0), trackTime(0), meshTiny(nullptr)
{
	memset(mesh, 0, sizeof(mesh));
	lastTime = GetTime();
}

App::~App()
{
}

void App::ApplySky()
{
	switch(skyNum) {
	case 0:
		//skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\C++\\Direct3D\\StateManager\\Media\\skybox02.dds", "sky_cubemap_high");
		skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\Media\\Lobby\\LobbyCube.dds", "sky_cubemap");
		break;
	case 1:
		skyMan.Create("resource\\OutputCube2.dds", "projection_equirectangular");
		//skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\C++\\Direct3D\\StateManager\\Media\\skybox02.dds", "projection_equirectangular");
		break;
	case 2:
		skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\C++\\Direct3D\\StateManager\\Media\\skybox02.dds", "projection_little_planet");
		break;
	case 3:
		skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\Media\\trees\\tree35S.dds", "sky_spheremap");
		//skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\Media\\SubD10\\msd_MicrosoftCharacterMaya100_heroChr_mechanicalCM_tga_001.dds", "sky_spheremap");
		//skyMan.Create("resource\\sphere_map.dds", "sky_spheremap");
		break;
	case 4:
		skyMan.Create("resource\\PANO_20141115_141959.dds", "sky_photosphere");
		break;
	case 5:
		skyMan.Create("resource\\Equirectangular-projection.jpg", "sky_photosphere");
		break;
	case 6:
		skyMan.Create("resource\\warcraft.dds", "sky_photosphere");
		break;
	case 7:
		skyMan.Create("resource\\PANO_20141115_141959.dds", "projection_equirectangular_to_stereographic");
		break;
	}
}

void App::Init(const char* fileName)
{
	Destroy();

	for (int i = 0; i < (int)dimof(rt); i++) {
//		rt[i].Init(ivec2(SCR_W, SCR_H), i == 2 ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R8G8B8A8_UNORM);
		rt[i].Init(ivec2(SCR_W, SCR_H), DXGI_FORMAT_R8G8B8A8_UNORM);
	}

	fontMan.Init();
	debugRenderer.Init();
	gridRenderer.Init();
	waterSurface.Init();
	postEffectCopy.Create("post_effect_copy");
	postEffectMono.Create("post_effect_mono");
	postEffectUAVTest.Create("post_effect_uav_test");
	computeShaderMan.Create("fx\\post_effect_cs.fx");
	computeShaderSkinning.Create("fx\\skin_cs.fx");

	g_type = "mesh";

	const char* meshFileName = "resource\\tiny.x";
	const char* ext = fileName ? strrchr(fileName, '.') : nullptr;
	if (ext && !_stricmp(ext, ".x")) {
		meshFileName = fileName;
	}
#if 1
	meshTiny = new MeshX(meshFileName);

	if (ext && !_stricmp(ext, ".bvh")) {
		Bvh* bvh = new Bvh(fileName);
		mesh[0] = bvh;
		bvh->ResetAnim();
		meshTiny->SyncLocalAxisWithBvh(bvh, bind[0]);
	} else {
		const char* bvhNames[] = {
			"D:\\github\\aachan.bvh",
			"D:\\github\\kashiyuka.bvh",
			"D:\\github\\nocchi.bvh",
		};
		for (int i = 0; i < (int)dimof(bvhNames); i++) {
			Bvh* bvh = new Bvh(bvhNames[i]);
			mesh[i] = bvh;
			bvh->ResetAnim();
			meshTiny->SyncLocalAxisWithBvh(bvh, bind[i]);
		}
	}

	if (mesh[0]) {
		radius = CalcRadius(mesh[0]);
	}
#endif
	float scale = std::max(0.00001f, radius);
	devCamera.SetDistance(scale * 3);
	devCamera.SetHeight(radius / 2);

	lastTime = GetTime();
	ApplySky();
}

inline Vec2 GetScreenPos(const Mat& mLocal)
{
	Mat mV, mP, mViewport;
	matrixMan.Get(MatrixMan::VIEW, mV);
	matrixMan.Get(MatrixMan::PROJ, mP);
	mViewport._11 = SCR_W / 2;
	mViewport._22 = -SCR_H / 2;
	mViewport._41 = SCR_W / 2;
	mViewport._42 = SCR_H / 2;

	Mat m = mLocal * mV * mP * mViewport;

	Vec2 p;
	p.x = m._41 / m._44;
	p.y = m._42 / m._44;
	return p;
}

void App::DrawBoneNames(Bvh* bvh)
{
	const std::vector<BvhFrame>& frames = bvh->GetFrames();
	for (auto& it : frames) {
		if (it.childId < 0) {
			continue;
		}
		Vec2 size = fontMan.MeasureString(12, it.name);
		Vec2 pos = GetScreenPos(it.result);
		pos -= size / 2;
		fontMan.DrawString(floor(pos), 12, it.name);
	}
}

void App::DrawBoneNames(const MeshX* meshX, const MeshXAnimResult& result)
{
	const std::vector<Frame>& frames = meshX->GetFrames();
	for (BONE_ID id = 0; id < (BONE_ID)frames.size(); id++) {
		const Frame& f = frames[id];
		Vec2 pos = floor(GetScreenPos(result.boneMat[id]));
		fontMan.DrawString(pos, 12, f.name[0] == '\0' ? "[NO NAME]" : f.name);
	}
}

void App::DrawCameraParams()
{
	Mat v;
	matrixMan.Get(MatrixMan::VIEW, v);
	Mat mInv = inv(v);

	char buf[128];
	Vec2 pos = { 5, 105 };
	auto draw = [&]() {
		fontMan.DrawString(pos, 20, buf);
		pos.y += 22;
	};

//	snprintf(buf, sizeof(buf), "cam pos(via inv view):%f, %f, %f dir:%f, %f, %f", mInv._41, mInv._42, mInv._43, mInv._31, mInv._32, mInv._33);
//	draw();

//	mInv = fastInv(v);
//	snprintf(buf, sizeof(buf), "cam pos(by fastInv):%f, %f, %f dir:%f, %f, %f", mInv._41, mInv._42, mInv._43, mInv._31, mInv._32, mInv._33);
//	draw();

//	snprintf(buf, sizeof(buf), "cam dir(view mtx direct): %f, %f, %f", v._13, v._23, v._33);
//	draw();

	snprintf(buf, sizeof(buf), "cam dir: %f, %f, %f", v._13, v._23, v._33);
	draw();

	float longitude = atan2(v._13, v._33) * (180.0f / 3.14159265f);
	float latitude = asin(v._23) * (180.0f / 3.14159265f);
	snprintf(buf, sizeof(buf), "longitude: %f, latitude: %f", longitude, latitude);
	draw();
}

void App::Update()
{
	if (GetKeyState(VK_F1) & 0x80) {
		skyNum = 0;
		ApplySky();
	}
	if (GetKeyState(VK_F2) & 0x80) {
		skyNum = 1;
		ApplySky();
	}
	if (GetKeyState(VK_F3) & 0x80) {
		skyNum = 2;
		ApplySky();
	}
	if (GetKeyState(VK_F4) & 0x80) {
		skyNum = 3;
		ApplySky();
	}
	if (GetKeyState(VK_F5) & 0x80) {
		skyNum = 4;
		ApplySky();
	}
	if (GetKeyState(VK_F6) & 0x80) {
		skyNum = 5;
		ApplySky();
	}
	if (GetKeyState(VK_F7) & 0x80) {
		skyNum = 6;
		ApplySky();
	}
	if (GetKeyState(VK_F8) & 0x80) {
		skyNum = 7;
		ApplySky();
	}

	if (GetKeyState('P') & 0x80) {
		g_type = "pivot";
	}
	if (GetKeyState('M') & 0x80) {
		g_type = "mesh";
	}
	if (GetKeyState('B') & 0x80) {
		g_type = "bone";
	}
	static char v[] = "012349";
	for (auto& i : v) {
		if (i && GetKeyState(i) & 0x80) {
			animationNumber = i - '0';
		}
	}
}

void App::Draw()
{
//	fontMan.DrawString(Vec2(0, 110), 16, "TEXT SPRITE TEST!!!!!!!!!!!!!text sprite 1234567890");
//	fontMan.DrawString(Vec2(10, 130), 32, "@#$%^&*()");
//	fontMan.DrawString(Vec2(10, 170), 40, L"あいうえお한글漢字");

	// render to rt[0]
	rt[0].BeginRenderToThis();

	ID3D11DeviceContext* context = deviceMan11.GetContext();

	double currentTime = GetTime();
	double deltaTime = currentTime - lastTime;
	lastTime = currentTime;

	if (GetKeyState(VK_RETURN) & 0x01) {
		trackTime += deltaTime;
	}

	matrixMan.Set(MatrixMan::VIEW, devCamera.GetViewMatrix());
	matrixMan.Set(MatrixMan::PROJ, devCamera.GetProjMatrix());

	gridRenderer.Draw();
	waterSurface.Draw();

	for (int i = 0; i < (int)dimof(mesh); i++) {
		Mesh* it = mesh[i];
		MeshX* meshX = meshTiny;
		MeshXAnimResult meshXAnimResult;
		if (it && meshX) {

			Bvh* bvh = dynamic_cast<Bvh*>(it);

			if (bvh) {
				bvh->Draw(animationNumber == 9 ? 0 : animationNumber, trackTime);
				if (animationNumber == 9) {
					meshX->CalcAnimationFromBvh(bvh, bind[i], trackTime, meshXAnimResult, 270 / radius);
				} else {
					meshX->CalcAnimation(animationNumber, trackTime, meshXAnimResult);
				}
				meshX->Draw(meshXAnimResult);
				if (GetKeyState('T') & 0x01) {
					DrawBoneNames(bvh);
				}
			}
		}
		if (meshX && (GetKeyState('T') & 0x01)) {
			DrawBoneNames(meshX, meshXAnimResult);
		}
	}

	if (GetKeyState('T') & 0x01) {
		DrawCameraParams();
		char buf[20];
		sprintf(buf, "FPS: %f", fps.Get());
		Vec2 pos = { 5, 15 };
		fontMan.DrawString(pos, 16, buf);
	}

	skyMan.Draw();

	fontMan.Render();

	// 0 => 1
	deviceMan11.GetContext()->OMSetRenderTargets(0, nullptr, nullptr);	// unbind RT to prevent warnings in debug layer
	computeShaderMan.Draw(rt[0].GetTexture(), rt[1].GetUnorderedAccessView());

	AFRenderTarget defaultTarget;
	defaultTarget.InitForDefaultRenderTarget();

	if (GetKeyState('U') & 0x01) {
		// 1 => 2
		ID3D11UnorderedAccessView* view = rt[2].GetUnorderedAccessView();
		deviceMan11.GetContext()->OMSetRenderTargetsAndUnorderedAccessViews(0, nullptr, nullptr, 1, 1, &view, nullptr);
		postEffectUAVTest.Draw(rt[1].GetTexture());

		// 2 => front
		defaultTarget.BeginRenderToThis();
		postEffectMono.Draw(rt[2].GetTexture());
	} else {
		// 1 => 0
		rt[0].BeginRenderToThis();
		postEffectCopy.Draw(rt[1].GetTexture());

		// 0 => front
		defaultTarget.BeginRenderToThis();
		postEffectMono.Draw(rt[0].GetTexture());
	}

	ID3D11ShaderResourceView* dummy = nullptr;
	deviceMan11.GetContext()->PSSetShaderResources(0, 1, &dummy);

	deviceMan11.Present();
	fps.Update();
}

void App::Destroy()
{
	for (auto& it : mesh) {
		SAFE_DELETE(it);
	}
	SAFE_DELETE(meshTiny);
	for (auto& it : rt) {
		it.Destroy();
	}

	fontMan.Destroy();
	debugRenderer.Destroy();
	gridRenderer.Destroy();
	waterSurface.Destroy();
	postEffectMono.Destroy();
	postEffectCopy.Destroy();
	postEffectUAVTest.Destroy();
	computeShaderMan.Destroy();
	computeShaderSkinning.Destroy();
	matMan.Destroy();
}

std::string g_type;
<commit_msg>Font rendering should be performed after post processes<commit_after>#include "stdafx.h"

#ifndef _MSC_VER
static int GetKeyState(char) {
	return 0x01;
}
#define VK_RETURN 0x0D
#endif

static float CalcRadius(const Mesh* m)
{
	const Block& b = m->GetRawDatas();
	float maxSq = 0;
	for (auto& it : b.vertices) {
		float sq = lengthSq(it.xyz);
		maxSq = std::max(maxSq, sq);
	}
	return sqrt(maxSq);
}

App::App() : radius(1), animationNumber(0), trackTime(0), meshTiny(nullptr)
{
	memset(mesh, 0, sizeof(mesh));
	lastTime = GetTime();
}

App::~App()
{
}

void App::ApplySky()
{
	switch(skyNum) {
	case 0:
		//skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\C++\\Direct3D\\StateManager\\Media\\skybox02.dds", "sky_cubemap_high");
		skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\Media\\Lobby\\LobbyCube.dds", "sky_cubemap");
		break;
	case 1:
		skyMan.Create("resource\\OutputCube2.dds", "projection_equirectangular");
		//skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\C++\\Direct3D\\StateManager\\Media\\skybox02.dds", "projection_equirectangular");
		break;
	case 2:
		skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\C++\\Direct3D\\StateManager\\Media\\skybox02.dds", "projection_little_planet");
		break;
	case 3:
		skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\Media\\trees\\tree35S.dds", "sky_spheremap");
		//skyMan.Create("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\Media\\SubD10\\msd_MicrosoftCharacterMaya100_heroChr_mechanicalCM_tga_001.dds", "sky_spheremap");
		//skyMan.Create("resource\\sphere_map.dds", "sky_spheremap");
		break;
	case 4:
		skyMan.Create("resource\\PANO_20141115_141959.dds", "sky_photosphere");
		break;
	case 5:
		skyMan.Create("resource\\Equirectangular-projection.jpg", "sky_photosphere");
		break;
	case 6:
		skyMan.Create("resource\\warcraft.dds", "sky_photosphere");
		break;
	case 7:
		skyMan.Create("resource\\PANO_20141115_141959.dds", "projection_equirectangular_to_stereographic");
		break;
	}
}

void App::Init(const char* fileName)
{
	Destroy();

	for (int i = 0; i < (int)dimof(rt); i++) {
//		rt[i].Init(ivec2(SCR_W, SCR_H), i == 2 ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R8G8B8A8_UNORM);
		rt[i].Init(ivec2(SCR_W, SCR_H), DXGI_FORMAT_R8G8B8A8_UNORM);
	}

	fontMan.Init();
	debugRenderer.Init();
	gridRenderer.Init();
	waterSurface.Init();
	postEffectCopy.Create("post_effect_copy");
	postEffectMono.Create("post_effect_mono");
	postEffectUAVTest.Create("post_effect_uav_test");
	computeShaderMan.Create("fx\\post_effect_cs.fx");
	computeShaderSkinning.Create("fx\\skin_cs.fx");

	g_type = "mesh";

	const char* meshFileName = "resource\\tiny.x";
	const char* ext = fileName ? strrchr(fileName, '.') : nullptr;
	if (ext && !_stricmp(ext, ".x")) {
		meshFileName = fileName;
	}
#if 1
	meshTiny = new MeshX(meshFileName);

	if (ext && !_stricmp(ext, ".bvh")) {
		Bvh* bvh = new Bvh(fileName);
		mesh[0] = bvh;
		bvh->ResetAnim();
		meshTiny->SyncLocalAxisWithBvh(bvh, bind[0]);
	} else {
		const char* bvhNames[] = {
			"D:\\github\\aachan.bvh",
			"D:\\github\\kashiyuka.bvh",
			"D:\\github\\nocchi.bvh",
		};
		for (int i = 0; i < (int)dimof(bvhNames); i++) {
			Bvh* bvh = new Bvh(bvhNames[i]);
			mesh[i] = bvh;
			bvh->ResetAnim();
			meshTiny->SyncLocalAxisWithBvh(bvh, bind[i]);
		}
	}

	if (mesh[0]) {
		radius = CalcRadius(mesh[0]);
	}
#endif
	float scale = std::max(0.00001f, radius);
	devCamera.SetDistance(scale * 3);
	devCamera.SetHeight(radius / 2);

	lastTime = GetTime();
	ApplySky();
}

inline Vec2 GetScreenPos(const Mat& mLocal)
{
	Mat mV, mP, mViewport;
	matrixMan.Get(MatrixMan::VIEW, mV);
	matrixMan.Get(MatrixMan::PROJ, mP);
	mViewport._11 = SCR_W / 2;
	mViewport._22 = -SCR_H / 2;
	mViewport._41 = SCR_W / 2;
	mViewport._42 = SCR_H / 2;

	Mat m = mLocal * mV * mP * mViewport;

	Vec2 p;
	p.x = m._41 / m._44;
	p.y = m._42 / m._44;
	return p;
}

void App::DrawBoneNames(Bvh* bvh)
{
	const std::vector<BvhFrame>& frames = bvh->GetFrames();
	for (auto& it : frames) {
		if (it.childId < 0) {
			continue;
		}
		Vec2 size = fontMan.MeasureString(12, it.name);
		Vec2 pos = GetScreenPos(it.result);
		pos -= size / 2;
		fontMan.DrawString(floor(pos), 12, it.name);
	}
}

void App::DrawBoneNames(const MeshX* meshX, const MeshXAnimResult& result)
{
	const std::vector<Frame>& frames = meshX->GetFrames();
	for (BONE_ID id = 0; id < (BONE_ID)frames.size(); id++) {
		const Frame& f = frames[id];
		Vec2 pos = floor(GetScreenPos(result.boneMat[id]));
		fontMan.DrawString(pos, 12, f.name[0] == '\0' ? "[NO NAME]" : f.name);
	}
}

void App::DrawCameraParams()
{
	Mat v;
	matrixMan.Get(MatrixMan::VIEW, v);
	Mat mInv = inv(v);

	char buf[128];
	Vec2 pos = { 5, 105 };
	auto draw = [&]() {
		fontMan.DrawString(pos, 20, buf);
		pos.y += 22;
	};

//	snprintf(buf, sizeof(buf), "cam pos(via inv view):%f, %f, %f dir:%f, %f, %f", mInv._41, mInv._42, mInv._43, mInv._31, mInv._32, mInv._33);
//	draw();

//	mInv = fastInv(v);
//	snprintf(buf, sizeof(buf), "cam pos(by fastInv):%f, %f, %f dir:%f, %f, %f", mInv._41, mInv._42, mInv._43, mInv._31, mInv._32, mInv._33);
//	draw();

//	snprintf(buf, sizeof(buf), "cam dir(view mtx direct): %f, %f, %f", v._13, v._23, v._33);
//	draw();

	snprintf(buf, sizeof(buf), "cam dir: %f, %f, %f", v._13, v._23, v._33);
	draw();

	float longitude = atan2(v._13, v._33) * (180.0f / 3.14159265f);
	float latitude = asin(v._23) * (180.0f / 3.14159265f);
	snprintf(buf, sizeof(buf), "longitude: %f, latitude: %f", longitude, latitude);
	draw();
}

void App::Update()
{
	if (GetKeyState(VK_F1) & 0x80) {
		skyNum = 0;
		ApplySky();
	}
	if (GetKeyState(VK_F2) & 0x80) {
		skyNum = 1;
		ApplySky();
	}
	if (GetKeyState(VK_F3) & 0x80) {
		skyNum = 2;
		ApplySky();
	}
	if (GetKeyState(VK_F4) & 0x80) {
		skyNum = 3;
		ApplySky();
	}
	if (GetKeyState(VK_F5) & 0x80) {
		skyNum = 4;
		ApplySky();
	}
	if (GetKeyState(VK_F6) & 0x80) {
		skyNum = 5;
		ApplySky();
	}
	if (GetKeyState(VK_F7) & 0x80) {
		skyNum = 6;
		ApplySky();
	}
	if (GetKeyState(VK_F8) & 0x80) {
		skyNum = 7;
		ApplySky();
	}

	if (GetKeyState('P') & 0x80) {
		g_type = "pivot";
	}
	if (GetKeyState('M') & 0x80) {
		g_type = "mesh";
	}
	if (GetKeyState('B') & 0x80) {
		g_type = "bone";
	}
	static char v[] = "012349";
	for (auto& i : v) {
		if (i && GetKeyState(i) & 0x80) {
			animationNumber = i - '0';
		}
	}
}

void App::Draw()
{
//	fontMan.DrawString(Vec2(0, 110), 16, "TEXT SPRITE TEST!!!!!!!!!!!!!text sprite 1234567890");
//	fontMan.DrawString(Vec2(10, 130), 32, "@#$%^&*()");
//	fontMan.DrawString(Vec2(10, 170), 40, L"あいうえお한글漢字");

	// render to rt[0]
	rt[0].BeginRenderToThis();

	ID3D11DeviceContext* context = deviceMan11.GetContext();

	double currentTime = GetTime();
	double deltaTime = currentTime - lastTime;
	lastTime = currentTime;

	if (GetKeyState(VK_RETURN) & 0x01) {
		trackTime += deltaTime;
	}

	matrixMan.Set(MatrixMan::VIEW, devCamera.GetViewMatrix());
	matrixMan.Set(MatrixMan::PROJ, devCamera.GetProjMatrix());

	gridRenderer.Draw();
	waterSurface.Draw();

	for (int i = 0; i < (int)dimof(mesh); i++) {
		Mesh* it = mesh[i];
		MeshX* meshX = meshTiny;
		MeshXAnimResult meshXAnimResult;
		if (it && meshX) {

			Bvh* bvh = dynamic_cast<Bvh*>(it);

			if (bvh) {
				bvh->Draw(animationNumber == 9 ? 0 : animationNumber, trackTime);
				if (animationNumber == 9) {
					meshX->CalcAnimationFromBvh(bvh, bind[i], trackTime, meshXAnimResult, 270 / radius);
				} else {
					meshX->CalcAnimation(animationNumber, trackTime, meshXAnimResult);
				}
				meshX->Draw(meshXAnimResult);
				if (GetKeyState('T') & 0x01) {
					DrawBoneNames(bvh);
				}
			}
		}
		if (meshX && (GetKeyState('T') & 0x01)) {
			DrawBoneNames(meshX, meshXAnimResult);
		}
	}

	if (GetKeyState('T') & 0x01) {
		DrawCameraParams();
		char buf[20];
		sprintf(buf, "FPS: %f", fps.Get());
		Vec2 pos = { 5, 15 };
		fontMan.DrawString(pos, 16, buf);
	}

	skyMan.Draw();

	// 0 => 1
	deviceMan11.GetContext()->OMSetRenderTargets(0, nullptr, nullptr);	// unbind RT to prevent warnings in debug layer
	computeShaderMan.Draw(rt[0].GetTexture(), rt[1].GetUnorderedAccessView());

	AFRenderTarget defaultTarget;
	defaultTarget.InitForDefaultRenderTarget();

	if (GetKeyState('U') & 0x01) {
		// 1 => 2
		ID3D11UnorderedAccessView* view = rt[2].GetUnorderedAccessView();
		deviceMan11.GetContext()->OMSetRenderTargetsAndUnorderedAccessViews(0, nullptr, nullptr, 1, 1, &view, nullptr);
		postEffectUAVTest.Draw(rt[1].GetTexture());

		// 2 => front
		defaultTarget.BeginRenderToThis();
		postEffectMono.Draw(rt[2].GetTexture());
	} else {
		// 1 => 0
		rt[0].BeginRenderToThis();
		postEffectCopy.Draw(rt[1].GetTexture());

		// 0 => front
		defaultTarget.BeginRenderToThis();
		postEffectMono.Draw(rt[0].GetTexture());
	}

	ID3D11ShaderResourceView* dummy = nullptr;
	deviceMan11.GetContext()->PSSetShaderResources(0, 1, &dummy);

	fontMan.Render();
	deviceMan11.Present();
	fps.Update();
}

void App::Destroy()
{
	for (auto& it : mesh) {
		SAFE_DELETE(it);
	}
	SAFE_DELETE(meshTiny);
	for (auto& it : rt) {
		it.Destroy();
	}

	fontMan.Destroy();
	debugRenderer.Destroy();
	gridRenderer.Destroy();
	waterSurface.Destroy();
	postEffectMono.Destroy();
	postEffectCopy.Destroy();
	postEffectUAVTest.Destroy();
	computeShaderMan.Destroy();
	computeShaderSkinning.Destroy();
	matMan.Destroy();
}

std::string g_type;
<|endoftext|>


<commit_before>#include <UtH\Renderer\Texture.hpp>
#include <UtH\Platform\Graphics.hpp>
#include <UtH\Resources\ResourceManager.h>
#include <cstdlib>

namespace uth
{
    Texture::Texture()
        : m_textureID(0),
          m_size(),
          m_smooth(false),
          m_repeated(false)
    {

    }

    Texture::~Texture()
    {

    }

    bool Texture::loadFromFile(const char* path, const bool smooth, const bool repeated)
    {
        uthRS.loadTGA(path);

        m_size.w = uthRS.header.width;
        m_size.h = uthRS.header.height;

        uthGraphics.setPixelStore(UNPACK_ALIGNMENT, 1);
        uthGraphics.generateTextures(1, &m_textureID);
        uthGraphics.setActiveTexUnit(TEXTURE_0);

        bind();

		//setSmooth(smooth);
  //      setRepeated(repeated);

        uthGraphics.setTextureImage2D(TEXTURE_2D, 0, RGBA_FORMAT, m_size.w, m_size.h, RGBA_FORMAT, UNSIGNED_BYTE_TYPE, uthRS.header.pixels);

		setSmooth(smooth);
        setRepeated(repeated);

		return true;
    }

    void Texture::bind()
    {
        uthGraphics.setActiveTexUnit(TEXTURE_0);
        uthGraphics.bindTexture(TEXTURE_2D, m_textureID);
    }

    const unsigned int Texture::getTextureID() const
    {
        return m_textureID;
    }

    bool Texture::setSmooth(const bool value)
    {
        if (isValid()) return false;

        //if (m_smooth != value)
        {
            bind();

            uthGraphics.setTextureParameter(TEXTURE_2D, TEXTURE_MAG_FILTER, value ? LINEAR : NEAREST);
		    uthGraphics.setTextureParameter(TEXTURE_2D, TEXTURE_MIN_FILTER, value ? LINEAR : NEAREST);

            m_smooth = value;
        }

        return true;
    }

    bool Texture::setRepeated(const bool value)
    {
        if (!isValid()) return false;

        //if (m_smooth != value)
        {
            bind();

            uthGraphics.setTextureParameter(TEXTURE_2D, TEXTURE_WRAP_S, value ? REPEAT : CLAMP_TO_EDGE);
            uthGraphics.setTextureParameter(TEXTURE_2D, TEXTURE_WRAP_T, value ? REPEAT : CLAMP_TO_EDGE);

            m_repeated = value;
        }

        return true;
    }

    const umath::vector2& Texture::getSize() const
    {
        return m_size;
    }

    const bool Texture::isValid() const
    {
        return m_textureID > 0;
    }

    const bool Texture::isSmooth() const
    {
        return m_smooth;
    }

    const bool Texture::isRepeated() const
    {
        return m_repeated;
    }
}<commit_msg>Fixed and cleaned Texture<commit_after>#include <UtH\Renderer\Texture.hpp>
#include <UtH\Platform\Graphics.hpp>
#include <UtH\Resources\ResourceManager.h>
#include <cstdlib>

namespace uth
{
    Texture::Texture()
        : m_textureID(0),
          m_size(),
          m_smooth(false),
          m_repeated(false)
    {

    }

    Texture::~Texture()
    {

    }

    bool Texture::loadFromFile(const char* path, const bool smooth, const bool repeated)
    {
        uthRS.loadTGA(path);

        m_size.w = uthRS.header.width;
        m_size.h = uthRS.header.height;

        uthGraphics.setPixelStore(UNPACK_ALIGNMENT, 1);
        uthGraphics.generateTextures(1, &m_textureID);
        uthGraphics.setActiveTexUnit(TEXTURE_0);

        bind();

		//setSmooth(smooth);
  //      setRepeated(repeated);

        uthGraphics.setTextureImage2D(TEXTURE_2D, 0, RGBA_FORMAT, m_size.w, m_size.h, RGBA_FORMAT, UNSIGNED_BYTE_TYPE, uthRS.header.pixels);

		setSmooth(smooth);
        setRepeated(repeated);

		return true;
    }

    void Texture::bind()
    {
        uthGraphics.setActiveTexUnit(TEXTURE_0);
        uthGraphics.bindTexture(TEXTURE_2D, m_textureID);
    }

    const unsigned int Texture::getTextureID() const
    {
        return m_textureID;
    }

    bool Texture::setSmooth(const bool value)
    {
        if (!isValid()) return false;

        bind();

        uthGraphics.setTextureParameter(TEXTURE_2D, TEXTURE_MAG_FILTER, value ? LINEAR : NEAREST);
		uthGraphics.setTextureParameter(TEXTURE_2D, TEXTURE_MIN_FILTER, value ? LINEAR : NEAREST);

        m_smooth = value;

        return true;
    }

    bool Texture::setRepeated(const bool value)
    {
        if (!isValid()) return false;

        bind();

        uthGraphics.setTextureParameter(TEXTURE_2D, TEXTURE_WRAP_S, value ? REPEAT : CLAMP_TO_EDGE);
        uthGraphics.setTextureParameter(TEXTURE_2D, TEXTURE_WRAP_T, value ? REPEAT : CLAMP_TO_EDGE);

        m_repeated = value;

        return true;
    }

    const umath::vector2& Texture::getSize() const
    {
        return m_size;
    }

    const bool Texture::isValid() const
    {
        return m_textureID > 0;
    }

    const bool Texture::isSmooth() const
    {
        return m_smooth;
    }

    const bool Texture::isRepeated() const
    {
        return m_repeated;
    }
}<|endoftext|>