<commit_before>/******************************************************************************
 * $Id$
 *
 * Project:  libLAS - http://liblas.org - A BSD library for LAS format data.
 * Purpose:  LAS Dimension implementation for C++ libLAS
 * Author:   Howard Butler, hobu.inc@gmail.com
 *
 ******************************************************************************
 * Copyright (c) 2010, Howard Butler
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following
 * conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of the Martin Isenburg or Iowa Department
 *       of Natural Resources 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 OWNER 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 <libpc/Dimension.hpp>

#include <libpc/exceptions.hpp>
#include <libpc/Utils.hpp>

namespace libpc
{

std::string Dimension::s_fieldNames[Field_LAST];
bool Dimension::s_fieldNamesValid = false;

Dimension::Dimension(Field field, DataType dataType)
    : m_dataType(dataType)
    , m_field(field)
    , m_endian(libpc::Endian_Little)
    , m_byteSize(0)
    , m_description(std::string(""))
    , m_min(0.0)
    , m_max(0.0)
    , m_precise(false)
    , m_numericScale(0.0)
    , m_numericOffset(0.0)
{
    m_byteSize = getDataTypeSize(m_dataType);
}

/// copy constructor
Dimension::Dimension(Dimension const& other)
    : m_dataType(other.m_dataType)
    , m_field(other.m_field)
    , m_endian(other.m_endian)
    , m_byteSize(other.m_byteSize)
    , m_description(other.m_description)
    , m_min(other.m_min)
    , m_max(other.m_max)
    , m_precise(other.m_precise)
    , m_numericScale(other.m_numericScale)
    , m_numericOffset(other.m_numericOffset)
{
}

/// assignment operator
Dimension& Dimension::operator=(Dimension const& rhs)
{
    if (&rhs != this)
    {
        m_dataType = rhs.m_dataType;
        m_field = rhs.m_field;
        m_endian = rhs.m_endian;
        m_byteSize = rhs.m_byteSize;
        m_description = rhs.m_description;
        m_min = rhs.m_min;
        m_max = rhs.m_max;
        m_precise = rhs.m_precise;
        m_numericScale = rhs.m_numericScale;
        m_numericOffset = rhs.m_numericOffset;
    }

    return *this;
}

bool Dimension::operator==(const Dimension& other) const
{
    if (m_dataType == other.m_dataType &&
        m_field == other.m_field &&
        m_endian == other.m_endian &&
        m_byteSize == other.m_byteSize &&
        m_description == other.m_description &&
        Utils::compare_approx(m_min, other.m_min, (std::numeric_limits<double>::min)()) &&
        Utils::compare_approx(m_max, other.m_max, (std::numeric_limits<double>::min)()) &&
        m_precise == other.m_precise &&

        Utils::compare_approx(m_numericScale, other.m_numericScale, (std::numeric_limits<double>::min)()) &&
        Utils::compare_approx(m_numericOffset, other.m_numericOffset, (std::numeric_limits<double>::min)())

        )
    {
        return true;
    }

    return false;
}

bool Dimension::operator!=(const Dimension& other) const
{
  return !(*this==other);
}

boost::property_tree::ptree Dimension::GetPTree() const
{
    using boost::property_tree::ptree;
    ptree dim;
    dim.put("name", getFieldName());
    dim.put("datatype", getDataTypeName(getDataType()));
    dim.put("description", getDescription());
    dim.put("bytesize", getByteSize());

    std::string e("little");
    if (getEndianness() == Endian_Big)
        e = std::string("big");
    dim.put("endianness", e);

    if (isNumeric())
    {
        if (! (Utils::compare_distance(getMinimum(), getMaximum()) &&
               Utils::compare_distance(0.0, getMaximum())))
        {
            dim.put("minimum", getMinimum());
            dim.put("maximum", getMaximum());
        }
    }

    return dim;
}

std::ostream& operator<<(std::ostream& os, libpc::Dimension const& d)
{
    using boost::property_tree::ptree;
    ptree tree = d.GetPTree();

    std::string const name = tree.get<std::string>("name");

    std::ostringstream quoted_name;
    quoted_name << "'" << name << "'";
    std::ostringstream pad;
    std::string const& cur = quoted_name.str();
    std::string::size_type size = cur.size();
    std::string::size_type pad_size = 30 - size;

    for (std::string::size_type i=0; i != pad_size; i++ )
    {
        pad << " ";
    }
    os << quoted_name.str() << pad.str() <<" -- "<< " size: " << tree.get<boost::uint32_t>("bytesize");
    //os << " offset: " << tree.get<boost::uint32_t>("byteoffset");
    os << std::endl;

    return os;
}

std::string Dimension::getDataTypeName(DataType type)
{
    switch (type)
    {
    case Int8:
        return "Int8";
    case Uint8:
        return "Uint8";
    case Int16:
        return "Int16";
    case Uint16:
        return "Uint16";
    case Int32:
        return "Int32";
    case Uint32:
        return "Uint32";
    case Int64:
        return "Int64";
    case Uint64:
        return "Uint64";
    case Float:
        return "Float";
    case Double:
        return "Double";
    case Undefined:
        return "Undefined";
    }
    throw;
}

std::size_t Dimension::getDataTypeSize(DataType type)
{
    switch (type)
    {
    case Int8:
        return 1;
    case Uint8:
        return 1;
    case Int16:
        return 2;
    case Uint16:
        return 2;
    case Int32:
        return 4;
    case Uint32:
        return 4;
    case Int64:
        return 8;
    case Uint64:
        return 8;
    case Float:
        return 4;
    case Double:
        return 8;
    case Undefined:
        throw;
    }
    throw;
}

bool Dimension::getDataTypeIsNumeric(DataType type)
{
    switch (type)
    {
    case Int8:
    case Uint8:
    case Int16:
    case Uint16:
    case Int32:
    case Uint32:
    case Int64:
    case Uint64:
        return true;
    case Float:
    case Double:
        return true;
    case Undefined:
        throw;
    }
    throw;
}

bool Dimension::getDataTypeIsSigned(DataType type)
{
    switch (type)
    {
    case Uint8:
    case Uint16:
    case Uint32:
    case Uint64:
        return false;
    case Int8:
    case Int16:
    case Int32:
    case Int64:
        return true;
    case Float:
    case Double:
        return true;
    case Undefined:
        throw;

    }
    throw;
}

bool Dimension::getDataTypeIsInteger(DataType type)
{
    switch (type)
    {
    case Uint8:
    case Uint16:
    case Uint32:
    case Uint64:
        return true;
    case Int8:
    case Int16:
    case Int32:
    case Int64:
        return true;
    case Float:
    case Double:
        return false;
    case Undefined:
        throw;

    }
    throw;
}

Dimension::DataType Dimension::getDataTypeFromString(const std::string& s)
{
    if (s == "Int8") return Int8;
    if (s == "Uint8") return Uint8;
    if (s == "Int16") return Int16;
    if (s == "Uint16") return Uint16;
    if (s == "Int32") return Int32;
    if (s == "Uint32") return Uint32;
    if (s == "Int64") return Int64;
    if (s == "Uint64") return Uint64;
    if (s == "Float") return Float;
    if (s == "Double") return Double;
    throw;
}

std::string const& Dimension::getFieldName() const
{
    return getFieldName(m_field);
}

std::string const& Dimension::getFieldName(Field field)
{
    if (!s_fieldNamesValid)
        initFieldNames();

    if (field > Field_LAST)
        throw libpc_error("invalid field value (too large)");

    const std::string& s =  s_fieldNames[field];
    if (s.empty())
    {
        throw libpc_error("Field name not set for built-in field value");
    }

    return s;
}

void Dimension::initFieldNames()
{
    for (int i=0; i<Dimension::Field_LAST; i++)
    {
        std::ostringstream ostr;
        ostr << "Unnamed field " << i;
        s_fieldNames[i] = ostr.str();
    }

    // BUG: not threadsafe
    s_fieldNames[Field_INVALID] = "invalid";
    s_fieldNames[Field_X] = "X";
    s_fieldNames[Field_Y] = "Y";
    s_fieldNames[Field_Z] = "Z";
    s_fieldNames[Field_Intensity] = "Intensity";
    s_fieldNames[Field_ReturnNumber] = "ReturnNumber";
    s_fieldNames[Field_NumberOfReturns] = "NumberOfReturns";
    s_fieldNames[Field_ScanDirectionFlag] = "ScanDirectionFlag";
    s_fieldNames[Field_EdgeOfFlightLine] = "EdgeOfFlightLine";
    s_fieldNames[Field_Classification] = "Classification";
    s_fieldNames[Field_ScanAngleRank] = "ScanAngleRank";
    s_fieldNames[Field_UserData] = "UserData";
    s_fieldNames[Field_PointSourceId] = "PointSourceId";
    s_fieldNames[Field_Time] = "Time";
    s_fieldNames[Field_Red] = "Red";
    s_fieldNames[Field_Green] = "Green";
    s_fieldNames[Field_Blue] = "Blue";
    s_fieldNames[Field_WavePacketDescriptorIndex] = "WavePacketDescriptorIndex";
    s_fieldNames[Field_WaveformDataOffset] = "WaveformDataOffset";
    s_fieldNames[Field_ReturnPointWaveformLocation] = "ReturnPointWaveformLocation";
    s_fieldNames[Field_WaveformXt] = "WaveformXt";
    s_fieldNames[Field_WaveformYt] = "WaveformYt";
    s_fieldNames[Field_WaveformZt] = "WaveformZt";

    s_fieldNamesValid = true;
}

} // namespace libpc
<commit_msg>add Field_Alpha name<commit_after>/******************************************************************************
 * $Id$
 *
 * Project:  libLAS - http://liblas.org - A BSD library for LAS format data.
 * Purpose:  LAS Dimension implementation for C++ libLAS
 * Author:   Howard Butler, hobu.inc@gmail.com
 *
 ******************************************************************************
 * Copyright (c) 2010, Howard Butler
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following
 * conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of the Martin Isenburg or Iowa Department
 *       of Natural Resources 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 OWNER 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 <libpc/Dimension.hpp>

#include <libpc/exceptions.hpp>
#include <libpc/Utils.hpp>

namespace libpc
{

std::string Dimension::s_fieldNames[Field_LAST];
bool Dimension::s_fieldNamesValid = false;

Dimension::Dimension(Field field, DataType dataType)
    : m_dataType(dataType)
    , m_field(field)
    , m_endian(libpc::Endian_Little)
    , m_byteSize(0)
    , m_description(std::string(""))
    , m_min(0.0)
    , m_max(0.0)
    , m_precise(false)
    , m_numericScale(0.0)
    , m_numericOffset(0.0)
{
    m_byteSize = getDataTypeSize(m_dataType);
}

/// copy constructor
Dimension::Dimension(Dimension const& other)
    : m_dataType(other.m_dataType)
    , m_field(other.m_field)
    , m_endian(other.m_endian)
    , m_byteSize(other.m_byteSize)
    , m_description(other.m_description)
    , m_min(other.m_min)
    , m_max(other.m_max)
    , m_precise(other.m_precise)
    , m_numericScale(other.m_numericScale)
    , m_numericOffset(other.m_numericOffset)
{
}

/// assignment operator
Dimension& Dimension::operator=(Dimension const& rhs)
{
    if (&rhs != this)
    {
        m_dataType = rhs.m_dataType;
        m_field = rhs.m_field;
        m_endian = rhs.m_endian;
        m_byteSize = rhs.m_byteSize;
        m_description = rhs.m_description;
        m_min = rhs.m_min;
        m_max = rhs.m_max;
        m_precise = rhs.m_precise;
        m_numericScale = rhs.m_numericScale;
        m_numericOffset = rhs.m_numericOffset;
    }

    return *this;
}

bool Dimension::operator==(const Dimension& other) const
{
    if (m_dataType == other.m_dataType &&
        m_field == other.m_field &&
        m_endian == other.m_endian &&
        m_byteSize == other.m_byteSize &&
        m_description == other.m_description &&
        Utils::compare_approx(m_min, other.m_min, (std::numeric_limits<double>::min)()) &&
        Utils::compare_approx(m_max, other.m_max, (std::numeric_limits<double>::min)()) &&
        m_precise == other.m_precise &&

        Utils::compare_approx(m_numericScale, other.m_numericScale, (std::numeric_limits<double>::min)()) &&
        Utils::compare_approx(m_numericOffset, other.m_numericOffset, (std::numeric_limits<double>::min)())

        )
    {
        return true;
    }

    return false;
}

bool Dimension::operator!=(const Dimension& other) const
{
  return !(*this==other);
}

boost::property_tree::ptree Dimension::GetPTree() const
{
    using boost::property_tree::ptree;
    ptree dim;
    dim.put("name", getFieldName());
    dim.put("datatype", getDataTypeName(getDataType()));
    dim.put("description", getDescription());
    dim.put("bytesize", getByteSize());

    std::string e("little");
    if (getEndianness() == Endian_Big)
        e = std::string("big");
    dim.put("endianness", e);

    if (isNumeric())
    {
        if (! (Utils::compare_distance(getMinimum(), getMaximum()) &&
               Utils::compare_distance(0.0, getMaximum())))
        {
            dim.put("minimum", getMinimum());
            dim.put("maximum", getMaximum());
        }
    }

    return dim;
}

std::ostream& operator<<(std::ostream& os, libpc::Dimension const& d)
{
    using boost::property_tree::ptree;
    ptree tree = d.GetPTree();

    std::string const name = tree.get<std::string>("name");

    std::ostringstream quoted_name;
    quoted_name << "'" << name << "'";
    std::ostringstream pad;
    std::string const& cur = quoted_name.str();
    std::string::size_type size = cur.size();
    std::string::size_type pad_size = 30 - size;

    for (std::string::size_type i=0; i != pad_size; i++ )
    {
        pad << " ";
    }
    os << quoted_name.str() << pad.str() <<" -- "<< " size: " << tree.get<boost::uint32_t>("bytesize");
    //os << " offset: " << tree.get<boost::uint32_t>("byteoffset");
    os << std::endl;

    return os;
}

std::string Dimension::getDataTypeName(DataType type)
{
    switch (type)
    {
    case Int8:
        return "Int8";
    case Uint8:
        return "Uint8";
    case Int16:
        return "Int16";
    case Uint16:
        return "Uint16";
    case Int32:
        return "Int32";
    case Uint32:
        return "Uint32";
    case Int64:
        return "Int64";
    case Uint64:
        return "Uint64";
    case Float:
        return "Float";
    case Double:
        return "Double";
    case Undefined:
        return "Undefined";
    }
    throw;
}

std::size_t Dimension::getDataTypeSize(DataType type)
{
    switch (type)
    {
    case Int8:
        return 1;
    case Uint8:
        return 1;
    case Int16:
        return 2;
    case Uint16:
        return 2;
    case Int32:
        return 4;
    case Uint32:
        return 4;
    case Int64:
        return 8;
    case Uint64:
        return 8;
    case Float:
        return 4;
    case Double:
        return 8;
    case Undefined:
        throw;
    }
    throw;
}

bool Dimension::getDataTypeIsNumeric(DataType type)
{
    switch (type)
    {
    case Int8:
    case Uint8:
    case Int16:
    case Uint16:
    case Int32:
    case Uint32:
    case Int64:
    case Uint64:
        return true;
    case Float:
    case Double:
        return true;
    case Undefined:
        throw;
    }
    throw;
}

bool Dimension::getDataTypeIsSigned(DataType type)
{
    switch (type)
    {
    case Uint8:
    case Uint16:
    case Uint32:
    case Uint64:
        return false;
    case Int8:
    case Int16:
    case Int32:
    case Int64:
        return true;
    case Float:
    case Double:
        return true;
    case Undefined:
        throw;

    }
    throw;
}

bool Dimension::getDataTypeIsInteger(DataType type)
{
    switch (type)
    {
    case Uint8:
    case Uint16:
    case Uint32:
    case Uint64:
        return true;
    case Int8:
    case Int16:
    case Int32:
    case Int64:
        return true;
    case Float:
    case Double:
        return false;
    case Undefined:
        throw;

    }
    throw;
}

Dimension::DataType Dimension::getDataTypeFromString(const std::string& s)
{
    if (s == "Int8") return Int8;
    if (s == "Uint8") return Uint8;
    if (s == "Int16") return Int16;
    if (s == "Uint16") return Uint16;
    if (s == "Int32") return Int32;
    if (s == "Uint32") return Uint32;
    if (s == "Int64") return Int64;
    if (s == "Uint64") return Uint64;
    if (s == "Float") return Float;
    if (s == "Double") return Double;
    throw;
}

std::string const& Dimension::getFieldName() const
{
    return getFieldName(m_field);
}

std::string const& Dimension::getFieldName(Field field)
{
    if (!s_fieldNamesValid)
        initFieldNames();

    if (field > Field_LAST)
        throw libpc_error("invalid field value (too large)");

    const std::string& s =  s_fieldNames[field];
    if (s.empty())
    {
        throw libpc_error("Field name not set for built-in field value");
    }

    return s;
}

void Dimension::initFieldNames()
{
    for (int i=0; i<Dimension::Field_LAST; i++)
    {
        std::ostringstream ostr;
        ostr << "Unnamed field " << i;
        s_fieldNames[i] = ostr.str();
    }

    // BUG: not threadsafe
    s_fieldNames[Field_INVALID] = "invalid";
    s_fieldNames[Field_X] = "X";
    s_fieldNames[Field_Y] = "Y";
    s_fieldNames[Field_Z] = "Z";
    s_fieldNames[Field_Intensity] = "Intensity";
    s_fieldNames[Field_ReturnNumber] = "ReturnNumber";
    s_fieldNames[Field_NumberOfReturns] = "NumberOfReturns";
    s_fieldNames[Field_ScanDirectionFlag] = "ScanDirectionFlag";
    s_fieldNames[Field_EdgeOfFlightLine] = "EdgeOfFlightLine";
    s_fieldNames[Field_Classification] = "Classification";
    s_fieldNames[Field_ScanAngleRank] = "ScanAngleRank";
    s_fieldNames[Field_UserData] = "UserData";
    s_fieldNames[Field_PointSourceId] = "PointSourceId";
    s_fieldNames[Field_Time] = "Time";
    s_fieldNames[Field_Red] = "Red";
    s_fieldNames[Field_Green] = "Green";
    s_fieldNames[Field_Blue] = "Blue";
    s_fieldNames[Field_WavePacketDescriptorIndex] = "WavePacketDescriptorIndex";
    s_fieldNames[Field_WaveformDataOffset] = "WaveformDataOffset";
    s_fieldNames[Field_ReturnPointWaveformLocation] = "ReturnPointWaveformLocation";
    s_fieldNames[Field_WaveformXt] = "WaveformXt";
    s_fieldNames[Field_WaveformYt] = "WaveformYt";
    s_fieldNames[Field_WaveformZt] = "WaveformZt";
    s_fieldNames[Field_Alpha] = "Alpha";

    s_fieldNamesValid = true;
}

} // namespace libpc
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: printerinfomanager.hxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: kz $ $Date: 2007-12-12 14:55:25 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _PSPRINT_PRINTERINFOMANAGER_HXX_
#define _PSPRINT_PRINTERINFOMANAGER_HXX_

#include <hash_map>
#ifndef __SGI_STL_LIST
#include <list>
#endif
#ifndef _PSPRINT_HELPER_HXX_
#include <psprint/helper.hxx>
#endif
#ifndef _PSPRINT_JOBDATA_HXX_
#include <psprint/jobdata.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _PSPRINT_HELPER_HXX_
#include <psprint/helper.hxx>
#endif
#include <cstdio>

namespace psp
{

class SystemQueueInfo;

struct PrinterInfo : JobData
{
    // basename of PPD
    rtl::OUString             m_aDriverName;
    // can be the queue
    rtl::OUString             m_aLocation;
    // a user defined comment
    rtl::OUString             m_aComment;
    // a command line to pipe a PS-file to
    rtl::OUString             m_aCommand;
    // a command line to pipe a PS-file to in case of direct print
    rtl::OUString             m_aQuickCommand;
    // a list of special features separated by ',' not used by psprint
    // but assigned from the outside (currently for "fax","pdf=","autoqueue","external_dialog")
    rtl::OUString             m_aFeatures;
    // a mapping of fonts to other fonts.
    // this provides a method for the user
    // to replace arbitrary fonts by printer builtin fonts
    // currently this is only a mapping between font names
    // assuming that only adbobe standard encoding fonts are
    // built into the printer. in future it may be necessary
    // to map to a font name and UCS2 vector which should be mapped
    // this vector is currently implicitly given by the adobe
    // standard encoding
    bool                        m_bPerformFontSubstitution;
    std::hash_map< rtl::OUString, rtl::OUString, rtl::OUStringHash >
    m_aFontSubstitutes;
    std::hash_map< fontID, fontID >
    m_aFontSubstitutions;

    PrinterInfo() :
            JobData(),
            m_bPerformFontSubstitution( false )
    {}
};

class PrinterInfoManager
{
public:
    enum Type { Default = 0, CUPS = 1 };

    struct SystemPrintQueue
    {
        rtl::OUString       m_aQueue;
        rtl::OUString       m_aLocation;
        rtl::OUString       m_aComment;
    };
protected:
    // needed for checkPrintersChanged: files (not necessarily existant)
    // and their last known modification time
    struct WatchFile
    {
        // the file in question
        rtl::OUString         m_aFilePath;
        // the last know modification time or 0, if file did not exist
        TimeValue               m_aModified;
    };

    // internal data to describe a printer
    struct Printer
    {
        // configuration file containing this printer
        // empty means a freshly added printer that has to be saved yet
        rtl::OUString         m_aFile;
        // details other config files that have this printer
        // in case of removal all have to be removed
        std::list< rtl::OUString > m_aAlternateFiles;
        // group in m_aFile containing the printer
        // this must be unique over all configuration files
        // it usually should be the printer name
        rtl::OString          m_aGroup;
        // whether changes need to be saved
        bool                    m_bModified;
        // the corresponding info and job data
        PrinterInfo             m_aInfo;
    };

    std::hash_map< rtl::OUString, Printer, rtl::OUStringHash > m_aPrinters;
    PrinterInfo                         m_aGlobalDefaults;
    std::list< WatchFile >            m_aWatchFiles;
    rtl::OUString                     m_aDefaultPrinter;
    rtl::OUString                     m_aSystemPrintCommand;

    std::list< SystemPrintQueue >     m_aSystemPrintQueues;

    SystemQueueInfo*                  m_pQueueInfo;

    Type                              m_eType;
    bool                              m_bUseIncludeFeature;
    rtl::OUString                     m_aSystemDefaultPaper;

    PrinterInfoManager( Type eType = Default );
    virtual ~PrinterInfoManager();

    virtual void initialize();

    // fill in font substitutions
    // the resulting hash_map maps from source to target font ids
    void fillFontSubstitutions( PrinterInfo& rInfo ) const;

    // fill default paper if not configured in config file
    // default paper is e.g. locale dependent
    // if a paper is already set it will not be overwritten
    void setDefaultPaper( PPDContext& rInfo ) const;

    void initSystemDefaultPaper();
public:

    // there can only be one
    static PrinterInfoManager& get();

    // get PrinterInfoManager type
    Type getType() const { return m_eType; }

    // lists the names of all known printers
    void listPrinters( std::list< rtl::OUString >& rList ) const;

    // gets the number of known printers
    int countPrinters() const { return m_aPrinters.size(); }

    // gets info about a named printer
    const PrinterInfo& getPrinterInfo( const rtl::OUString& rPrinter ) const;

    // gets the name of the default printer
    const rtl::OUString& getDefaultPrinter() const { return m_aDefaultPrinter; }

    virtual void setupJobContextData( JobData& rData );

    // changes the info about a named printer
    virtual void changePrinterInfo( const rtl::OUString& rPrinter, const PrinterInfo& rNewInfo );

    // check if the printer configuration has changed
    // if bwait is true, then this method waits for eventual asynchronous
    // printer discovery to finish
    virtual bool checkPrintersChanged( bool bWait );

    // members for administration (->padmin)

    // add a named printer
    // addPrinter fails if a printer with the same name already exists
    // or the driver does not exist
    virtual bool addPrinter( const rtl::OUString& rPrinterName, const rtl::OUString& rDriverName );

    // remove a named printer
    // this fails if the config file belonging to this printer
    // is not writeable
    // if bCheckOnly is true, the printer is not really removed;
    // this is for checking if the removal would fail
    virtual bool removePrinter( const rtl::OUString& rPrinterName, bool bCheckOnly = false );

    // save the changes to all printers. this fails if there
    // is no writable config file at all
    virtual bool writePrinterConfig();

    // set a new default printer
    // fails if the specified printer does not exist
    virtual bool setDefaultPrinter( const rtl::OUString& rPrinterName );

    // primarily used internally but also by padmin
    // returns the printer queue names
    virtual const std::list< SystemPrintQueue >& getSystemPrintQueues();

    // similar but returnse whole commandlines
    virtual void getSystemPrintCommands( std::list< rtl::OUString >& rCommands );

    // abstract print command
    // returns a stdio FILE* that a postscript file may be written to
    // this may either be a regular file or the result of popen()
    virtual FILE* startSpool( const rtl::OUString& rPrinterName, bool bQuickCommand );
    // close the FILE* returned by startSpool and does the actual spooling
    // returns a numerical job id
    virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData );

    // for spadmin: whether adding or removing a printer is possible
    virtual bool addOrRemovePossible() const;

    bool getUseIncludeFeature() const { return m_bUseIncludeFeature; }

    // check whether a printer's feature string contains a subfeature
    bool checkFeatureToken( const rtl::OUString& rPrinterName, const char* pToken ) const;
};

} // namespace

#endif // _PSPRINT_PRINTERINFOMANAGER_HXX_
<commit_msg>INTEGRATION: CWS vcl86_DEV300 (1.18.6); FILE MERGED 2008/02/20 17:37:12 pl 1.18.6.1: #i83676# add disable CUPS api for the very few people who want that<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: printerinfomanager.hxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-05 16:47:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _PSPRINT_PRINTERINFOMANAGER_HXX_
#define _PSPRINT_PRINTERINFOMANAGER_HXX_

#include <hash_map>
#ifndef __SGI_STL_LIST
#include <list>
#endif
#ifndef _PSPRINT_HELPER_HXX_
#include <psprint/helper.hxx>
#endif
#ifndef _PSPRINT_JOBDATA_HXX_
#include <psprint/jobdata.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _PSPRINT_HELPER_HXX_
#include <psprint/helper.hxx>
#endif
#include <cstdio>

namespace psp
{

class SystemQueueInfo;

struct PrinterInfo : JobData
{
    // basename of PPD
    rtl::OUString             m_aDriverName;
    // can be the queue
    rtl::OUString             m_aLocation;
    // a user defined comment
    rtl::OUString             m_aComment;
    // a command line to pipe a PS-file to
    rtl::OUString             m_aCommand;
    // a command line to pipe a PS-file to in case of direct print
    rtl::OUString             m_aQuickCommand;
    // a list of special features separated by ',' not used by psprint
    // but assigned from the outside (currently for "fax","pdf=","autoqueue","external_dialog")
    rtl::OUString             m_aFeatures;
    // a mapping of fonts to other fonts.
    // this provides a method for the user
    // to replace arbitrary fonts by printer builtin fonts
    // currently this is only a mapping between font names
    // assuming that only adbobe standard encoding fonts are
    // built into the printer. in future it may be necessary
    // to map to a font name and UCS2 vector which should be mapped
    // this vector is currently implicitly given by the adobe
    // standard encoding
    bool                        m_bPerformFontSubstitution;
    std::hash_map< rtl::OUString, rtl::OUString, rtl::OUStringHash >
    m_aFontSubstitutes;
    std::hash_map< fontID, fontID >
    m_aFontSubstitutions;

    PrinterInfo() :
            JobData(),
            m_bPerformFontSubstitution( false )
    {}
};

class PrinterInfoManager
{
public:
    enum Type { Default = 0, CUPS = 1 };

    struct SystemPrintQueue
    {
        rtl::OUString       m_aQueue;
        rtl::OUString       m_aLocation;
        rtl::OUString       m_aComment;
    };
protected:
    // needed for checkPrintersChanged: files (not necessarily existant)
    // and their last known modification time
    struct WatchFile
    {
        // the file in question
        rtl::OUString         m_aFilePath;
        // the last know modification time or 0, if file did not exist
        TimeValue               m_aModified;
    };

    // internal data to describe a printer
    struct Printer
    {
        // configuration file containing this printer
        // empty means a freshly added printer that has to be saved yet
        rtl::OUString         m_aFile;
        // details other config files that have this printer
        // in case of removal all have to be removed
        std::list< rtl::OUString > m_aAlternateFiles;
        // group in m_aFile containing the printer
        // this must be unique over all configuration files
        // it usually should be the printer name
        rtl::OString          m_aGroup;
        // whether changes need to be saved
        bool                    m_bModified;
        // the corresponding info and job data
        PrinterInfo             m_aInfo;
    };

    std::hash_map< rtl::OUString, Printer, rtl::OUStringHash > m_aPrinters;
    PrinterInfo                         m_aGlobalDefaults;
    std::list< WatchFile >            m_aWatchFiles;
    rtl::OUString                     m_aDefaultPrinter;
    rtl::OUString                     m_aSystemPrintCommand;

    std::list< SystemPrintQueue >     m_aSystemPrintQueues;

    SystemQueueInfo*                  m_pQueueInfo;

    Type                              m_eType;
    bool                              m_bUseIncludeFeature;
    rtl::OUString                     m_aSystemDefaultPaper;

    bool                              m_bDisableCUPS;

    PrinterInfoManager( Type eType = Default );
    virtual ~PrinterInfoManager();

    virtual void initialize();

    // fill in font substitutions
    // the resulting hash_map maps from source to target font ids
    void fillFontSubstitutions( PrinterInfo& rInfo ) const;

    // fill default paper if not configured in config file
    // default paper is e.g. locale dependent
    // if a paper is already set it will not be overwritten
    void setDefaultPaper( PPDContext& rInfo ) const;

    void initSystemDefaultPaper();
public:

    // there can only be one
    static PrinterInfoManager& get();

    // get PrinterInfoManager type
    Type getType() const { return m_eType; }

    // lists the names of all known printers
    void listPrinters( std::list< rtl::OUString >& rList ) const;

    // gets the number of known printers
    int countPrinters() const { return m_aPrinters.size(); }

    // gets info about a named printer
    const PrinterInfo& getPrinterInfo( const rtl::OUString& rPrinter ) const;

    // gets the name of the default printer
    const rtl::OUString& getDefaultPrinter() const { return m_aDefaultPrinter; }

    virtual void setupJobContextData( JobData& rData );

    // changes the info about a named printer
    virtual void changePrinterInfo( const rtl::OUString& rPrinter, const PrinterInfo& rNewInfo );

    // check if the printer configuration has changed
    // if bwait is true, then this method waits for eventual asynchronous
    // printer discovery to finish
    virtual bool checkPrintersChanged( bool bWait );

    // members for administration (->padmin)

    // add a named printer
    // addPrinter fails if a printer with the same name already exists
    // or the driver does not exist
    virtual bool addPrinter( const rtl::OUString& rPrinterName, const rtl::OUString& rDriverName );

    // remove a named printer
    // this fails if the config file belonging to this printer
    // is not writeable
    // if bCheckOnly is true, the printer is not really removed;
    // this is for checking if the removal would fail
    virtual bool removePrinter( const rtl::OUString& rPrinterName, bool bCheckOnly = false );

    // save the changes to all printers. this fails if there
    // is no writable config file at all
    virtual bool writePrinterConfig();

    // set a new default printer
    // fails if the specified printer does not exist
    virtual bool setDefaultPrinter( const rtl::OUString& rPrinterName );

    // primarily used internally but also by padmin
    // returns the printer queue names
    virtual const std::list< SystemPrintQueue >& getSystemPrintQueues();

    // similar but returnse whole commandlines
    virtual void getSystemPrintCommands( std::list< rtl::OUString >& rCommands );

    // abstract print command
    // returns a stdio FILE* that a postscript file may be written to
    // this may either be a regular file or the result of popen()
    virtual FILE* startSpool( const rtl::OUString& rPrinterName, bool bQuickCommand );
    // close the FILE* returned by startSpool and does the actual spooling
    // returns a numerical job id
    virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData );

    // for spadmin: whether adding or removing a printer is possible
    virtual bool addOrRemovePossible() const;

    bool getUseIncludeFeature() const { return m_bUseIncludeFeature; }

    // check whether a printer's feature string contains a subfeature
    bool checkFeatureToken( const rtl::OUString& rPrinterName, const char* pToken ) const;

    // set m_bDisableCUPS and update printer config
    void setCUPSDisabled( bool );

    // gets m_bDisableCUPS, initialized from printer config
    bool isCUPSDisabled() const;
};

} // namespace

#endif // _PSPRINT_PRINTERINFOMANAGER_HXX_
<|endoftext|>


<commit_before>/**
 * \file Dynamixel.cpp
*/

#include "Dynamixel.h"

uint8_t DynamixelPacket::checkSum()
{
	uint8_t result=mID+mLenght+mInstruction;
	for(int i=0; i<(mLenght-2); ++i)
	{
		result+=mData[i];
	}
	return ~result;
}

DynamixelDevice::DynamixelDevice(DynamixelInterface &aInterface, DynamixelID aID):
	mInterface(aInterface), mID(aID), mStatusReturnLevel(255)
{
	mPacket.mStatus=DYN_STATUS_OK;
	if(mID==BROADCAST_ID)
		mStatusReturnLevel=0;
}

uint8_t DynamixelDevice::statusReturnLevel()
{
	if(mStatusReturnLevel==255)
	{
		init();
	}
	return mStatusReturnLevel;
}

void DynamixelDevice::statusReturnLevel(uint8_t aSRL)
{
	write(DYN_ADDRESS_SRL, aSRL);
	if(status()==DYN_STATUS_OK)
	{
		mStatusReturnLevel=aSRL;
	}
}

uint16_t DynamixelDevice::model()
{
	uint16_t result;
	read(DYN_ADDRESS_ID, result);
	return result;
}

uint8_t DynamixelDevice::firmware()
{
	uint8_t result;
	read(DYN_ADDRESS_FIRMWARE, result);
	return result;
}

void DynamixelDevice::communicationSpeed(uint32_t aSpeed)
{
	uint8_t value=2000000/aSpeed-1;
	write(DYN_ADDRESS_BAUDRATE, value);
}

DynamixelStatus DynamixelDevice::ping()
{
	transaction(DYN_PING, 0, NULL);
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::read(uint8_t aAddress, uint8_t aSize, uint8_t *aPtr)
{
	aPtr[0]=aAddress;
	aPtr[1]=aSize;
	transaction(DYN_READ, 2, aPtr);
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::write(uint8_t aAddress, uint8_t aSize, uint8_t *aPtr)
{
	aPtr[-1]=aAddress;
	transaction(DYN_WRITE, aSize+1, const_cast<uint8_t*>(aPtr-1));
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::regWrite(uint8_t aAddress, uint8_t aSize, uint8_t *aPtr)
{
	aPtr[-1]=aAddress;
	transaction(DYN_REG_WRITE, aSize+1, const_cast<uint8_t*>(aPtr-1));
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::action()
{
	transaction(DYN_ACTION, 0, NULL);
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::reset()
{
	transaction(DYN_RESET, 0, NULL);
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::init()
{
	mStatusReturnLevel=2;
	DynamixelStatus status=ping();
	if(status!=DYN_STATUS_OK)
	{
		return status;
	}
	status=read(DYN_ADDRESS_SRL, mStatusReturnLevel);
	if(status&DYN_STATUS_TIMEOUT)
	{
		mStatusReturnLevel=0;
	}
	return DYN_STATUS_OK;
}

uint8_t DynamixelDevice::sInternalBuffer[]={0};

void DynamixelDevice::transaction(uint8_t aInstruction, uint8_t aLenght, uint8_t *aData)
{
	bool response_expected=(mStatusReturnLevel>1 || (mStatusReturnLevel>0 && mPacket.mInstruction==DYN_READ) || mPacket.mInstruction==DYN_PING);

	mPacket.mID=mID;
	mPacket.mInstruction=aInstruction;
	mPacket.mLenght=aLenght+2;
	mPacket.mData=aData;
	mPacket.mCheckSum=mPacket.checkSum();
	mInterface.sendPacket(mPacket);
	if(response_expected)
	{
		mInterface.receivePacket(mPacket);
	}
	else
	{
		mPacket.mStatus=DYN_STATUS_OK;
	}
}

<commit_msg>more safe communicationSpeed : forbid 2MBd<commit_after>/**
 * \file Dynamixel.cpp
*/

#include "Dynamixel.h"

uint8_t DynamixelPacket::checkSum()
{
	uint8_t result=mID+mLenght+mInstruction;
	for(int i=0; i<(mLenght-2); ++i)
	{
		result+=mData[i];
	}
	return ~result;
}

DynamixelDevice::DynamixelDevice(DynamixelInterface &aInterface, DynamixelID aID):
	mInterface(aInterface), mID(aID), mStatusReturnLevel(255)
{
	mPacket.mStatus=DYN_STATUS_OK;
	if(mID==BROADCAST_ID)
		mStatusReturnLevel=0;
}

uint8_t DynamixelDevice::statusReturnLevel()
{
	if(mStatusReturnLevel==255)
	{
		init();
	}
	return mStatusReturnLevel;
}

void DynamixelDevice::statusReturnLevel(uint8_t aSRL)
{
	write(DYN_ADDRESS_SRL, aSRL);
	if(status()==DYN_STATUS_OK)
	{
		mStatusReturnLevel=aSRL;
	}
}

uint16_t DynamixelDevice::model()
{
	uint16_t result;
	read(DYN_ADDRESS_ID, result);
	return result;
}

uint8_t DynamixelDevice::firmware()
{
	uint8_t result;
	read(DYN_ADDRESS_FIRMWARE, result);
	return result;
}

void DynamixelDevice::communicationSpeed(uint32_t aSpeed)
{
	uint8_t value=2000000/aSpeed-1;
	if(value!=0) // forbid 2MBd rate, because it is out of spec, and can be difficult to undo
	{
		write(DYN_ADDRESS_BAUDRATE, value);
	}
}

DynamixelStatus DynamixelDevice::ping()
{
	transaction(DYN_PING, 0, NULL);
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::read(uint8_t aAddress, uint8_t aSize, uint8_t *aPtr)
{
	aPtr[0]=aAddress;
	aPtr[1]=aSize;
	transaction(DYN_READ, 2, aPtr);
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::write(uint8_t aAddress, uint8_t aSize, uint8_t *aPtr)
{
	aPtr[-1]=aAddress;
	transaction(DYN_WRITE, aSize+1, const_cast<uint8_t*>(aPtr-1));
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::regWrite(uint8_t aAddress, uint8_t aSize, uint8_t *aPtr)
{
	aPtr[-1]=aAddress;
	transaction(DYN_REG_WRITE, aSize+1, const_cast<uint8_t*>(aPtr-1));
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::action()
{
	transaction(DYN_ACTION, 0, NULL);
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::reset()
{
	transaction(DYN_RESET, 0, NULL);
	return mPacket.mStatus;
}

DynamixelStatus DynamixelDevice::init()
{
	mStatusReturnLevel=2;
	DynamixelStatus status=ping();
	if(status!=DYN_STATUS_OK)
	{
		return status;
	}
	status=read(DYN_ADDRESS_SRL, mStatusReturnLevel);
	if(status&DYN_STATUS_TIMEOUT)
	{
		mStatusReturnLevel=0;
	}
	return DYN_STATUS_OK;
}

uint8_t DynamixelDevice::sInternalBuffer[]={0};

void DynamixelDevice::transaction(uint8_t aInstruction, uint8_t aLenght, uint8_t *aData)
{
	bool response_expected=(mStatusReturnLevel>1 || (mStatusReturnLevel>0 && mPacket.mInstruction==DYN_READ) || mPacket.mInstruction==DYN_PING);

	mPacket.mID=mID;
	mPacket.mInstruction=aInstruction;
	mPacket.mLenght=aLenght+2;
	mPacket.mData=aData;
	mPacket.mCheckSum=mPacket.checkSum();
	mInterface.sendPacket(mPacket);
	if(response_expected)
	{
		mInterface.receivePacket(mPacket);
	}
	else
	{
		mPacket.mStatus=DYN_STATUS_OK;
	}
}

<|endoftext|>


<commit_before>#define _USE_MATH_DEFINES

#include <Windows.h>
#include "Game.h"
#include <gl\GL.h>
#include <gl\glut.h>
#include "RGBAColor.h"
#include "SpriteLayer.h"
#include "WallPlayer.h"

#include <math.h>
#include <iostream>

Game::Game() :
    window(800, 600, "Foul Kicker"), level(0)
{
    Layer* background = new Layer();
    background->addImage("resources/img/stadium.ptm");
    background->setX(0);
    background->setY(0);

    Image* bgImg = background->getImage();

    this->scene = new Image(*bgImg);
    this->bgCopy = bgImg;
    this->layers.push_back(background);

    Layer* goalkeeper = new Layer();
    goalkeeper->addImage("resources/img/goalkeeper1.ptm");
    goalkeeper->setX(399);
    goalkeeper->setY(208);

    this->layers.push_back(goalkeeper);

    /*
     * TODO: Level layout initialization should be in
     * another place. Maybe on a file later.
     */
    level.addPlayerOnWall(Position(270, 150));
    loadLevel(level);

    Level l(1);
    l.addPlayerOnWall(Position(490, 150));
    levels.push_back(l);

    Level l2(2);
    l2.addPlayerOnWall(Position(270, 150));
    l2.addPlayerOnWall(Position(320, 150));
    levels.push_back(l2);

    Level l3(3);
    l3.addPlayerOnWall(Position(440, 150));
    l3.addPlayerOnWall(Position(490, 150));
    levels.push_back(l3);

    Level l4(4);
    l4.addPlayerOnWall(Position(270, 150));
    l4.addPlayerOnWall(Position(320, 150));
    l4.addPlayerOnWall(Position(370, 150));
    levels.push_back(l4);

    Level l5(5);
    l5.addPlayerOnWall(Position(390, 150));
    l5.addPlayerOnWall(Position(440, 150));
    l5.addPlayerOnWall(Position(490, 150));
    levels.push_back(l5);

    // set initial speed of the ball
    ball.setSpeedX(0);
    ball.setSpeedY(0);

    ballLayer.setSprite(ball.getCurrentSprite());
    ballLayer.setX(400);
    ballLayer.setY(0);

    this->goalkeeperDirection = 1;

    currentTime = 1;

    this->run();
}

Game::~Game()
{
    delete this->scene;
    delete this->bgCopy;

    // Properly clean the vector
    while (!this->layers.empty()) {
        delete this->layers.back();
        this->layers.pop_back();
    }
}

bool Game::checkForCollision() {

	bool collision = false;

	Layer* goalkeeper = this->layers.at(1);

	// GoalKeeper collision
	if ((ballLayer.getY() >= goalkeeper->getY() && ballLayer.getY() <= 224) &&
		(ballLayer.getX() >= goalkeeper->getX() && ballLayer.getX() <= goalkeeper->getX() + goalkeeper->getWidth())) {
		collision = true;
	}

	Layer wall = wallLayers.at(0);

	// WallLayer collision
	if (ballLayer.getY() == wall.getY() &&
		ballLayer.getX() >= wall.getX() &&
		ballLayer.getX() <= (wall.getX() + wall.getWidth() * (int)wallLayers.size())) {
		collision = true;
	}

	// GoalLine collision
	if (isBallOutOfPlay() && !hasCrossedGoalLine()) {
		collision = true;
	}

	// Sideline collision
	if (ballLayer.getX() > window.getWidth() || ballLayer.getX() < 0) {
		collision = true;
	}

	return collision;
}

int Game::animateBall(int time) {
    ballLayer.saveCurrentPosition();

	//ToDo:: Aplicar calculo de balistica
	if (currentAngleDirection > 0) {
		double v = ball.getSpeedY();
		double a = currentAngleDirection * M_PI / 180.0;
		double z = v * cos(a) * ++time;
		double temp = z / (v * cos(a));
		double w = z * tan(a) - 0.5 * 98 * (temp * temp);

		//ToDo:: Troca de Bola em Funcao do time por "v"
		if (ballLayer.getY() / 45 >= currentTime) {
			ball.nextBall();
			ballLayer.setSprite(ball.getCurrentSprite());
			currentTime++;
		}

		int posY = ballLayer.getY() + v;
		ballLayer.setX(400 + z);
		ballLayer.setY(posY);
	}

    Layer* goalkeeper = this->layers.at(1);

	/* Detectar gol
	 * Linha do Gol y@226
	 */
	if (checkForCollision()) {
		//Goal Defense
		prepare();
		std::cout << "Goal Defense" << "\n";
		time = 0;
	}

	if (isBallOutOfPlay() && hasCrossedGoalLine()) {
		//Goal
		prepare();
		std::cout << "Goal" << "\n";
		time = 0;
		nextLevel();
	}

	/*
     * Trave Esquerda x@286
     * Trave Direita x@490
     */

    if (goalkeeper->getX() >= 490) {
        goalkeeperDirection = -1;
    } else {
        if (goalkeeper->getX() <= 286) {
            goalkeeperDirection = 1;
        }
    }

    goalkeeper->saveCurrentPosition();

    int goalkeeperPos = goalkeeper->getX();
    goalkeeperPos += 5 * goalkeeperDirection;
    goalkeeper->setX(goalkeeperPos);

    this->run();

    return time;
}

void Game::run() {
    if (!this->scene) {
        this->scene = new Image(this->window.getWidth(), this->window.getHeight());
    }

    int length = this->layers.size();

    for (int i = 1; i < length; i++) {
        drawLayer(layers.at(i));
    }

    for (unsigned i = 0; i < wallLayers.size(); i++) {
        drawLayer(&wallLayers.at(i));
    }

    drawLayer(&ballLayer);
}

void Game::drawLayer(Layer* layer) {
    Position* lastPos = layer->getLastPosition();

    /* TODO: Refactor it. This code probably should not be here.
     *
     * Redraw the part where the layer was located in the previous frame
     * so it deletes its trace.
     */
    if (lastPos) {
        int height = lastPos->getPosY() + lastPos->getHeight(),
            width = lastPos->getPosX() + lastPos->getWidth();

        for (int y = lastPos->getPosY(); y < height; y++) {
            if (y >= scene->getHeight()) break;
            if (y < 0) continue;

            for (int x = lastPos->getPosX(); x < width; x++) {
                if (x >= scene->getWidth()) break;
                if (x < 0) continue;

                unsigned pixel = this->bgCopy->getPixel(x, y);
                this->scene->setPixel(pixel, x, y);
            }
        }
    }

    layer->draw(this->scene, layer->getX(), layer->getY());
}

void Game::display(void) {

    glDrawPixels(scene->getWidth(), scene->getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, scene->getPixels());

    glFlush();
}

void Game::loadLevel(Level newLevel) {
    while (!wallLayers.empty()) {
        wallLayers.pop_back();
    }

    for (int a = 0; a < newLevel.getNumberOfPlayersOnWall(); a++) {
        Layer player;
        player.setImage(wallPlayer.getImage());

        const Position* position = level.getPlayerPosition(a);

        if (position) {
            player.setX(position->getPosX());
            player.setY(position->getPosY());
        }

        wallLayers.push_back(player);
    }
}

bool Game::isBallOutOfPlay() {
	return ballLayer.getY() > 225;
}

bool Game::hasCrossedGoalLine() {
	return ballLayer.getX() >= 280 && ballLayer.getX() <= 520;
}

void Game::prepare() {
	ballLayer.setX(400);
	ballLayer.setY(0);
	ball.setSpeedX(0);
	ball.setSpeedY(2.0);
	currentAngleDirection = 0;

    currentTime = 1;
    ball.setCurrentBall(0);
    ballLayer.setSprite(ball.getCurrentSprite());
}

void Game::kick(int x, int y) {
	std::cout << "Kick " << x << "\t" << y << "\n";

	int diffY = window.getHeight() - y;

	int initialX = ballLayer.getX();
	int finalX = initialX + ballLayer.getWidth();

	int initialY = ballLayer.getY();
	int finalY = initialY + ballLayer.getHeight();

	int axisX = finalX - x;
	int axisY = finalY - abs(diffY);

	if (initialY == 0 &&
		(axisX >= 0 && axisX <= ballLayer.getWidth()) &&
		(axisY >= 0 && axisY <= ballLayer.getHeight())) {
		prepare();
		currentAngleDirection = abs(180 - axisX * 6);
		std::cout << axisX << "\t" << axisY << "\n";
	}
}

bool Game::nextLevel() {
    if (levels.size() > 0) {
        Level l = levels.front();
        levels.erase(levels.begin());
        level = l;
        std::cout << level.getLevel() << "\n";
        // draw background
        drawLayer(layers.at(0));
        loadLevel(l);
    } else {
        std::cout << "Out of levels\n";
        return false;
    }

    return true;
}

<commit_msg>Better Goal Defense Detection and Brief Pause<commit_after>#define _USE_MATH_DEFINES

#include <Windows.h>
#include "Game.h"
#include <gl\GL.h>
#include <gl\glut.h>
#include "RGBAColor.h"
#include "SpriteLayer.h"
#include "WallPlayer.h"

#include <math.h>
#include <iostream>

Game::Game() :
    window(800, 600, "Foul Kicker"), level(0)
{
    Layer* background = new Layer();
    background->addImage("resources/img/stadium.ptm");
    background->setX(0);
    background->setY(0);

    Image* bgImg = background->getImage();

    this->scene = new Image(*bgImg);
    this->bgCopy = bgImg;
    this->layers.push_back(background);

    Layer* goalkeeper = new Layer();
    goalkeeper->addImage("resources/img/goalkeeper1.ptm");
    goalkeeper->setX(399);
    goalkeeper->setY(208);

    this->layers.push_back(goalkeeper);

    /*
     * TODO: Level layout initialization should be in
     * another place. Maybe on a file later.
     */
    level.addPlayerOnWall(Position(270, 150));
    loadLevel(level);

    Level l(1);
    l.addPlayerOnWall(Position(490, 150));
    levels.push_back(l);

    Level l2(2);
    l2.addPlayerOnWall(Position(270, 150));
    l2.addPlayerOnWall(Position(320, 150));
    levels.push_back(l2);

    Level l3(3);
    l3.addPlayerOnWall(Position(440, 150));
    l3.addPlayerOnWall(Position(490, 150));
    levels.push_back(l3);

    Level l4(4);
    l4.addPlayerOnWall(Position(270, 150));
    l4.addPlayerOnWall(Position(320, 150));
    l4.addPlayerOnWall(Position(370, 150));
    levels.push_back(l4);

    Level l5(5);
    l5.addPlayerOnWall(Position(390, 150));
    l5.addPlayerOnWall(Position(440, 150));
    l5.addPlayerOnWall(Position(490, 150));
    levels.push_back(l5);

    // set initial speed of the ball
    ball.setSpeedX(0);
    ball.setSpeedY(0);

    ballLayer.setSprite(ball.getCurrentSprite());
    ballLayer.setX(400);
    ballLayer.setY(0);

    this->goalkeeperDirection = 1;

    currentTime = 1;

    this->run();
}

Game::~Game()
{
    delete this->scene;
    delete this->bgCopy;

    // Properly clean the vector
    while (!this->layers.empty()) {
        delete this->layers.back();
        this->layers.pop_back();
    }
}

bool Game::checkForCollision() {

	bool collision = false;

	Layer* goalkeeper = this->layers.at(1);

	int Y = goalkeeper->getY();
	// GoalKeeper collision
	if ((ballLayer.getY() >= goalkeeper->getY() && ballLayer.getY() < 220) &&
		(ballLayer.getX() >= goalkeeper->getX() && ballLayer.getX() <= goalkeeper->getX() + goalkeeper->getWidth())) {
		collision = true;
	}

	Layer wall = wallLayers.at(0);

	// WallLayer collision
	if (ballLayer.getY() == wall.getY() &&
		ballLayer.getX() >= wall.getX() &&
		ballLayer.getX() <= (wall.getX() + wall.getWidth() * (int)wallLayers.size())) {
		collision = true;
	}

	// GoalLine collision
	if (isBallOutOfPlay() && !hasCrossedGoalLine()) {
		collision = true;
	}

	// Sideline collision
	if (ballLayer.getX() > window.getWidth() || ballLayer.getX() < 0) {
		collision = true;
	}

	return collision;
}

int Game::animateBall(int time) {
    ballLayer.saveCurrentPosition();

	//ToDo:: Aplicar calculo de balistica
	if (currentAngleDirection > 0) {
		double v = ball.getSpeedY();
		double a = currentAngleDirection * M_PI / 180.0;
		double z = v * cos(a) * ++time;
		double temp = z / (v * cos(a));
		double w = z * tan(a) - 0.5 * 98 * (temp * temp);

		//ToDo:: Troca de Bola em Funcao do time por "v"
		if (ballLayer.getY() / 45 >= currentTime) {
			ball.nextBall();
			ballLayer.setSprite(ball.getCurrentSprite());
			currentTime++;
		}

		int posY = ballLayer.getY() + v;
		ballLayer.setX(400 + z);
		ballLayer.setY(posY);
	}

    Layer* goalkeeper = this->layers.at(1);

	/* Detectar gol
	 * Linha do Gol y@226
	 */
	if (checkForCollision()) {
		//Goal Defense
		prepare();
		Sleep(250);

		std::cout << "Goal Defense" << "\n";
		time = 0;
	}

	if (isBallOutOfPlay() && hasCrossedGoalLine()) {
		//Goal
		prepare();
		Sleep(250);

		std::cout << "Goal" << "\n";
		time = 0;
		nextLevel();
	}

	/*
     * Trave Esquerda x@286
     * Trave Direita x@490
     */

    if (goalkeeper->getX() >= 490) {
        goalkeeperDirection = -1;
    } else {
        if (goalkeeper->getX() <= 286) {
            goalkeeperDirection = 1;
        }
    }

    goalkeeper->saveCurrentPosition();

    int goalkeeperPos = goalkeeper->getX();
    goalkeeperPos += 5 * goalkeeperDirection;
    goalkeeper->setX(goalkeeperPos);

    this->run();

    return time;
}

void Game::run() {
    if (!this->scene) {
        this->scene = new Image(this->window.getWidth(), this->window.getHeight());
    }

    int length = this->layers.size();

    for (int i = 1; i < length; i++) {
        drawLayer(layers.at(i));
    }

    for (unsigned i = 0; i < wallLayers.size(); i++) {
        drawLayer(&wallLayers.at(i));
    }

    drawLayer(&ballLayer);
}

void Game::drawLayer(Layer* layer) {
    Position* lastPos = layer->getLastPosition();

    /* TODO: Refactor it. This code probably should not be here.
     *
     * Redraw the part where the layer was located in the previous frame
     * so it deletes its trace.
     */
    if (lastPos) {
        int height = lastPos->getPosY() + lastPos->getHeight(),
            width = lastPos->getPosX() + lastPos->getWidth();

        for (int y = lastPos->getPosY(); y < height; y++) {
            if (y >= scene->getHeight()) break;
            if (y < 0) continue;

            for (int x = lastPos->getPosX(); x < width; x++) {
                if (x >= scene->getWidth()) break;
                if (x < 0) continue;

                unsigned pixel = this->bgCopy->getPixel(x, y);
                this->scene->setPixel(pixel, x, y);
            }
        }
    }

    layer->draw(this->scene, layer->getX(), layer->getY());
}

void Game::display(void) {

    glDrawPixels(scene->getWidth(), scene->getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, scene->getPixels());

    glFlush();
}

void Game::loadLevel(Level newLevel) {
    while (!wallLayers.empty()) {
        wallLayers.pop_back();
    }

    for (int a = 0; a < newLevel.getNumberOfPlayersOnWall(); a++) {
        Layer player;
        player.setImage(wallPlayer.getImage());

        const Position* position = level.getPlayerPosition(a);

        if (position) {
            player.setX(position->getPosX());
            player.setY(position->getPosY());
        }

        wallLayers.push_back(player);
    }
}

bool Game::isBallOutOfPlay() {
	return ballLayer.getY() > 225;
}

bool Game::hasCrossedGoalLine() {
	return ballLayer.getX() >= 280 && ballLayer.getX() <= 520;
}

void Game::prepare() {
	ballLayer.setX(400);
	ballLayer.setY(0);
	ball.setSpeedX(0);
	ball.setSpeedY(2.0);
	currentAngleDirection = 0;

    currentTime = 1;
    ball.setCurrentBall(0);
    ballLayer.setSprite(ball.getCurrentSprite());
}

void Game::kick(int x, int y) {
	std::cout << "Kick " << x << "\t" << y << "\n";

	int diffY = window.getHeight() - y;

	int initialX = ballLayer.getX();
	int finalX = initialX + ballLayer.getWidth();

	int initialY = ballLayer.getY();
	int finalY = initialY + ballLayer.getHeight();

	int axisX = finalX - x;
	int axisY = finalY - abs(diffY);

	if (initialY == 0 &&
		(axisX >= 0 && axisX <= ballLayer.getWidth()) &&
		(axisY >= 0 && axisY <= ballLayer.getHeight())) {
		prepare();
		currentAngleDirection = abs(180 - axisX * 6);
		std::cout << axisX << "\t" << axisY << "\n";
	}
}

bool Game::nextLevel() {
    if (levels.size() > 0) {
        Level l = levels.front();
        levels.erase(levels.begin());
        level = l;
        std::cout << level.getLevel() << "\n";
        // draw background
        drawLayer(layers.at(0));
        loadLevel(l);
    } else {
        std::cout << "Out of levels\n";
        return false;
    }

    return true;
}

<|endoftext|>


<commit_before>//
//  SerialReader.cpp
//  GoldsprintsFX
//
//  Created by Charlie Whitney on 8/28/14.
//
//

#include "data/SerialReader.h"

using namespace ci;
using namespace ci::app;
using namespace std;
using namespace gfx;
using namespace Cinder::Serial;

SerialReader::SerialReader() :
    BAUD_RATE(115200),
    mStringBuffer(""),
    mHardwareVersion(""),
    mProtoculVersion(""),
    mFirmwareVersion(""),
    mSerial(NULL),
    mReceiveBuffer(100),
    mSendBuffer(100)
{

}

SerialReader::~SerialReader()
{
    stopRace();
    bThreadShouldQuit = true;
    mSerialThread->join();
}

void SerialReader::setup()
{
    mStateManager = StateManager::getInstance();

    mSerialThread = std::shared_ptr<std::thread>( new std::thread( std::bind(&SerialReader::updateSerialThread, this) ) );
}

void SerialReader::update()
{
    // if we connected since the last update, notify
    if( bSerialConnected && !bLastConnection){
		mSerial->flush();
        onConnect();
        timeline().add( [&](){ getVersion(); }, timeline().getCurrentTime() + 2.0 );
    }else if( !bSerialConnected && bLastConnection ){
        onDisconnect();
    }
    bLastConnection = bSerialConnected;

    // parse buffered data
    parseFromBuffer();
}

void SerialReader::updateSerialThread()
{
    ThreadSetup threadSetup;

    while( !bThreadShouldQuit ){
        std::lock_guard<std::mutex> guard(mSerialMutex);

        if(!bSerialConnected ){ // we aren't connected try to connect
			auto ports = SerialPort::getPorts(true);
            /*
			for (auto port : ports) {
				console() << "SERIAL DEVICE" << endl;
				console() << "\tNAME: " << port->getName() << endl;
				console() << "\tDESCRIPTION: " << port->getDescription() << endl;
				console() << "\tHARDWARE IDENTIFIER: " << port->getHardwareIdentifier() << endl;
			}
             */
			try {
				if (!ports.empty()) {
					SerialPortRef port = SerialPort::findPortByDescriptionMatching(std::regex("Arduino.*"), true);
					if (!port) {
						port = ports.back();
					}

					mSerial = SerialDevice::create(port, BAUD_RATE);
					mSerial->flush();
					bSerialConnected = true;

					for (int i = 0; i < mSendBuffer.getSize(); i++) {        // clear send buffer
						std::string tmp;
						mSendBuffer.popBack(&tmp);
					}
					stopRace();

					for (int i = 0; i < mReceiveBuffer.getSize(); i++) {    // clear receive buffer
						std::vector<std::string> tmp;
						mReceiveBuffer.popBack(&tmp);
					}
					CI_LOG_I("OpenSprints hardware found successfully. :: ") << mSerial->getPortName();
				}
			}catch (serial::IOException& e) {
				if (mSerial && mSerial->isOpen()) {
					mSerial->close();
				}
                bSerialConnected = false;
            }
        }else{
            // make sure we're still connected
			auto pOpen = SerialPort::findPortByDescriptionMatching(std::regex("Arduino.*"), true);

            if(pOpen == nullptr){
				if (mSerial && mSerial->isOpen()) {
					mSerial->close();
				}
                bSerialConnected = false;
            }else{
				// send to arduino
                for(int i=0; i<mSendBuffer.getSize(); i++){
                    std::string msgToSend;
                    mSendBuffer.popBack( &msgToSend );

					CI_LOG_I("Sending :: ") << msgToSend;

                    mSerial->writeString( msgToSend );
                }

                // receive from arduino
                readSerial();
            }
        }
    }
}

void SerialReader::readSerial()
{
    try {
		size_t bytesAvailable = mSerial->getNumBytesAvailable();
		size_t charsAvailable = floor(bytesAvailable / sizeof(char));

        for(int i=0; i<charsAvailable; i++){
			unsigned char c;	// uint8_t
			mSerial->readBytes(&c, 1);
            mStringBuffer += c;
        }
    }catch(serial::IOException& e){
        bSerialConnected = false;
		if (mSerial && mSerial->isOpen()) {
			mSerial->close();
			//mSerial = nullptr;
		}
    }

    auto index = mStringBuffer.find("\r\n");
    if(index != string::npos){
        std::string cmd = mStringBuffer.substr(0, index);
        mStringBuffer.replace(0, index+2, "");      // The newline is 2 bytes (\r\n) so add two to remove it

        parseCommandToBuffer( cmd );
    }
}

void SerialReader::parseCommandToBuffer( std::string command )
{
    std::vector<std::string> strs;
    boost::split(strs, command, boost::is_any_of(":"));

    std::vector<std::string> tmpBuffer;
    tmpBuffer.push_back( strs[0] );

    std::string args = "";
    if( strs.size() > 1){
        tmpBuffer.push_back(strs[1]);
    }

    mReceiveBuffer.tryPushFront(tmpBuffer);
}

// Parse commands in the main thread that we grabbed during the updateSerial thread
void SerialReader::parseFromBuffer()
{
    auto numCmds = mReceiveBuffer.getSize();

    for( int i=0; i<numCmds; i++) {
        std::vector<std::string> cmdArgs;
        mReceiveBuffer.popBack( &cmdArgs );

        std::string cmd = cmdArgs[0];
        std::string args = (cmdArgs.size() > 1) ? cmdArgs[1] : "";

        if(cmd == ""){
            return;
        }
        // ------------------------------------------------------------------------------
        // KIOSK MODE
        if(cmd == "G"){
            if(mStateManager->getCurrentRaceState() == RACE_STATE::RACE_STOPPED){
                mStateManager->changeRaceState( RACE_STATE::RACE_STARTING );
            }
        }else if(cmd == "S"){
            mStateManager->changeRaceState( RACE_STATE::RACE_STOPPED );
        }

        // ------------------------------------------------------------------------------
        // RACE FINISH (ars are the time the race finished in millis)
        else if(cmd == "0F"){
            CI_LOG_I("RACER 1 FINISHED " + args);
            mStateManager->signalRacerFinish.emit(0, fromString<int>(args), Model::instance().playerData[0]->getCurrentRaceTicks());
            if( isRaceFinished() ){ mStateManager->signalOnRaceFinished.emit(); }
        }
        else if( cmd == "1F"){
            CI_LOG_I("RACER 2 FINISHED " +args);
            mStateManager->signalRacerFinish.emit(1, fromString<int>(args), Model::instance().playerData[1]->getCurrentRaceTicks());
            if( isRaceFinished() ){ mStateManager->signalOnRaceFinished.emit(); }
        }
        else if( cmd == "2F"){
            CI_LOG_I("RACER 3 FINISHED " + args);
            mStateManager->signalRacerFinish.emit(2, fromString<int>(args), Model::instance().playerData[2]->getCurrentRaceTicks());
            if( isRaceFinished() ){ mStateManager->signalOnRaceFinished.emit(); }
        }
        else if( cmd == "3F"){
            CI_LOG_I("RACER 4 FINISHED " + args);
            mStateManager->signalRacerFinish.emit(3, fromString<int>(args), Model::instance().playerData[3]->getCurrentRaceTicks());
            if( isRaceFinished() ){ mStateManager->signalOnRaceFinished.emit(); }
        }

        // ------------------------------------------------------------------------------
        // RACE PROGRESS (args are race ticks, then race time millis)
        else if(cmd == "R"){
            std::vector<std::string> rdata;
            boost::split(rdata, args, boost::is_any_of(","));

            int raceMillis = fromString<int>( rdata.back() );

            float dt = raceMillis - Model::instance().elapsedRaceTimeMillis;

            for( int i=0; i<rdata.size()-1; i++){
                Model::instance().playerData[i]->updateRaceTicks( fromString<int>(rdata[i]), dt );
            }
//            Model::instance().playerData[0]->updateRaceTicks( fromString<int>(rdata[0]), dt );
//            Model::instance().playerData[1]->updateRaceTicks( fromString<int>(rdata[1]), dt );
//            Model::instance().playerData[2]->updateRaceTicks( fromString<int>(rdata[2]), dt );
//            Model::instance().playerData[3]->updateRaceTicks( fromString<int>(rdata[3]), dt );
            Model::instance().elapsedRaceTimeMillis = raceMillis;
            Model::instance().startTimeMillis = ci::app::getElapsedSeconds() * 1000.0 - Model::instance().elapsedRaceTimeMillis;
        }

        // ------------------------------------------------------------------------------
        // SETTINGS
        else if( cmd == "CD"){
            CI_LOG_I("SerialReader :: Countdown :: " + args);

            if( args == "3" ){
                mStateManager->changeRaceState( RACE_STATE::RACE_COUNTDOWN_3 );
            }else if( args == "2"){
                mStateManager->changeRaceState( RACE_STATE::RACE_COUNTDOWN_2 );
            }else if( args == "1"){
                mStateManager->changeRaceState( RACE_STATE::RACE_COUNTDOWN_1 );
            }else if( args == "0" ){
                Model::instance().startTimeMillis = ci::app::getElapsedSeconds() * 1000.0;

                mStateManager->changeRaceState( RACE_STATE::RACE_COUNTDOWN_GO );
                mStateManager->changeRaceState( RACE_STATE::RACE_RUNNING );
            }
        }
        else if( cmd == "FS"){
            CI_LOG_I("SerialReader :: False start. Racer: " + args);    // 0 based
//            mStateManager->changeRaceState( RACE_STATE::RACE_FALSE_START );
//            mStateManager->changeRaceState( RACE_STATE::RACE_STOPPED );
        }
        else if( cmd == "L"){   // After sending a race length, it will send this confirmation
            CI_LOG_I("SerialReader :: Race Length " + args + ".");
        }
        else if( cmd == "M"){   // Mock mode confirmation
            CI_LOG_I("SerialReader :: Mock mode turned " + args);
        }
        else if(cmd == "V"){   // version
            mFirmwareVersion = args;
            Model::instance().mFirmwareVersion = args;
        }

        else{
            CI_LOG_I("SerialReader :: Unrecognized command :: ");
			try {
				CI_LOG_I(cmd);
			}catch (...) {}

            if(args != ""){
				try {
					CI_LOG_I(" with arg :: '" + args + "'");
				}catch (...) {}
            }
        }
    }
}

void SerialReader::onConnect()
{
    CI_LOG_I("OpenSprints hardware connected.");
    Model::instance().setHardwareConnected(bSerialConnected);
    Model::instance().mFirmwareVersion = "Unknown";
}

void SerialReader::onDisconnect()
{
    CI_LOG_I("OpenSprints hardware disconnected.");
    Model::instance().setHardwareConnected(bSerialConnected);
}

void SerialReader::startRace(){
    sendSerialMessage("g");
}

void SerialReader::stopRace(){
    sendSerialMessage("s");
}

void SerialReader::setRaceDuration(int numSeconds){
    sendSerialMessage("t" + to_string(numSeconds) );
}

void SerialReader::setRaceLengthTicks( int numTicks ){
    sendSerialMessage( "l"+to_string(numTicks) );
}

void SerialReader::setMockMode( bool enabled ){
    bMockEnabled = enabled;
    sendSerialMessage("m");
}

void SerialReader::getVersion(){
    sendSerialMessage("v");
}

void SerialReader::setRaceType( gfx::RACE_TYPE raceType)
{
    if(raceType == RACE_TYPE_DISTANCE){
        sendSerialMessage("d");
    }else{
        sendSerialMessage("x");
    }
}

void SerialReader::sendSerialMessage( std::string msg )
{
    std::string toSend = msg + "\n";
    mSendBuffer.pushFront( toSend );
}

bool SerialReader::isRaceFinished()
{
    for( int i=0; i<Model::instance().getNumRacers(); i++){
        if( !Model::instance().playerData[i]->isFinished() ){
            return false;
        }
    }

    return true;
}

<commit_msg>Fixed a bug where error reporting was crashing<commit_after>//
//  SerialReader.cpp
//  GoldsprintsFX
//
//  Created by Charlie Whitney on 8/28/14.
//
//

#include "data/SerialReader.h"

using namespace ci;
using namespace ci::app;
using namespace std;
using namespace gfx;
using namespace Cinder::Serial;

SerialReader::SerialReader() :
    BAUD_RATE(115200),
    mStringBuffer(""),
    mHardwareVersion(""),
    mProtoculVersion(""),
    mFirmwareVersion(""),
    mSerial(NULL),
    mReceiveBuffer(100),
    mSendBuffer(100)
{

}

SerialReader::~SerialReader()
{
    stopRace();
    bThreadShouldQuit = true;
    mSerialThread->join();
}

void SerialReader::setup()
{
    mStateManager = StateManager::getInstance();

    mSerialThread = std::shared_ptr<std::thread>( new std::thread( std::bind(&SerialReader::updateSerialThread, this) ) );
}

void SerialReader::update()
{
    // if we connected since the last update, notify
    if( bSerialConnected && !bLastConnection){
		mSerial->flush();
        onConnect();
        timeline().add( [&](){ getVersion(); }, timeline().getCurrentTime() + 2.0 );
    }else if( !bSerialConnected && bLastConnection ){
        onDisconnect();
    }
    bLastConnection = bSerialConnected;

    // parse buffered data
    parseFromBuffer();
}

void SerialReader::updateSerialThread()
{
    ThreadSetup threadSetup;

    while( !bThreadShouldQuit ){
        std::lock_guard<std::mutex> guard(mSerialMutex);

        if(!bSerialConnected ){ // we aren't connected try to connect
			auto ports = SerialPort::getPorts(true);
            /*
			for (auto port : ports) {
				console() << "SERIAL DEVICE" << endl;
				console() << "\tNAME: " << port->getName() << endl;
				console() << "\tDESCRIPTION: " << port->getDescription() << endl;
				console() << "\tHARDWARE IDENTIFIER: " << port->getHardwareIdentifier() << endl;
			}
             */
			try {
				if (!ports.empty()) {
					SerialPortRef port = SerialPort::findPortByDescriptionMatching(std::regex("Arduino.*"), true);
					if (!port) {
						port = ports.back();
					}

					mSerial = SerialDevice::create(port, BAUD_RATE);
					mSerial->flush();
					bSerialConnected = true;

					for (int i = 0; i < mSendBuffer.getSize(); i++) {        // clear send buffer
						std::string tmp;
						mSendBuffer.popBack(&tmp);
					}
					stopRace();

					for (int i = 0; i < mReceiveBuffer.getSize(); i++) {    // clear receive buffer
						std::vector<std::string> tmp;
						mReceiveBuffer.popBack(&tmp);
					}
					CI_LOG_I("OpenSprints hardware found successfully. :: ") << mSerial->getPortName();
				}
			}catch (serial::IOException& e) {
				if (mSerial && mSerial->isOpen()) {
					mSerial->close();
				}
                bSerialConnected = false;
            }
        }else{
            // make sure we're still connected
			auto pOpen = SerialPort::findPortByDescriptionMatching(std::regex("Arduino.*"), true);

            if(pOpen == nullptr){
				if (mSerial && mSerial->isOpen()) {
					mSerial->close();
				}
                bSerialConnected = false;
            }else{
				// send to arduino
                for(int i=0; i<mSendBuffer.getSize(); i++){
                    std::string msgToSend;
                    mSendBuffer.popBack( &msgToSend );

					CI_LOG_I("Sending :: ") << msgToSend;

                    mSerial->writeString( msgToSend );
                }

                // receive from arduino
                readSerial();
            }
        }
    }
}

void SerialReader::readSerial()
{
    try {
		size_t bytesAvailable = mSerial->getNumBytesAvailable();
		size_t charsAvailable = floor(bytesAvailable / sizeof(char));

        for(int i=0; i<charsAvailable; i++){
			unsigned char c;	// uint8_t
			mSerial->readBytes(&c, 1);
            mStringBuffer += c;
        }
    }catch(serial::IOException& e){
        bSerialConnected = false;
		if (mSerial && mSerial->isOpen()) {
			mSerial->close();
			//mSerial = nullptr;
		}
    }

    auto index = mStringBuffer.find("\r\n");
    if(index != string::npos){
        std::string cmd = mStringBuffer.substr(0, index);
        mStringBuffer.replace(0, index+2, "");      // The newline is 2 bytes (\r\n) so add two to remove it

        parseCommandToBuffer( cmd );
    }
}

void SerialReader::parseCommandToBuffer( std::string command )
{
    std::vector<std::string> strs;
    boost::split(strs, command, boost::is_any_of(":"));

    std::vector<std::string> tmpBuffer;
    tmpBuffer.push_back( strs[0] );

    std::string args = "";
    if( strs.size() > 1){
        tmpBuffer.push_back(strs[1]);
    }

    mReceiveBuffer.tryPushFront(tmpBuffer);
}

// Parse commands in the main thread that we grabbed during the updateSerial thread
void SerialReader::parseFromBuffer()
{
    auto numCmds = mReceiveBuffer.getSize();

    for( int i=0; i<numCmds; i++) {
        std::vector<std::string> cmdArgs;
        mReceiveBuffer.popBack( &cmdArgs );

        std::string cmd = cmdArgs[0];
        std::string args = (cmdArgs.size() > 1) ? cmdArgs[1] : "";

        if(cmd == ""){
            return;
        }
        // ------------------------------------------------------------------------------
        // KIOSK MODE
        if(cmd == "G"){
            if(mStateManager->getCurrentRaceState() == RACE_STATE::RACE_STOPPED){
                mStateManager->changeRaceState( RACE_STATE::RACE_STARTING );
            }
        }else if(cmd == "S"){
            mStateManager->changeRaceState( RACE_STATE::RACE_STOPPED );
        }

        // ------------------------------------------------------------------------------
        // RACE FINISH (ars are the time the race finished in millis)
        else if(cmd == "0F"){
            CI_LOG_I("RACER 1 FINISHED " + args);
            mStateManager->signalRacerFinish.emit(0, fromString<int>(args), Model::instance().playerData[0]->getCurrentRaceTicks());
            if( isRaceFinished() ){ mStateManager->signalOnRaceFinished.emit(); }
        }
        else if( cmd == "1F"){
            CI_LOG_I("RACER 2 FINISHED " +args);
            mStateManager->signalRacerFinish.emit(1, fromString<int>(args), Model::instance().playerData[1]->getCurrentRaceTicks());
            if( isRaceFinished() ){ mStateManager->signalOnRaceFinished.emit(); }
        }
        else if( cmd == "2F"){
            CI_LOG_I("RACER 3 FINISHED " + args);
            mStateManager->signalRacerFinish.emit(2, fromString<int>(args), Model::instance().playerData[2]->getCurrentRaceTicks());
            if( isRaceFinished() ){ mStateManager->signalOnRaceFinished.emit(); }
        }
        else if( cmd == "3F"){
            CI_LOG_I("RACER 4 FINISHED " + args);
            mStateManager->signalRacerFinish.emit(3, fromString<int>(args), Model::instance().playerData[3]->getCurrentRaceTicks());
            if( isRaceFinished() ){ mStateManager->signalOnRaceFinished.emit(); }
        }

        // ------------------------------------------------------------------------------
        // RACE PROGRESS (args are race ticks, then race time millis)
        else if(cmd == "R"){
            std::vector<std::string> rdata;
            boost::split(rdata, args, boost::is_any_of(","));

            int raceMillis = fromString<int>( rdata.back() );

            float dt = raceMillis - Model::instance().elapsedRaceTimeMillis;

            for( int i=0; i<rdata.size()-1; i++){
                Model::instance().playerData[i]->updateRaceTicks( fromString<int>(rdata[i]), dt );
            }
//            Model::instance().playerData[0]->updateRaceTicks( fromString<int>(rdata[0]), dt );
//            Model::instance().playerData[1]->updateRaceTicks( fromString<int>(rdata[1]), dt );
//            Model::instance().playerData[2]->updateRaceTicks( fromString<int>(rdata[2]), dt );
//            Model::instance().playerData[3]->updateRaceTicks( fromString<int>(rdata[3]), dt );
            Model::instance().elapsedRaceTimeMillis = raceMillis;
            Model::instance().startTimeMillis = ci::app::getElapsedSeconds() * 1000.0 - Model::instance().elapsedRaceTimeMillis;
        }

        // ------------------------------------------------------------------------------
        // SETTINGS
        else if( cmd == "CD"){
            CI_LOG_I("SerialReader :: Countdown :: " + args);

            if( args == "3" ){
                mStateManager->changeRaceState( RACE_STATE::RACE_COUNTDOWN_3 );
            }else if( args == "2"){
                mStateManager->changeRaceState( RACE_STATE::RACE_COUNTDOWN_2 );
            }else if( args == "1"){
                mStateManager->changeRaceState( RACE_STATE::RACE_COUNTDOWN_1 );
            }else if( args == "0" ){
                Model::instance().startTimeMillis = ci::app::getElapsedSeconds() * 1000.0;

                mStateManager->changeRaceState( RACE_STATE::RACE_COUNTDOWN_GO );
                mStateManager->changeRaceState( RACE_STATE::RACE_RUNNING );
            }
        }
        else if( cmd == "FS"){
            CI_LOG_I("SerialReader :: False start. Racer: " + args);    // 0 based
//            mStateManager->changeRaceState( RACE_STATE::RACE_FALSE_START );
//            mStateManager->changeRaceState( RACE_STATE::RACE_STOPPED );
        }
        else if( cmd == "L"){   // After sending a race length, it will send this confirmation
            CI_LOG_I("SerialReader :: Race Length " + args + ".");
        }
        else if( cmd == "M"){   // Mock mode confirmation
            CI_LOG_I("SerialReader :: Mock mode turned " + args);
        }
        else if(cmd == "V"){   // version
            mFirmwareVersion = args;
            Model::instance().mFirmwareVersion = args;
        }

        else{
            CI_LOG_I("SerialReader :: Unrecognized command :: ");
			/*
			try {
				CI_LOG_I(cmd);
			}catch (std::exception exc) {
				CI_LOG_EXCEPTION("Error parsing arduino", exc);
			}

            if(args != ""){
				try {
					CI_LOG_I(" with arg :: '" + args + "'");
				}catch (std::exception exc) {
					CI_LOG_EXCEPTION("Error parsing arduino", exc);
				}
            }
			*/
        }
    }
}

void SerialReader::onConnect()
{
    CI_LOG_I("OpenSprints hardware connected.");
    Model::instance().setHardwareConnected(bSerialConnected);
    Model::instance().mFirmwareVersion = "Unknown";
}

void SerialReader::onDisconnect()
{
    CI_LOG_I("OpenSprints hardware disconnected.");
    Model::instance().setHardwareConnected(bSerialConnected);
}

void SerialReader::startRace(){
    sendSerialMessage("g");
}

void SerialReader::stopRace(){
    sendSerialMessage("s");
}

void SerialReader::setRaceDuration(int numSeconds){
    sendSerialMessage("t" + to_string(numSeconds) );
}

void SerialReader::setRaceLengthTicks( int numTicks ){
    sendSerialMessage( "l"+to_string(numTicks) );
}

void SerialReader::setMockMode( bool enabled ){
    bMockEnabled = enabled;
    sendSerialMessage("m");
}

void SerialReader::getVersion(){
    sendSerialMessage("v");
}

void SerialReader::setRaceType( gfx::RACE_TYPE raceType)
{
    if(raceType == RACE_TYPE_DISTANCE){
        sendSerialMessage("d");
    }else{
        sendSerialMessage("x");
    }
}

void SerialReader::sendSerialMessage( std::string msg )
{
    std::string toSend = msg + "\n";
    mSendBuffer.pushFront( toSend );
}

bool SerialReader::isRaceFinished()
{
    for( int i=0; i<Model::instance().getNumRacers(); i++){
        if( !Model::instance().playerData[i]->isFinished() ){
            return false;
        }
    }

    return true;
}

<|endoftext|>


<commit_before>#include "Halide.h"
using namespace Halide;

Var x, y;

// Downsample with a 1 3 3 1 filter
Func downsample(Func f) {
    Func downx, downy;

    downx(x, y, _) = (f(2*x-1, y, _) + 3.0f * (f(2*x, y, _) + f(2*x+1, y, _)) + f(2*x+2, y, _)) / 8.0f;
    downy(x, y, _) = (downx(x, 2*y-1, _) + 3.0f * (downx(x, 2*y, _) + downx(x, 2*y+1, _)) + downx(x, 2*y+2, _)) / 8.0f;

    return downy;
}

// Upsample using bilinear interpolation
Func upsample(Func f) {
    Func upx, upy;

    upx(x, y, _) = 0.25f * f((x/2) - 1 + 2*(x % 2), y, _) + 0.75f * f(x/2, y, _);
    upy(x, y, _) = 0.25f * upx(x, (y/2) - 1 + 2*(y % 2), _) + 0.75f * upx(x, y/2, _);

    return upy;

}

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

    /* THE ALGORITHM */

    // Number of pyramid levels
    const int J = 8;

    // number of intensity levels
    Param<int> levels;
    // Parameters controlling the filter
    Param<float> alpha, beta;
    // Takes a 16-bit input
    ImageParam input(UInt(16), 3);

    // loop variables
    Var c, k;

    // Make the remapping function as a lookup table.
    Func remap;
    Expr fx = cast<float>(x) / 256.0f;
    remap(x) = alpha*fx*exp(-fx*fx/2.0f);

    // Set a boundary condition
    Func clamped = BoundaryConditions::repeat_edge(input);

    // Convert to floating point
    Func floating;
    floating(x, y, c) = clamped(x, y, c) / 65535.0f;

    // Get the luminance channel
    Func gray;
    gray(x, y) = 0.299f * floating(x, y, 0) + 0.587f * floating(x, y, 1) + 0.114f * floating(x, y, 2);

    // Make the processed Gaussian pyramid.
    Func gPyramid[J];
    // Do a lookup into a lut with 256 entires per intensity level
    Expr level = k * (1.0f / (levels - 1));
    Expr idx = gray(x, y)*cast<float>(levels-1)*256.0f;
    idx = clamp(cast<int>(idx), 0, (levels-1)*256);
    gPyramid[0](x, y, k) = beta*(gray(x, y) - level) + level + remap(idx - 256*k);
    for (int j = 1; j < J; j++) {
        gPyramid[j](x, y, k) = downsample(gPyramid[j-1])(x, y, k);
    }

    // Get its laplacian pyramid
    Func lPyramid[J];
    lPyramid[J-1](x, y, k) = gPyramid[J-1](x, y, k);
    for (int j = J-2; j >= 0; j--) {
        lPyramid[j](x, y, k) = gPyramid[j](x, y, k) - upsample(gPyramid[j+1])(x, y, k);
    }

    // Make the Gaussian pyramid of the input
    Func inGPyramid[J];
    inGPyramid[0](x, y) = gray(x, y);
    for (int j = 1; j < J; j++) {
        inGPyramid[j](x, y) = downsample(inGPyramid[j-1])(x, y);
    }

    // Make the laplacian pyramid of the output
    Func outLPyramid[J];
    for (int j = 0; j < J; j++) {
        // Split input pyramid value into integer and floating parts
        Expr level = inGPyramid[j](x, y) * cast<float>(levels-1);
        Expr li = clamp(cast<int>(level), 0, levels-2);
        Expr lf = level - cast<float>(li);
        // Linearly interpolate between the nearest processed pyramid levels
        outLPyramid[j](x, y) = (1.0f - lf) * lPyramid[j](x, y, li) + lf * lPyramid[j](x, y, li+1);
    }

    // Make the Gaussian pyramid of the output
    Func outGPyramid[J];
    outGPyramid[J-1](x, y) = outLPyramid[J-1](x, y);
    for (int j = J-2; j >= 0; j--) {
        outGPyramid[j](x, y) = upsample(outGPyramid[j+1])(x, y) + outLPyramid[j](x, y);
    }

    // Reintroduce color (Connelly: use eps to avoid scaling up noise w/ apollo3.png input)
    Func color;
    float eps = 0.01f;
    color(x, y, c) = outGPyramid[0](x, y) * (floating(x, y, c)+eps) / (gray(x, y)+eps);

    Func output("local_laplacian");
    // Convert back to 16-bit
    output(x, y, c) = cast<uint16_t>(clamp(color(x, y, c), 0.0f, 1.0f) * 65535.0f);

    /* THE SCHEDULE */
    remap.compute_root();

    Target target = get_target_from_environment();
    if (target.has_gpu_feature()) {
        // gpu schedule
        output.compute_root().gpu_tile(x, y, 16, 8, DeviceAPI::Default_GPU);
        for (int j = 0; j < J; j++) {
            int blockw = 16, blockh = 8;
            if (j > 3) {
                blockw = 2;
                blockh = 2;
            }
            if (j > 0) inGPyramid[j].compute_root().gpu_tile(x, y, blockw, blockh, DeviceAPI::Default_GPU);
            if (j > 0) gPyramid[j].compute_root().reorder(k, x, y).gpu_tile(x, y, blockw, blockh, DeviceAPI::Default_GPU);
            outGPyramid[j].compute_root().gpu_tile(x, y, blockw, blockh, DeviceAPI::Default_GPU);
        }
    } else {
        // cpu schedule
        Var yi;
        output.parallel(y, 4).vectorize(x, 8);
        gray.compute_root().parallel(y, 4).vectorize(x, 8);
        for (int j = 0; j < 4; j++) {
            if (j > 0) inGPyramid[j].compute_root().parallel(y, 4).vectorize(x, 8);
            if (j > 0) gPyramid[j].compute_root().parallel(y, 4).vectorize(x, 8);
            outGPyramid[j].compute_root().parallel(y, 4).vectorize(x, 8);
        }
        for (int j = 4; j < J; j++) {
            inGPyramid[j].compute_root().parallel(y);
            gPyramid[j].compute_root().parallel(k);
            outGPyramid[j].compute_root().parallel(y);
        }
    }

    output.compile_to_file("local_laplacian", {levels, alpha, beta, input}, target);
    output.compile_to_assembly("local_laplacian.s", {levels, alpha, beta, input}, target);

    return 0;
}
<commit_msg>Remove accidental change<commit_after>#include "Halide.h"
using namespace Halide;

Var x, y;

// Downsample with a 1 3 3 1 filter
Func downsample(Func f) {
    Func downx, downy;

    downx(x, y, _) = (f(2*x-1, y, _) + 3.0f * (f(2*x, y, _) + f(2*x+1, y, _)) + f(2*x+2, y, _)) / 8.0f;
    downy(x, y, _) = (downx(x, 2*y-1, _) + 3.0f * (downx(x, 2*y, _) + downx(x, 2*y+1, _)) + downx(x, 2*y+2, _)) / 8.0f;

    return downy;
}

// Upsample using bilinear interpolation
Func upsample(Func f) {
    Func upx, upy;

    upx(x, y, _) = 0.25f * f((x/2) - 1 + 2*(x % 2), y, _) + 0.75f * f(x/2, y, _);
    upy(x, y, _) = 0.25f * upx(x, (y/2) - 1 + 2*(y % 2), _) + 0.75f * upx(x, y/2, _);

    return upy;

}

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

    /* THE ALGORITHM */

    // Number of pyramid levels
    const int J = 8;

    // number of intensity levels
    Param<int> levels;
    // Parameters controlling the filter
    Param<float> alpha, beta;
    // Takes a 16-bit input
    ImageParam input(UInt(16), 3);

    // loop variables
    Var c, k;

    // Make the remapping function as a lookup table.
    Func remap;
    Expr fx = cast<float>(x) / 256.0f;
    remap(x) = alpha*fx*exp(-fx*fx/2.0f);

    // Set a boundary condition
    Func clamped = BoundaryConditions::repeat_edge(input);

    // Convert to floating point
    Func floating;
    floating(x, y, c) = clamped(x, y, c) / 65535.0f;

    // Get the luminance channel
    Func gray;
    gray(x, y) = 0.299f * floating(x, y, 0) + 0.587f * floating(x, y, 1) + 0.114f * floating(x, y, 2);

    // Make the processed Gaussian pyramid.
    Func gPyramid[J];
    // Do a lookup into a lut with 256 entires per intensity level
    Expr level = k * (1.0f / (levels - 1));
    Expr idx = gray(x, y)*cast<float>(levels-1)*256.0f;
    idx = clamp(cast<int>(idx), 0, (levels-1)*256);
    gPyramid[0](x, y, k) = beta*(gray(x, y) - level) + level + remap(idx - 256*k);
    for (int j = 1; j < J; j++) {
        gPyramid[j](x, y, k) = downsample(gPyramid[j-1])(x, y, k);
    }

    // Get its laplacian pyramid
    Func lPyramid[J];
    lPyramid[J-1](x, y, k) = gPyramid[J-1](x, y, k);
    for (int j = J-2; j >= 0; j--) {
        lPyramid[j](x, y, k) = gPyramid[j](x, y, k) - upsample(gPyramid[j+1])(x, y, k);
    }

    // Make the Gaussian pyramid of the input
    Func inGPyramid[J];
    inGPyramid[0](x, y) = gray(x, y);
    for (int j = 1; j < J; j++) {
        inGPyramid[j](x, y) = downsample(inGPyramid[j-1])(x, y);
    }

    // Make the laplacian pyramid of the output
    Func outLPyramid[J];
    for (int j = 0; j < J; j++) {
        // Split input pyramid value into integer and floating parts
        Expr level = inGPyramid[j](x, y) * cast<float>(levels-1);
        Expr li = clamp(cast<int>(level), 0, levels-2);
        Expr lf = level - cast<float>(li);
        // Linearly interpolate between the nearest processed pyramid levels
        outLPyramid[j](x, y) = (1.0f - lf) * lPyramid[j](x, y, li) + lf * lPyramid[j](x, y, li+1);
    }

    // Make the Gaussian pyramid of the output
    Func outGPyramid[J];
    outGPyramid[J-1](x, y) = outLPyramid[J-1](x, y);
    for (int j = J-2; j >= 0; j--) {
        outGPyramid[j](x, y) = upsample(outGPyramid[j+1])(x, y) + outLPyramid[j](x, y);
    }

    // Reintroduce color (Connelly: use eps to avoid scaling up noise w/ apollo3.png input)
    Func color;
    float eps = 0.01f;
    color(x, y, c) = outGPyramid[0](x, y) * (floating(x, y, c)+eps) / (gray(x, y)+eps);

    Func output("local_laplacian");
    // Convert back to 16-bit
    output(x, y, c) = cast<uint16_t>(clamp(color(x, y, c), 0.0f, 1.0f) * 65535.0f);

    /* THE SCHEDULE */
    remap.compute_root();

    Target target = get_target_from_environment();
    if (target.has_gpu_feature()) {
        // gpu schedule
        output.compute_root().gpu_tile(x, y, 16, 8, DeviceAPI::Default_GPU);
        for (int j = 0; j < J; j++) {
            int blockw = 16, blockh = 8;
            if (j > 3) {
                blockw = 2;
                blockh = 2;
            }
            if (j > 0) inGPyramid[j].compute_root().gpu_tile(x, y, blockw, blockh, DeviceAPI::Default_GPU);
            if (j > 0) gPyramid[j].compute_root().reorder(k, x, y).gpu_tile(x, y, blockw, blockh, DeviceAPI::Default_GPU);
            outGPyramid[j].compute_root().gpu_tile(x, y, blockw, blockh, DeviceAPI::Default_GPU);
        }
    } else {
        // cpu schedule
        Var yi;
        output.parallel(y, 4).vectorize(x, 8);
        gray.compute_root().parallel(y, 4).vectorize(x, 8);
        for (int j = 0; j < 4; j++) {
            if (j > 0) inGPyramid[j].compute_root().parallel(y, 4).vectorize(x, 8);
            if (j > 0) gPyramid[j].compute_root().parallel(y, 4).vectorize(x, 8);
            outGPyramid[j].compute_root().parallel(y, 4).vectorize(x, 8);
        }
        for (int j = 4; j < J; j++) {
            inGPyramid[j].compute_root().parallel(y);
            gPyramid[j].compute_root().parallel(k);
            outGPyramid[j].compute_root().parallel(y);
        }
    }

    output.compile_to_file("local_laplacian", {levels, alpha, beta, input}, target);

    return 0;
}
<|endoftext|>


<commit_before>/*
   Project: SC4Fix Patches for SimCity 4
   File: TitleBarMod.cpp

   Copyright (c) 2015 Nelson Gomez (simmaster07)

   Licensed under the MIT License. A copy of the License is available in
   LICENSE or at:

       http://opensource.org/licenses/MIT

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
*/

#include "TitleBarMod.h"
#include <string>

// This is restricted to 15 characters + the null terminator
std::string szCaption("SC4Fix pre3");

void __declspec(naked) TitleBarMod::Hook_Sub44C2B0(void) {
	_asm mov edx, offset szCaption
	RETJMP(44C99Ch);
}

void __declspec(naked) TitleBarMod::Hook_Steam_Sub44C2B0(void) {
	_asm mov ecx, offset szCaption
	RETJMP(44CA80h)
}

void TitleBarMod::InstallPatch(void) {
	switch (GetGameVersion()) {
	case 640:
		CPatcher::InstallHook(0x44C996, Hook_Sub44C2B0);
		break;

	case 641:
		CPatcher::InstallHook(0x44CA7A, Hook_Steam_Sub44C2B0);
		break;

	default:
		break;
	}
}<commit_msg>Bump version number<commit_after>/*
   Project: SC4Fix Patches for SimCity 4
   File: TitleBarMod.cpp

   Copyright (c) 2015 Nelson Gomez (simmaster07)

   Licensed under the MIT License. A copy of the License is available in
   LICENSE or at:

       http://opensource.org/licenses/MIT

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
*/

#include "TitleBarMod.h"
#include <string>

// This is restricted to 15 characters + the null terminator
std::string szCaption("SC4Fix r4");

void __declspec(naked) TitleBarMod::Hook_Sub44C2B0(void) {
	_asm mov edx, offset szCaption
	RETJMP(44C99Ch);
}

void __declspec(naked) TitleBarMod::Hook_Steam_Sub44C2B0(void) {
	_asm mov ecx, offset szCaption
	RETJMP(44CA80h)
}

void TitleBarMod::InstallPatch(void) {
	switch (GetGameVersion()) {
	case 640:
		CPatcher::InstallHook(0x44C996, Hook_Sub44C2B0);
		break;

	case 641:
		CPatcher::InstallHook(0x44CA7A, Hook_Steam_Sub44C2B0);
		break;

	default:
		break;
	}
}<|endoftext|>