<commit_before>#/*##########################################################################
#
# The fisx library for X-Ray Fluorescence
#
# Copyright (c) 2014-2016 European Synchrotron Radiation Facility
#
# This file is part of the fisx X-ray developed by V.A. Sole
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#############################################################################*/
#include "fisx_xrf.h"
#include "fisx_math.h"
#include "fisx_simpleini.h"
#include <cmath>
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <iomanip>

namespace fisx
{

XRF::XRF()
{
    // initialize geometry with default parameters
    this->configuration = XRFConfig();
    this->setGeometry(45., 45.);
    //this->elements = NULL;
};

XRF::XRF(const std::string & fileName)
{
    this->readConfigurationFromFile(fileName);
    //this->elements = NULL;
}

void XRF::readConfigurationFromFile(const std::string & fileName)
{
    this->recentBeam = true;
    this->configuration.readConfigurationFromFile(fileName);
}

void XRF::setGeometry(const double & alphaIn, const double & alphaOut, const double & scatteringAngle)
{
    this->recentBeam = true;
    if (scatteringAngle < 0.0)
    {
        this->configuration.setGeometry(alphaIn, alphaOut, alphaIn + alphaOut);
    }
    else
    {
        this->configuration.setGeometry(alphaIn, alphaOut, scatteringAngle);
    }
}

void XRF::setBeam(const Beam & beam)
{
    this->recentBeam = true;
    this->configuration.setBeam(beam);
}

void XRF::setBeam(const double & energy, const double & divergency)
{
    this->recentBeam = true;
    this->configuration.setBeam(energy, divergency);
}

void XRF::setBeam(const std::vector<double> & energies, \
                 const std::vector<double> & weight, \
                 const std::vector<int> & characteristic, \
                 const std::vector<double> & divergency)
{
    this->configuration.setBeam(energies, weight, characteristic, divergency);
}

void XRF::setBeamFilters(const std::vector<Layer> &layers)
{
    this->recentBeam = true;
    this->configuration.setBeamFilters(layers);
}

void XRF::setSample(const std::vector<Layer> & layers, const int & referenceLayer)
{
    this->configuration.setSample(layers, referenceLayer);
}

void XRF::setSample(const std::string & name, \
                   const double & density, \
                   const double & thickness)
{
    std::vector<Layer> vLayer;
    vLayer.push_back(Layer(name, density, thickness, 1.0));
    this->configuration.setSample(vLayer, 0);
}

void XRF::setSample(const Layer & layer)
{
    std::vector<Layer> vLayer;
    vLayer.push_back(layer);
    this->configuration.setSample(vLayer, 0);
}

void XRF::setAttenuators(const std::vector<Layer> & attenuators)
{
    this->configuration.setAttenuators(attenuators);
}

void XRF::setDetector(const Detector & detector)
{
    this->configuration.setDetector(detector);
}

double XRF::getGeometricEfficiency(const int & sampleLayerIndex) const
{
    const Detector & detector = this->configuration.getDetector();
    const double PI = acos(-1.0);
    const double & sinAlphaOut = sin(this->configuration.getAlphaOut()*(PI/180.));
    const double & detectorDistance = detector.getDistance();
    const double & detectorDiameter = detector.getDiameter();
    double distance;
    const std::vector<Layer> & sample = this->configuration.getSample();
    std::vector<Layer>::size_type iLayer;
    const int & referenceLayerIndex = this->configuration.getReferenceLayer();
    const Layer* layerPtr;

    // if the detector diameter is zero, return 1
    if (detectorDiameter == 0.0)
    {
        return 1.0;
    }
    distance = detectorDistance;
    if ((distance == 0.0) && (sampleLayerIndex == 0))
    {
        return 0.5;
    }
    if (sampleLayerIndex < 0)
    {
        std::cout << "Negative sample layer index in getGeometricEfficiency " << sampleLayerIndex << std::endl;
        throw std::invalid_argument("Negative sample layer index in getGeometricEfficiency");
    }
    if (sampleLayerIndex != referenceLayerIndex)
    {
        if (sampleLayerIndex > referenceLayerIndex)
        {
            for (iLayer = (std::vector<Layer>::size_type) referenceLayerIndex; iLayer < (std::vector<Layer>::size_type) sampleLayerIndex; iLayer++)
            {
                layerPtr = &sample[iLayer];
                distance += (*layerPtr).getThickness() / sinAlphaOut;
            }
        }
        else
        {
            for (iLayer = (std::vector<Layer>::size_type) sampleLayerIndex; iLayer < (std::vector<Layer>::size_type) referenceLayerIndex; iLayer++)
            {
                layerPtr = &sample[iLayer];
                distance -= (*layerPtr).getThickness() / sinAlphaOut;
            }
        }
    }

    // we can calculate the geometric efficiency for the given layer
    // calculate geometric efficiency 0.5 * (1 - cos theta)
    return (0.5 * (1.0 - (distance / sqrt(pow(distance, 2) + pow(0.5 * detectorDiameter, 2)))));
}

std::map<std::string, std::map<int, std::map<std::string, std::map<std::string, double> > > > \
                XRF::getMultilayerFluorescence( \
                const std::string & elementName, \
                const Elements & elementsLibrary, const int & sampleLayerIndex, \
                const std::string & lineFamily, const int & secondary, \
                const int & useGeometricEfficiency, const int & useMassFractions, \
                const double & optimizationFactor )
{
    std::vector<std::string> elementList;
    std::vector<std::string> familyList;
    std::vector<int> layerList;
    std::vector<std::string>::size_type i;
    std::string tmpString;
    std::vector<std::string> tmpStringVector;

    elementList.push_back(elementName);

    if (lineFamily == "")
    {
        throw std::invalid_argument("Please specify K, L or M as peak family");
    }
    familyList.push_back(lineFamily);
    if (sampleLayerIndex < 0)
    {
        throw std::invalid_argument("Layer index cannot be negative");
    }
    layerList.push_back(sampleLayerIndex);
    return this->getMultilayerFluorescence(elementList, elementsLibrary, layerList, familyList, \
                                           secondary, useGeometricEfficiency, useMassFractions, \
                                           optimizationFactor);
}

double XRF::getEnergyThreshold(const std::string & elementName, const std::string & family, \
                                const Elements & elementsLibrary) const
{
    std::map<std::string, double> binding;
    binding = elementsLibrary.getBindingEnergies(elementName);
    if ((family == "K") || (family.size() == 2))
        return binding[family];

    if (family == "L")
    {
        if (binding["L3"] > 0)
            return binding["L3"];
        if (binding["L2"] > 0)
            return binding["L2"];
        return binding["L1"]; // It can be 0.0
    }

    if (family == "M")
    {
        if (binding["M5"] > 0)
            return binding["M5"];
        if (binding["M4"] > 0)
            return binding["M4"];
        if (binding["M3"] > 0)
            return binding["M3"];
        if (binding["M2"] > 0)
            return binding["M2"];
        return binding["M1"]; // It can be 0.0
    }
    return 0.0;
}

const XRFConfig & XRF::getConfiguration() const
{
    return this->configuration;

}

std::map<std::string, std::map<int, std::map<std::string, std::map<std::string, double> > > > \
                XRF::getMultilayerFluorescence(const std::vector<std::string> & elementFamilyLayer, \
                const Elements & elementsLibrary, const int & secondary, \
                const int & useGeometricEfficiency, const int & useMassFractions, \
                const double & secondaryCalculationLimit)
{
    std::vector<std::string> elementList;
    std::vector<std::string> familyList;
    std::vector<int> layerList;
    std::vector<std::string>::size_type i;
    int layerIndex;
    std::string tmpString;
    std::vector<std::string> tmpStringVector;

    elementList.resize(elementFamilyLayer.size());
    familyList.resize(elementFamilyLayer.size());
    layerList.resize(elementFamilyLayer.size());

    for(i = 0; i < elementFamilyLayer.size(); i++)
    {
        tmpString = "";
        SimpleIni::parseStringAsMultipleValues(elementFamilyLayer[i], tmpStringVector, tmpString, ' ');
        // We should have a key of the form "Cr", "Cr K", or "Cr K 0"
        if(tmpStringVector.size() == 3)
        {
            elementList[i] = tmpStringVector[0];
            familyList[i] = tmpStringVector[1];
            if (!SimpleIni::stringConverter(tmpStringVector[2], layerIndex))
            {
                tmpString = "Unsuccessul conversion to layer integer: " + tmpStringVector[2];
                std::cout << tmpString << std::endl;
                throw std::invalid_argument(tmpString);
            }
            layerList[i] = layerIndex;
        }
        if(tmpStringVector.size() == 2)
        {
            elementList[i] = tmpStringVector[0];
            familyList[i] = tmpStringVector[1];
            layerList[i] = -1;
        }
        if(tmpStringVector.size() == 1)
        {
            elementList[i] = tmpStringVector[0];
            familyList[i] = "";
            layerList[i] = -1;
        }
    }
    return this->getMultilayerFluorescence(elementList, elementsLibrary, \
                                           layerList, familyList, secondary, useGeometricEfficiency, \
                                           useMassFractions, secondaryCalculationLimit);
}

} // namespace fisx
<commit_msg>Remove unused variable.<commit_after>#/*##########################################################################
#
# The fisx library for X-Ray Fluorescence
#
# Copyright (c) 2014-2018 European Synchrotron Radiation Facility
#
# This file is part of the fisx X-ray developed by V.A. Sole
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#############################################################################*/
#include "fisx_xrf.h"
#include "fisx_math.h"
#include "fisx_simpleini.h"
#include <cmath>
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <iomanip>

namespace fisx
{

XRF::XRF()
{
    // initialize geometry with default parameters
    this->configuration = XRFConfig();
    this->setGeometry(45., 45.);
    //this->elements = NULL;
};

XRF::XRF(const std::string & fileName)
{
    this->readConfigurationFromFile(fileName);
    //this->elements = NULL;
}

void XRF::readConfigurationFromFile(const std::string & fileName)
{
    this->recentBeam = true;
    this->configuration.readConfigurationFromFile(fileName);
}

void XRF::setGeometry(const double & alphaIn, const double & alphaOut, const double & scatteringAngle)
{
    this->recentBeam = true;
    if (scatteringAngle < 0.0)
    {
        this->configuration.setGeometry(alphaIn, alphaOut, alphaIn + alphaOut);
    }
    else
    {
        this->configuration.setGeometry(alphaIn, alphaOut, scatteringAngle);
    }
}

void XRF::setBeam(const Beam & beam)
{
    this->recentBeam = true;
    this->configuration.setBeam(beam);
}

void XRF::setBeam(const double & energy, const double & divergency)
{
    this->recentBeam = true;
    this->configuration.setBeam(energy, divergency);
}

void XRF::setBeam(const std::vector<double> & energies, \
                 const std::vector<double> & weight, \
                 const std::vector<int> & characteristic, \
                 const std::vector<double> & divergency)
{
    this->configuration.setBeam(energies, weight, characteristic, divergency);
}

void XRF::setBeamFilters(const std::vector<Layer> &layers)
{
    this->recentBeam = true;
    this->configuration.setBeamFilters(layers);
}

void XRF::setSample(const std::vector<Layer> & layers, const int & referenceLayer)
{
    this->configuration.setSample(layers, referenceLayer);
}

void XRF::setSample(const std::string & name, \
                   const double & density, \
                   const double & thickness)
{
    std::vector<Layer> vLayer;
    vLayer.push_back(Layer(name, density, thickness, 1.0));
    this->configuration.setSample(vLayer, 0);
}

void XRF::setSample(const Layer & layer)
{
    std::vector<Layer> vLayer;
    vLayer.push_back(layer);
    this->configuration.setSample(vLayer, 0);
}

void XRF::setAttenuators(const std::vector<Layer> & attenuators)
{
    this->configuration.setAttenuators(attenuators);
}

void XRF::setDetector(const Detector & detector)
{
    this->configuration.setDetector(detector);
}

double XRF::getGeometricEfficiency(const int & sampleLayerIndex) const
{
    const Detector & detector = this->configuration.getDetector();
    const double PI = acos(-1.0);
    const double & sinAlphaOut = sin(this->configuration.getAlphaOut()*(PI/180.));
    const double & detectorDistance = detector.getDistance();
    const double & detectorDiameter = detector.getDiameter();
    double distance;
    const std::vector<Layer> & sample = this->configuration.getSample();
    std::vector<Layer>::size_type iLayer;
    const int & referenceLayerIndex = this->configuration.getReferenceLayer();
    const Layer* layerPtr;

    // if the detector diameter is zero, return 1
    if (detectorDiameter == 0.0)
    {
        return 1.0;
    }
    distance = detectorDistance;
    if ((distance == 0.0) && (sampleLayerIndex == 0))
    {
        return 0.5;
    }
    if (sampleLayerIndex < 0)
    {
        std::cout << "Negative sample layer index in getGeometricEfficiency " << sampleLayerIndex << std::endl;
        throw std::invalid_argument("Negative sample layer index in getGeometricEfficiency");
    }
    if (sampleLayerIndex != referenceLayerIndex)
    {
        if (sampleLayerIndex > referenceLayerIndex)
        {
            for (iLayer = (std::vector<Layer>::size_type) referenceLayerIndex; iLayer < (std::vector<Layer>::size_type) sampleLayerIndex; iLayer++)
            {
                layerPtr = &sample[iLayer];
                distance += (*layerPtr).getThickness() / sinAlphaOut;
            }
        }
        else
        {
            for (iLayer = (std::vector<Layer>::size_type) sampleLayerIndex; iLayer < (std::vector<Layer>::size_type) referenceLayerIndex; iLayer++)
            {
                layerPtr = &sample[iLayer];
                distance -= (*layerPtr).getThickness() / sinAlphaOut;
            }
        }
    }

    // we can calculate the geometric efficiency for the given layer
    // calculate geometric efficiency 0.5 * (1 - cos theta)
    return (0.5 * (1.0 - (distance / sqrt(pow(distance, 2) + pow(0.5 * detectorDiameter, 2)))));
}

std::map<std::string, std::map<int, std::map<std::string, std::map<std::string, double> > > > \
                XRF::getMultilayerFluorescence( \
                const std::string & elementName, \
                const Elements & elementsLibrary, const int & sampleLayerIndex, \
                const std::string & lineFamily, const int & secondary, \
                const int & useGeometricEfficiency, const int & useMassFractions, \
                const double & optimizationFactor )
{
    std::vector<std::string> elementList;
    std::vector<std::string> familyList;
    std::vector<int> layerList;
    std::string tmpString;
    std::vector<std::string> tmpStringVector;

    elementList.push_back(elementName);

    if (lineFamily == "")
    {
        throw std::invalid_argument("Please specify K, L or M as peak family");
    }
    familyList.push_back(lineFamily);
    if (sampleLayerIndex < 0)
    {
        throw std::invalid_argument("Layer index cannot be negative");
    }
    layerList.push_back(sampleLayerIndex);
    return this->getMultilayerFluorescence(elementList, elementsLibrary, layerList, familyList, \
                                           secondary, useGeometricEfficiency, useMassFractions, \
                                           optimizationFactor);
}

double XRF::getEnergyThreshold(const std::string & elementName, const std::string & family, \
                                const Elements & elementsLibrary) const
{
    std::map<std::string, double> binding;
    binding = elementsLibrary.getBindingEnergies(elementName);
    if ((family == "K") || (family.size() == 2))
        return binding[family];

    if (family == "L")
    {
        if (binding["L3"] > 0)
            return binding["L3"];
        if (binding["L2"] > 0)
            return binding["L2"];
        return binding["L1"]; // It can be 0.0
    }

    if (family == "M")
    {
        if (binding["M5"] > 0)
            return binding["M5"];
        if (binding["M4"] > 0)
            return binding["M4"];
        if (binding["M3"] > 0)
            return binding["M3"];
        if (binding["M2"] > 0)
            return binding["M2"];
        return binding["M1"]; // It can be 0.0
    }
    return 0.0;
}

const XRFConfig & XRF::getConfiguration() const
{
    return this->configuration;

}

std::map<std::string, std::map<int, std::map<std::string, std::map<std::string, double> > > > \
                XRF::getMultilayerFluorescence(const std::vector<std::string> & elementFamilyLayer, \
                const Elements & elementsLibrary, const int & secondary, \
                const int & useGeometricEfficiency, const int & useMassFractions, \
                const double & secondaryCalculationLimit)
{
    std::vector<std::string> elementList;
    std::vector<std::string> familyList;
    std::vector<int> layerList;
    std::vector<std::string>::size_type i;
    int layerIndex;
    std::string tmpString;
    std::vector<std::string> tmpStringVector;

    elementList.resize(elementFamilyLayer.size());
    familyList.resize(elementFamilyLayer.size());
    layerList.resize(elementFamilyLayer.size());

    for(i = 0; i < elementFamilyLayer.size(); i++)
    {
        tmpString = "";
        SimpleIni::parseStringAsMultipleValues(elementFamilyLayer[i], tmpStringVector, tmpString, ' ');
        // We should have a key of the form "Cr", "Cr K", or "Cr K 0"
        if(tmpStringVector.size() == 3)
        {
            elementList[i] = tmpStringVector[0];
            familyList[i] = tmpStringVector[1];
            if (!SimpleIni::stringConverter(tmpStringVector[2], layerIndex))
            {
                tmpString = "Unsuccessul conversion to layer integer: " + tmpStringVector[2];
                std::cout << tmpString << std::endl;
                throw std::invalid_argument(tmpString);
            }
            layerList[i] = layerIndex;
        }
        if(tmpStringVector.size() == 2)
        {
            elementList[i] = tmpStringVector[0];
            familyList[i] = tmpStringVector[1];
            layerList[i] = -1;
        }
        if(tmpStringVector.size() == 1)
        {
            elementList[i] = tmpStringVector[0];
            familyList[i] = "";
            layerList[i] = -1;
        }
    }
    return this->getMultilayerFluorescence(elementList, elementsLibrary, \
                                           layerList, familyList, secondary, useGeometricEfficiency, \
                                           useMassFractions, secondaryCalculationLimit);
}

} // namespace fisx
<|endoftext|>


<commit_before>/*
gpe_scene_tilemap_class.cpp
This file is part of:
GAME PENCIL ENGINE
https://create.pawbyte.com
Copyright (c) 2014-2020 Nathan Hurde, Chase Lee.

Copyright (c) 2014-2020 PawByte LLC.
Copyright (c) 2014-2020 Game Pencil Engine contributors ( Contributors Page )

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

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

-Game Pencil Engine <https://create.pawbyte.com>

*/

#include "gpe_scene_tilemap_class.h"

GPE_SceneTile::GPE_SceneTile()
{
    isLocked = false;
    branchType = BRANCH_TYPE_TILE;
    iconTexture = guiRCM->texture_add( APP_DIRECTORY_NAME+"resources/gfx/iconpacks/fontawesome/table.png") ;

    tileTypeId = -1;
    tileIndexId = -1;
    tilesheetIndexId = -1;
    tileRect.x = 0;
    tileRect.y = 0;
    tileRect.w = 0;
    tileRect.h = 0;
}

GPE_SceneTile::~GPE_SceneTile()
{

}

void GPE_SceneTile::add_typed_elements()
{
    if( PANEL_INSPECTOR!=NULL )
    {
    }
}

void GPE_SceneTile::render_branch()
{

}

bool GPE_SceneTile::save_branch_data(std::ofstream * fileTarget, int nestedFoldersIn )
{
    return true;
}

GPE_SceneTileMap::GPE_SceneTileMap( std::string mapName, int x, int y, GPE_GeneralResourceContainer *pFolder  )
{
    projectParentFolder = pFolder;
    if( projectParentFolder!=NULL)
    {
        tilesheetDropDown = new GPE_DropDown_Resouce_Menu( "Tilesheet",projectParentFolder->find_resource_from_name(RESOURCE_TYPE_NAMES[RESOURCE_TYPE_TILESHEET]+"s"),-1,true);
        tilesheetDropDown->set_width(192);
        tSPreviewer = new tilesheetPreviewer();

    }
    else
    {
        tilesheetDropDown = NULL;
        tSPreviewer = NULL;
    }

    isLocked = false;
    set_position( x, y);
    branchType = BRANCH_TYPE_TILEMAP;
    iconTexture = guiRCM->texture_add( APP_DIRECTORY_NAME+"resources/gfx/iconpacks/fontawesome/th.png") ;

    update_rect(&tsPlacementArea,0,0,0,0);

    tileWidth = GPE_DEFAULT_TILEHEIGHT;
    tileHeight = GPE_DEFAULT_TILEHEIGHT;

    tileAmountX = prevTileAmountX = 0;
    tileAmountY = prevTileAmountY = 0;

    xPosField->set_number( xPos );
    xPosField->set_label("Map-XStart");

    yPosField->set_number( yPos );
    yPosField->set_label("Map-YStart");

    fieldTileWidth = new GPE_TextInputNumber( "32" );
    fieldTileWidth->set_number( tileWidth );
    fieldTileWidth->set_label("Tile Width");
    fieldTileWidth->scale_width( 0.4 );

    fieldTileHeight = new GPE_TextInputNumber( "32" );
    fieldTileHeight->set_number( tileHeight );
    fieldTileHeight->set_label("Tile Height");
    fieldTileHeight->scale_width( 0.4 );

    fieldAmountX = new GPE_TextInputNumber( "" );
    fieldAmountX->set_number( tileAmountX );
    fieldAmountX->set_label("Map Width");
    fieldAmountX->scale_width( 0.4 );

    fieldAmountY = new GPE_TextInputNumber( "y-tile-amount" );
    fieldAmountY->set_label("Map Height");
    fieldAmountY->set_number( tileAmountY );
    fieldAmountY->scale_width( 0.4 );

    fillScene = new GPE_CheckBoxBasic("Fill Scene","Check to use remainder of scene" );
    if( (int)mapName.size()==0 )
    {
        name = "tilemap";
    }
    else
    {
        set_name( mapName );
    }
}

void GPE_SceneTileMap::add_typed_elements()
{
    if( PANEL_INSPECTOR!=NULL )
    {
        PANEL_INSPECTOR->add_gui_element( tilesheetDropDown, true );
        PANEL_INSPECTOR->add_gui_element( fieldTileWidth, false );
        PANEL_INSPECTOR->add_gui_element( fieldTileHeight, true );
        PANEL_INSPECTOR->add_gui_element( fieldAmountX, false );
        PANEL_INSPECTOR->add_gui_element( fieldAmountY, true );
        PANEL_INSPECTOR->add_gui_element( fillScene, true );
    }
}

GPE_SceneTileMap::~GPE_SceneTileMap()
{
    if( tSPreviewer!=NULL)
    {
        delete tSPreviewer;
        tSPreviewer = NULL;
    }
}

bool GPE_SceneTileMap::build_intohtml5_file(std::ofstream * fileTarget, int leftTabAmount, GPE_GeneralResourceContainer * localResTypeController )
{
    if( localResTypeController == NULL )
    {
        return false;
    }
    std::string nestedTabsStr = generate_tabs( leftTabAmount  );
    GPE_SceneTile * fSceneTile = NULL;
    GPE_GeneralResourceContainer * fTSToPlace = NULL;
    int maxTilesInLayer = (int)mapTiles.size();

    for(  int i = 0; i < maxTilesInLayer; i++)
    {
        fSceneTile = mapTiles.at(i);
        if( fSceneTile!=NULL &&fSceneTile->tilesheetIndexId>=0 && fSceneTile->tileIndexId>=0)
        {
            fTSToPlace = localResTypeController->find_resource_from_id(fSceneTile->tilesheetIndexId);
            if( fTSToPlace!=NULL)
            {
                *fileTarget << nestedTabsStr << "_scn_temp_layer.scnStartTiles.push( {tileNumber: " << int_to_string( i ) << ",";
                *fileTarget << "tileSheetId: " << int_to_string(fTSToPlace->exportBuildGlobalId) << ",";
                *fileTarget << "tileIndexId: " << int_to_string(fSceneTile->tileIndexId);
                *fileTarget << "}); \n";
            }
        }
    }
    GPE_SceneBasicClass::build_intohtml5_file( fileTarget, leftTabAmount+1, localResTypeController);
    return true;
}

void GPE_SceneTileMap::calculate_size()
{

}

void GPE_SceneTileMap::create_new_map(int newTX, int newTY,int ntileType )
{
    tileAmountX=newTX;
    tileAmountY=newTY;
    int newSize = tileAmountX*tileAmountY;
    if( mapTiles.size() >0 )
    {
        for(std::vector<GPE_SceneTile*>::const_iterator it = mapTiles.begin(); it != mapTiles.end(); it++)
        {
            delete *it;
        }
        mapTiles.clear();
    }
    GPE_SceneTile * newTile = NULL;
    for(int i=0; i<newSize; i++)
    {
        newTile = new GPE_SceneTile();
        newTile->tileTypeId = ntileType;
        mapTiles.push_back(newTile);
    }

    xPosField->set_number( xPos );
    yPosField->set_number( yPos );

    fieldTileWidth->set_number( tileWidth );
    fieldTileHeight->set_number( tileHeight );

    fieldAmountX->set_number( tileAmountX );
    fieldAmountY->set_number( tileAmountY );

    GPE_Report("Tile Map created.");
}

int GPE_SceneTileMap::get_map_size()
{
    return (int)mapTiles.size();
}

int GPE_SceneTileMap::get_xmax()
{
    return xPos+tileWidth * tileAmountX;
}

int GPE_SceneTileMap::get_ymax()
{
    return yPos+tileHeight * tileAmountY;
}

int GPE_SceneTileMap::get_sizex()
{
    return tileAmountX;
}

int GPE_SceneTileMap::get_sizey()
{
    return tileAmountY;
}

int GPE_SceneTileMap::get_tile_x( int xInPixels)
{
    if(  tileAmountX == 0 || tileWidth == 0)
    {
        return -1;
    }
    if( xInPixels > xPos )
    {
        xInPixels-= xPos;
        if( xInPixels < tileWidth * tileAmountX )
        {
            return xInPixels /tileWidth;
        }
        else
        {
            return tileAmountX;
        }
    }
    return -1;
}

int GPE_SceneTileMap::get_tile_y( int yInPixels)
{
    if( tileAmountY == 0 || tileHeight == 0)
    {
        return -1;
    }
    if( yInPixels > yPos )
    {
        yInPixels-= yPos;
        if( yInPixels < tileHeight * tileAmountY )
        {
            return yInPixels /tileHeight;
        }
        else
        {
            return tileAmountY;
        }
    }
    return -1;
}

GPE_SceneTile* GPE_SceneTileMap::get_tile_at(int xIn, int yIn)
{
    if( xIn >=0 && yIn >=0)
    {
        if( xIn < tileAmountX && yIn < tileAmountY)
        {
            int cTilePosition = xIn+ yIn*tileAmountX;
            if( cTilePosition >=0 && cTilePosition < (int)mapTiles.size() )
            {
                return mapTiles.at(cTilePosition);
            }
        }
    }
    return NULL;
}

void GPE_SceneTileMap::process_elements()
{
    GPE_SceneBasicClass::process_elements();
    int previousTileSheetId = tilesheetDropDown->get_selected_id();
    PANEL_TS_RESOURCE = GPE_DOCK->find_panel("Tilesheet");
    if(PANEL_TS_RESOURCE!=NULL )
    {
        if( tSPreviewer!=NULL )
        {
            tSPreviewer->tileSheetToPreview = NULL;
            PANEL_TS_RESOURCE->clear_panel();

            PANEL_TS_RESOURCE->add_gui_element(tilesheetDropDown,true);

            if( tilesheetDropDown!=NULL && tSPreviewer!=NULL )
            {
                if( tilesheetDropDown->is_clicked() || previousTileSheetId != tilesheetDropDown->get_selected_id() )
                {
                    tileToPlaceX1 = 0;
                    tileToPlaceY1 = 0;
                    tileToPlaceX2 = 0;
                    tileToPlaceY2 = 0;
                    tilesToPlacePerRow = 0;
                    tileIdsToPlace.clear();
                    tSPreviewer->reset_preview(true);
                }
                GPE_GeneralResourceContainer * tsTypeContainer = tilesheetDropDown->get_selected_container();
                if( tsTypeContainer!=NULL)
                {
                    tsRes = (tilesheetResource*) tsTypeContainer->get_held_resource();
                    tSPreviewer->tileSheetToPreview = tsRes->tilesheetInEditor;
                }
                tSPreviewer->set_width( PANEL_TS_RESOURCE->get_width()-GENERAL_GPE_GUI_PADDING );
                tSPreviewer->set_height( PANEL_TS_RESOURCE->get_height()-GENERAL_GPE_GUI_PADDING-tilesheetDropDown->get_height() );
                PANEL_TS_RESOURCE->add_gui_element(tSPreviewer,true);
            }
            PANEL_TS_RESOURCE->process_self( );
        }
    }

    int sceneTileMouseX = 0;
    int sceneTileMouseY = 0;
    if( spm !=NULL )
    {
        if( tileWidth > 0)
        {
            sceneTileMouseX = ( spm->mouseXPos - xPos) / tileWidth;
        }
        else
        {
            sceneTileMouseX = 0;
        }
        if( tileHeight > 0)
        {
            sceneTileMouseY = ( spm->mouseYPos - yPos) /tileHeight;
        }
    }
    else
    {
        return;
    }
    //if( shortcutButtonBar->get_tab_id() == SCENE_MODE_PLACE && mouseIsInScene && tSPreviewer!=NULL  &&  !selectedLayerMap->isLocked  )
    if( tSPreviewer!=NULL &&  !isLocked && tSPreviewer!=NULL && spm->mouseInScene && spm->editMode == SCENE_MODE_PLACE )
    {
        if( input->check_mouse_down( mb_left ) && tileWidth  > 0 && tileHeight  > 0  && (int)tSPreviewer->tilesIdsInPreview.size()>0  )
        {
            //Place Tiles and Such
            if( tsRes!=NULL  && tsRes->tilesheetInEditor!=NULL && tsRes->tilesheetInEditor->tsImage!=NULL)
            {
                //select tiles to place / place tiles / add tiles
                //if( RESOURCE_TO_DRAG==NULL && mouseIsInScene && sceneXScroll->is_scrolling()==false && sceneYScroll->is_scrolling()==false )
                {
                    GPE_SceneTile* fSceneTileToEdit = NULL;

                    int tileRowItr = 0;
                    int tilesItr= 0;
                    int newTileX = 0, newTileY = 0;

                    for( tilesItr = 0; tilesItr < (int)tSPreviewer->tilesIdsInPreview.size(); tilesItr++ )
                    {
                        fSceneTileToEdit = get_tile_at(sceneTileMouseX+newTileX,sceneTileMouseY+newTileY);
                        if( fSceneTileToEdit!=NULL)
                        {
                            fSceneTileToEdit->tileIndexId = tSPreviewer->tilesIdsInPreview.at(tilesItr);
                            fSceneTileToEdit->tilesheetIndexId = tilesheetDropDown->get_selected_id();
                            fSceneTileToEdit->tileTypeId = 1;
                        }
                        else
                        {
                            //    MAIN_OVERLAY->update_tooltip("Unable to find scene tile to edit...");
                        }
                        newTileX+=1;
                        tileRowItr+=1;
                        if( tileRowItr >= tSPreviewer->tilesToPlacePerRow)
                        {
                            tileRowItr = 0;
                            newTileX = 0;
                            newTileY+=1;
                        }
                    }
                }
            }
        }
    }
    //else if(shortcutButtonBar->get_tab_id() == SCENE_MODE_ERASE && mouseIsInScene && selectedLayerMap!=NULL  &&  !selectedLayerMap->isLocked  )
    else if(  !isLocked && input->check_mouse_down( mb_right )   && spm->mouseInScene  && spm->editMode == SCENE_MODE_ERASE  )
    {
        //Remove Tiles / Delete Tiles
        //if( mouseIsInScene && sceneXScroll->is_scrolling()==false && sceneYScroll->is_scrolling()==false )
        if( spm!=NULL )
        {
            GPE_SceneTile* fSceneTileToEdit = NULL;

            fSceneTileToEdit = get_tile_at(sceneTileMouseX,sceneTileMouseY);
            if( fSceneTileToEdit!=NULL )
            {
                fSceneTileToEdit->tileIndexId = -1;
                fSceneTileToEdit->tilesheetIndexId = -1;
                fSceneTileToEdit->tileTypeId = 1;
            }
        }
    }
}

void GPE_SceneTileMap::resize_tilemap( int newTX, int newTY,int ntileType)
{
    if( (newTX!=tileAmountX || newTY!=tileAmountY )&& newTX>0 && newTY>0)
    {
        int newSize = newTX*newTY;
        GPE_SceneTile *newTile = NULL;
        GPE_SceneTile *prevTile = NULL;
        int i, j;
        std::vector <GPE_SceneTile*> tempMapTiles;
        for( i=0; i<(int)mapTiles.size(); i++)
        {
            prevTile = mapTiles[i];
            newTile = new GPE_SceneTile();
            if( prevTile!=NULL)
            {
                newTile->tileTypeId = ntileType;
                newTile->tileIndexId = prevTile->tileIndexId;
                newTile->tilesheetIndexId = prevTile->tilesheetIndexId;
            }
            tempMapTiles.push_back(newTile);
        }

        //destroys old map to be reborn later
        if( (int)mapTiles.size() >0 )
        {
            for(std::vector<GPE_SceneTile*>::const_iterator it = mapTiles.begin(); it != mapTiles.end(); it++)
            {
                delete *it;
            }
        }
        mapTiles.clear();

        GPE_Report("Map cleared ("+int_to_string((int)mapTiles.size() ) +").");
        GPE_Report("New Dimensions ("+int_to_string(newTX)  +" x "+int_to_string(newTY)+" = "+int_to_string(newSize)+".");

        for( i=0; i<newSize; i++)
        {
            newTile = new GPE_SceneTile();
            newTile->tileTypeId = ntileType;
            mapTiles.push_back(newTile);
        }

        GPE_Report("Map resized ("+int_to_string((int)mapTiles.size() ) +").");
        //creates the tile layer with new dimensions all blanked out
        newTile = NULL;
        int iMaxPrevXTiles = std::max(newTX, tileAmountX);
        int jMaxPrevYTiles = std::max(newTY, tileAmountY);

        if( (int)tempMapTiles.size() >0 && (int)mapTiles.size() >0 )
        {
            for( j=0; j<jMaxPrevYTiles; j++)
            {
                for( i=0; i<iMaxPrevXTiles; i++)
                {
                    if( tileAmountX > i && tileAmountY > j)
                    {
                        prevTile = tempMapTiles.at(i+tileAmountX*j);
                    }
                    else
                    {
                        prevTile = NULL;
                    }
                    if( newTX > i && newTY > j)
                    {
                        newTile = mapTiles.at(i+newTX*j);
                    }
                    else
                    {
                        newTile = NULL;
                    }
                    if( prevTile!=NULL && newTile!=NULL)
                    {
                        newTile->tileTypeId = prevTile->tileIndexId;
                        newTile->tileIndexId = prevTile->tileIndexId;
                        newTile->tilesheetIndexId = prevTile->tilesheetIndexId;
                    }
                }
            }
        }

        tileAmountX=newTX;
        tileAmountY=newTY;
        //destroys the temp map
        if( (int)tempMapTiles.size() >0 )
        {
            for(std::vector<GPE_SceneTile*>::const_iterator itOld = tempMapTiles.begin(); itOld != tempMapTiles.end(); itOld++)
            {
                delete *itOld;
            }
            tempMapTiles.clear();
        }

        xPosField->set_number( xPos );
        yPosField->set_number( yPos );

        fieldTileWidth->set_number( tileWidth );
        fieldTileHeight->set_number( tileHeight );

        fieldAmountX->set_number( tileAmountX );
        fieldAmountY->set_number( tileAmountY );

        GPE_Report("Tile Map created.");
        GPE_Report("Map updated after resize ("+int_to_string((int)mapTiles.size() ) +").");
    }
}

void GPE_SceneTileMap::set_map_size( int newW, int newH )
{
    if( tileWidth !=0 & tileHeight!=0 )
    {
        int expectedNewSizeX = ceil( (float)newW/tileWidth );
        int expectedNewSizeY = ceil( (float)newW/tileHeight );
        if( prevTileAmountX <  tileAmountX || prevTileAmountX <  tileAmountY )
        {
            resize_tilemap( expectedNewSizeX, expectedNewSizeY);
        }
    }
}

void GPE_SceneTileMap::render_branch()
{
    //Avoid the time waste and don't continue if alpha is too low.
    if( branchAlpha!=NULL && branchAlpha->get_value() < 5)
    {
        return;
    }

    if( spm == NULL)
    {
        return;
    }

    if( spm->cSceneTstList!=NULL &&  tileWidth!=0 && tileHeight!=0 && spm->zoomValue!=0 )
    {
        GPE_Rect foundTsRect;
        int cTileXPos = 0;
        int cTileYPos = 0;
        int i = 0;
        int j = 0;
        int foundTilePos = 0;
        int tileXStartPos = std::max(0, get_tile_x( spm->cameraFloorXPos )-2 );
        int tileYStartPos = std::max(0, get_tile_y( spm->cameraFloorYPos )-2 );

        int tileXEndPos = tileXStartPos + std::max(0,get_tile_x( ( spm->currentCamera->w  / spm->zoomValue) ) ) +2;
        int tileYEndPos = tileYStartPos + std::max(0,get_tile_y( ( spm->currentCamera->h  / spm->zoomValue) ) ) +2;

        if( tileXStartPos>=0 && tileXStartPos > tileXEndPos)
        {
            tileXEndPos = tileAmountX;
        }

        if( tileYStartPos>=0 && tileYStartPos > tileYEndPos)
        {
            tileYEndPos = tileAmountY;
        }

        GPE_SceneTile * fSceneTile = NULL;
        GPE_GeneralResourceContainer * foundTSResource = NULL;
        tilesheetResource * foundHeldTSRes = NULL;

        //GPE_Report("Performing 1st loop");
        for( i = tileXStartPos; i < tileAmountX; i++ )
        {
            //GPE_Report("Performing 2nd loop");
            for(  j = tileYStartPos; j < tileAmountY; j++)
            {
                fSceneTile = get_tile_at( i, j);
                if( fSceneTile!=NULL)
                {
                    if( fSceneTile->tilesheetIndexId >= 0 && fSceneTile->tileIndexId >= 0 )
                    {
                        foundTSResource = spm->cSceneTstList->find_resource_from_id(fSceneTile->tilesheetIndexId);
                        if( foundTSResource!=NULL)
                        {
                            foundHeldTSRes = (tilesheetResource * )foundTSResource->get_held_resource();
                            if( foundHeldTSRes->tilesheetInEditor!=NULL )
                            {
                                if( foundHeldTSRes->tilesheetInEditor->tsImage!=NULL && fSceneTile->tileIndexId < (int)foundHeldTSRes->tilesheetInEditor->tsRects.size() )
                                {
                                    cTileXPos = floor( (i*tileWidth )  * spm->zoomValue ) - spm->currentCamera->x * spm->zoomValue;
                                    cTileYPos = floor( (j*tileHeight ) * spm->zoomValue ) - spm->currentCamera->y * spm->zoomValue;
                                    foundTsRect = foundHeldTSRes->tilesheetInEditor->tsRects.at(fSceneTile->tileIndexId );
                                    //if( check_collision(editorCameraRect,cTileXPos,cTileYPos,foundTsRect.w,foundTsRect.h) )
                                    {
                                        foundHeldTSRes->tilesheetInEditor->tsImage->render_tex_scaled( cTileXPos,cTileYPos, spm->zoomValue,spm->zoomValue,&foundTsRect,branchColor->get_color(), branchAlpha->get_value() );
                                        /*if( renderOutlines )
                                        {
                                            gcanvas->render_rectangle( cTileXPos,cTileYPos, cTileXPos+ceil( (float)foundTsRect.w*spm->zoomValue),cTileYPos+ceil( (float)foundTsRect.h*spm->zoomValue ), c_red, true, 255 );
                                            //render_text( cTileXPos,cTileYPos, int_to_string(fSceneTile->tilesheetIndexId)+"-"+int_to_string(fSceneTile->tileIndexId),c_red,GPE_DEFAULT_FONT,FA_LEFT,FA_TOP, 255 );
                                        }
                                        */
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //GPE_Report("2nd loop completed");
        }
        //GPE_Report("1st loop completed");

        //Previews tilesheet if selected
        GPE_GeneralResourceContainer * tsTypeContainer = tilesheetDropDown->get_selected_container();
        if( tsTypeContainer!=NULL  && spm->mouseInScene && spm->editMode == SCENE_MODE_PLACE && RESOURCE_TO_DRAG==NULL )
        {
            tsRes = (tilesheetResource*) tsTypeContainer->get_held_resource();
            if( tsRes!=NULL && tsRes->tilesheetInEditor!=NULL && tsRes->tilesheetInEditor->tsImage!=NULL)
            {
                //if( sceneXScroll->is_scrolling()==false && sceneYScroll->is_scrolling()==false )
                {
                    int sceneTileMouseX  = spm->mouseXPos;
                    int sceneTileMouseY  = spm->mouseYPos;

                    if( tileWidth!=0 &&tileHeight!=0)
                    {
                        sceneTileMouseX = sceneTileMouseX/tileWidth;
                        sceneTileMouseX = (sceneTileMouseX *tileWidth);
                        sceneTileMouseY = sceneTileMouseY/tileHeight;
                        sceneTileMouseY = (sceneTileMouseY *tileHeight);
                    }
                    sceneTileMouseX = floor( (sceneTileMouseX*spm->zoomValue-spm->cameraFloorXPos * spm->zoomValue ) );
                    sceneTileMouseY = floor( (sceneTileMouseY*spm->zoomValue-spm->cameraFloorYPos * spm->zoomValue) );

                    if( isLocked )
                    {
                        tSPreviewer->render_selection( sceneTileMouseX,sceneTileMouseY, NULL,NULL, spm->zoomValue, c_orangered );
                    }
                    else if( sceneTileMouseX >=0 && sceneTileMouseY >=0 )
                    {
                        tSPreviewer->render_selection( sceneTileMouseX,sceneTileMouseY,NULL,NULL,spm->zoomValue,c_white);
                    }
                    /*
                    else if( spm->mouseXPos < 0 || spm->mouseYPos < 0 || spm->mouseXPos > spm->tempRect->w || spm->mouseYPos > spm->tempRect->h )
                    {
                        tSPreviewer->render_selection( sceneTileMouseX,sceneTileMouseY,NULL,NULL,true,spm->zoomValue, c_red );
                    }
                    else
                    {
                        tSPreviewer->render_selection( sceneTileMouseX,sceneTileMouseY,NULL,NULL,true,spm->zoomValue,c_white);
                    }
                    */
                }
            }
        }
    }
    GPE_SpecialMenu_Branch::render_branch();
}

bool GPE_SceneTileMap::save_branch_data(std::ofstream * fileTarget, int nestedFoldersIn )
{
    if( fileTarget!=NULL && fileTarget->is_open() )
    {
        std::string nestedTabsStr = generate_tabs( nestedFoldersIn );
        *fileTarget << nestedTabsStr+ "[GPE_TileMap=";
        *fileTarget << int_to_string( tileWidth )+",";
        *fileTarget << int_to_string( tileHeight )+",";
        *fileTarget << int_to_string( tileAmountX )+",";
        *fileTarget << int_to_string( tileAmountY )+",";
        *fileTarget << int_to_string( xPos )+",";
        *fileTarget << int_to_string( yPos )+",";
        if( fillScene!=NULL)
        {
            *fileTarget << int_to_string( fillScene->is_clicked() )+",";
        }
        else
        {
            *fileTarget << "0,";
        }
        if( (int)name.size() > 0 )
        {
            *fileTarget <<                name +",,";
        }
        else
        {
            *fileTarget <<                 +"tilemap,,";
        }
        *fileTarget << "]\n";
        GPE_SceneBasicClass::save_branch_data( fileTarget, nestedFoldersIn+1 );
        int maxTilesInMap = (int)mapTiles.size();
        nestedTabsStr = generate_tabs( nestedFoldersIn+1 );
        GPE_SceneTile * fSceneTile = NULL;
        for(  int i = 0; i < maxTilesInMap; i++)
        {
            fSceneTile = mapTiles.at(i);
            if(  fSceneTile!=NULL && fSceneTile->tilesheetIndexId > 0 && fSceneTile->tileIndexId >= 0  )
            {
                *fileTarget << nestedTabsStr+ "GPE_SingleTile=";
                //This is the position of the tile in the tilemap
                *fileTarget << int_to_string( i )+",";
                *fileTarget << int_to_string( fSceneTile->tilesheetIndexId )+",";
                *fileTarget << int_to_string( fSceneTile->tileIndexId )+",";
                *fileTarget << int_to_string( fSceneTile->tileTypeId )+",";
                /*
                *fileTarget <<                fSceneTile->get_name() +",,";
                //For later version I plan to add more data here...
                fSceneTile->save_branch_data( fileTarget, nestedFoldersIn+1 );
                */
                *fileTarget << "\n";
            }
        }
        *fileTarget << nestedTabsStr+"[/GPE_TileMap]\n";
        return true;
    }
    return false;
}
<commit_msg>Delete gpe_scene_tilemap_class.cpp<commit_after><|endoftext|>


<commit_before>#include "./object_manager.h"
#include <QLoggingCategory>
#include <vector>
#include <map>
#include <algorithm>
#include "./gl.h"
#include "./buffer_manager.h"
#include "./texture_manager.h"
#include "./shader_manager.h"

namespace Graphics
{

QLoggingCategory omChan("Graphics.ObjectManager");

ObjectManager::ObjectManager(std::shared_ptr<TextureManager> textureManager,
                             std::shared_ptr<ShaderManager> shaderManager)
  : bufferManager(std::make_shared<BufferManager>()),
    textureManager(textureManager), shaderManager(shaderManager),
    transformBuffer(GL_SHADER_STORAGE_BUFFER),
    customBuffer(GL_SHADER_STORAGE_BUFFER),
    commandsBuffer(GL_DRAW_INDIRECT_BUFFER)

{
}

ObjectManager::~ObjectManager()
{
}

void ObjectManager::initialize(Gl *gl, uint maxObjectCount, uint bufferSize)
{
  this->gl = gl;

  bufferManager->initialize(gl, maxObjectCount, bufferSize);

  commandsBuffer.initialize(gl, 3 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
  transformBuffer.initialize(gl, 3 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
  customBuffer.initialize(gl, 12 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
}

ObjectData ObjectManager::addObject(const std::vector<float> &vertices,
                                    const std::vector<float> &normals,
                                    const std::vector<float> &colors,
                                    const std::vector<float> &texCoords,
                                    const std::vector<uint> &indices,
                                    int shaderProgramId, int primitiveType)
{
  auto bufferInformation =
      bufferManager->addObject(vertices, normals, colors, texCoords, indices);

  ObjectData object;
  object.vertexOffset = bufferInformation.vertexBufferOffset;
  object.vertexSize = bufferInformation.vertexCount;
  object.indexOffset = bufferInformation.indexBufferOffset;
  object.indexSize = indices.size();
  object.customBufferSize = 0;
  object.setBuffer = nullptr;
  object.transform = Eigen::Matrix4f::Identity();
  object.shaderProgramId = shaderProgramId;
  object.primitiveType = primitiveType;

  return object;
}

int ObjectManager::addShader(std::string vertexShaderPath,
                             std::string fragmentShaderPath)
{
  auto id = shaderManager->addShader(vertexShaderPath, fragmentShaderPath);

  qCDebug(omChan) << "Added" << vertexShaderPath.c_str() << "|"
                  << fragmentShaderPath.c_str() << "which got id" << id;

  return id;
}

int ObjectManager::addTexture(std::string path)
{
  return textureManager->addTexture(path);
}

TextureAddress ObjectManager::getAddressFor(int textureId)
{
  return textureManager->getAddressFor(textureId);
}

void ObjectManager::render(const RenderData &renderData)
{
  std::map<int, std::vector<ObjectData>> objectsByShader;
  for (auto &object : objectsForFrame)
  {
    objectsByShader[object.shaderProgramId].push_back(object);
  }

  for (auto &shaderObjectPair : objectsByShader)
  {
    qCDebug(omChan) << "Render objects with shader" << shaderObjectPair.first
                    << "with" << shaderObjectPair.second.size() << "objects";

    shaderManager->bind(shaderObjectPair.first, renderData);

    std::map<int, std::vector<ObjectData>> objectsByPrimitiveType;
    for (auto &object : shaderObjectPair.second)
    {
      objectsByPrimitiveType[object.primitiveType].push_back(object);
    }

    for (auto pair : objectsByPrimitiveType)
    {
      renderObjects(objectsByPrimitiveType[pair.first]);
    }
  }

  objectsForFrame.clear();
}

void ObjectManager::renderImmediately(ObjectData objectData)
{
  std::vector<ObjectData> objs = { objectData };

  renderObjects(objs);
}

void ObjectManager::renderLater(ObjectData object)
{
  objectsForFrame.push_back(object);
}

void ObjectManager::renderObjects(std::vector<ObjectData> objects)
{
  bufferManager->bind();

  // prepare per object buffers
  uint objectCount = objects.size();
  DrawElementsIndirectCommand *commands = commandsBuffer.reserve(objectCount);
  auto *matrices = transformBuffer.reserve(objectCount);
  int customBufferSize = objects[0].customBufferSize * objectCount;

  void *custom = nullptr;
  if (customBufferSize)
    custom = customBuffer.reserve(customBufferSize);

  qCDebug(omChan) << "customBufferSize" << customBufferSize << "custom"
                  << custom << "matrices" << matrices;

  int counter = 0;
  for (auto &objectData : objects)
  {
    commands[counter] = createDrawCommand(objectData, counter);

    auto *transform = &matrices[counter];
    memcpy(transform, objectData.transform.data(), sizeof(float[16]));

    if (objectData.setBuffer && customBufferSize)
    {
      objectData.setBuffer(static_cast<char *>(custom) +
                           counter * objectData.customBufferSize);
    }

    ++counter;
  }

  qCDebug(omChan, "objectcount: %u/%ld", objectCount, commandsBuffer.size());

  int mapRange = ((objectCount / 4) + 1) * 4;
  transformBuffer.bindBufferRange(0, mapRange);
  int customMapRange = ((customBufferSize / 16) + 1) * 16;
  if (customBufferSize)
    customBuffer.bindBufferRange(1, customMapRange);

  // We didn't use MAP_COHERENT here - make sure data is on the gpu
  glAssert(gl->glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT));

  // draw
  qCDebug(omChan, "head: %ld headoffset %p objectcount: %un",
          commandsBuffer.getHead(), commandsBuffer.headOffset(), objectCount);

  glAssert(gl->glMultiDrawElementsIndirect(
      objects[0].primitiveType, GL_UNSIGNED_INT, commandsBuffer.headOffset(),
      objectCount, 0));

  bufferManager->unbind();

  commandsBuffer.onUsageComplete(mapRange);
  transformBuffer.onUsageComplete(mapRange);
  if (customBufferSize)
    customBuffer.onUsageComplete(customMapRange);
}

DrawElementsIndirectCommand
ObjectManager::createDrawCommand(const ObjectData &objectData, int counter)
{
  DrawElementsIndirectCommand command;

  command.count = objectData.indexSize;
  command.instanceCount = 1;
  command.firstIndex = objectData.indexOffset;
  command.baseVertex = objectData.vertexOffset;
  command.baseInstance = counter;

  qCDebug(omChan, "counter: %d count: %u firstIndex: %u baseVertex: %u",
          counter, command.count, command.firstIndex, command.baseVertex);

  return command;
}

}  // namespace Graphics
<commit_msg>Use memory barrier for all bits.<commit_after>#include "./object_manager.h"
#include <QLoggingCategory>
#include <vector>
#include <map>
#include <algorithm>
#include "./gl.h"
#include "./buffer_manager.h"
#include "./texture_manager.h"
#include "./shader_manager.h"

namespace Graphics
{

QLoggingCategory omChan("Graphics.ObjectManager");

ObjectManager::ObjectManager(std::shared_ptr<TextureManager> textureManager,
                             std::shared_ptr<ShaderManager> shaderManager)
  : bufferManager(std::make_shared<BufferManager>()),
    textureManager(textureManager), shaderManager(shaderManager),
    transformBuffer(GL_SHADER_STORAGE_BUFFER),
    customBuffer(GL_SHADER_STORAGE_BUFFER),
    commandsBuffer(GL_DRAW_INDIRECT_BUFFER)

{
}

ObjectManager::~ObjectManager()
{
}

void ObjectManager::initialize(Gl *gl, uint maxObjectCount, uint bufferSize)
{
  this->gl = gl;

  bufferManager->initialize(gl, maxObjectCount, bufferSize);

  commandsBuffer.initialize(gl, 3 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
  transformBuffer.initialize(gl, 3 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
  customBuffer.initialize(gl, 12 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
}

ObjectData ObjectManager::addObject(const std::vector<float> &vertices,
                                    const std::vector<float> &normals,
                                    const std::vector<float> &colors,
                                    const std::vector<float> &texCoords,
                                    const std::vector<uint> &indices,
                                    int shaderProgramId, int primitiveType)
{
  auto bufferInformation =
      bufferManager->addObject(vertices, normals, colors, texCoords, indices);

  ObjectData object;
  object.vertexOffset = bufferInformation.vertexBufferOffset;
  object.vertexSize = bufferInformation.vertexCount;
  object.indexOffset = bufferInformation.indexBufferOffset;
  object.indexSize = indices.size();
  object.customBufferSize = 0;
  object.setBuffer = nullptr;
  object.transform = Eigen::Matrix4f::Identity();
  object.shaderProgramId = shaderProgramId;
  object.primitiveType = primitiveType;

  return object;
}

int ObjectManager::addShader(std::string vertexShaderPath,
                             std::string fragmentShaderPath)
{
  auto id = shaderManager->addShader(vertexShaderPath, fragmentShaderPath);

  qCDebug(omChan) << "Added" << vertexShaderPath.c_str() << "|"
                  << fragmentShaderPath.c_str() << "which got id" << id;

  return id;
}

int ObjectManager::addTexture(std::string path)
{
  return textureManager->addTexture(path);
}

TextureAddress ObjectManager::getAddressFor(int textureId)
{
  return textureManager->getAddressFor(textureId);
}

void ObjectManager::render(const RenderData &renderData)
{
  std::map<int, std::vector<ObjectData>> objectsByShader;
  for (auto &object : objectsForFrame)
  {
    objectsByShader[object.shaderProgramId].push_back(object);
  }

  for (auto &shaderObjectPair : objectsByShader)
  {
    qCDebug(omChan) << "Render objects with shader" << shaderObjectPair.first
                    << "with" << shaderObjectPair.second.size() << "objects";

    shaderManager->bind(shaderObjectPair.first, renderData);

    std::map<int, std::vector<ObjectData>> objectsByPrimitiveType;
    for (auto &object : shaderObjectPair.second)
    {
      objectsByPrimitiveType[object.primitiveType].push_back(object);
    }

    for (auto pair : objectsByPrimitiveType)
    {
      renderObjects(objectsByPrimitiveType[pair.first]);
    }
  }

  objectsForFrame.clear();
}

void ObjectManager::renderImmediately(ObjectData objectData)
{
  std::vector<ObjectData> objs = { objectData };

  renderObjects(objs);
}

void ObjectManager::renderLater(ObjectData object)
{
  objectsForFrame.push_back(object);
}

void ObjectManager::renderObjects(std::vector<ObjectData> objects)
{
  bufferManager->bind();

  // prepare per object buffers
  uint objectCount = objects.size();
  DrawElementsIndirectCommand *commands = commandsBuffer.reserve(objectCount);
  auto *matrices = transformBuffer.reserve(objectCount);
  int customBufferSize = objects[0].customBufferSize * objectCount;

  void *custom = nullptr;
  if (customBufferSize)
    custom = customBuffer.reserve(customBufferSize);

  qCDebug(omChan) << "customBufferSize" << customBufferSize << "custom"
                  << custom << "matrices" << matrices;

  int counter = 0;
  for (auto &objectData : objects)
  {
    commands[counter] = createDrawCommand(objectData, counter);

    auto *transform = &matrices[counter];
    memcpy(transform, objectData.transform.data(), sizeof(float[16]));

    if (objectData.setBuffer && customBufferSize)
    {
      objectData.setBuffer(static_cast<char *>(custom) +
                           counter * objectData.customBufferSize);
    }

    ++counter;
  }

  qCDebug(omChan, "objectcount: %u/%ld", objectCount, commandsBuffer.size());

  int mapRange = ((objectCount / 4) + 1) * 4;
  transformBuffer.bindBufferRange(0, mapRange);
  int customMapRange = ((customBufferSize / 16) + 1) * 16;
  if (customBufferSize)
    customBuffer.bindBufferRange(1, customMapRange);

  // We didn't use MAP_COHERENT here - make sure data is on the gpu
  // glAssert(gl->glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT));
  glAssert(gl->glMemoryBarrier(GL_ALL_BARRIER_BITS));

  // draw
  qCDebug(omChan, "head: %ld headoffset %p objectcount: %un",
          commandsBuffer.getHead(), commandsBuffer.headOffset(), objectCount);

  glAssert(gl->glMultiDrawElementsIndirect(
      objects[0].primitiveType, GL_UNSIGNED_INT, commandsBuffer.headOffset(),
      objectCount, 0));

  bufferManager->unbind();

  commandsBuffer.onUsageComplete(mapRange);
  transformBuffer.onUsageComplete(mapRange);
  if (customBufferSize)
    customBuffer.onUsageComplete(customMapRange);
}

DrawElementsIndirectCommand
ObjectManager::createDrawCommand(const ObjectData &objectData, int counter)
{
  DrawElementsIndirectCommand command;

  command.count = objectData.indexSize;
  command.instanceCount = 1;
  command.firstIndex = objectData.indexOffset;
  command.baseVertex = objectData.vertexOffset;
  command.baseInstance = counter;

  qCDebug(omChan, "counter: %d count: %u firstIndex: %u baseVertex: %u",
          counter, command.count, command.firstIndex, command.baseVertex);

  return command;
}

}  // namespace Graphics
<|endoftext|>


<commit_before>#include "mapadapter.h"
#include "ui_mapadapter.h"
#include <QPainter>
#include <QMouseEvent>
#include <QWheelEvent>
#include <common/utils/AngleUtils.h>

using namespace pcl;

MapAdapter::MapAdapter(MapBuilder *mapper, BasicPositionTracker *posTracker, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MapAdapter),
    _scale(20),
    LonNewMap(this),
    _mapper(mapper),
    _posTracker(posTracker)
{
    ui->setupUi(this);

    if(_mapper != nullptr)
        _mapper->onNewMap += &LonNewMap;
}

void MapAdapter::setScale(int scale)
{
    scale = std::min(scale, 100);
    scale = std::max(scale, 1);
    _scale = scale;
    ui->scaleSlider->setValue(scale);
    update();
}

void MapAdapter::onNewMap(pcl::PointCloud<PointXYZ>::Ptr map)
{
    _map = map;
    update();
}

void MapAdapter::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    // Draw axes
    painter.setPen(Qt::red);
    QPoint center = QPoint(this->width()/2, this->height()/2) + _origin;
    painter.drawLine(center, center + QPoint(0,-1*_scale));
    painter.setPen(Qt::blue);
    painter.drawLine(center, center + QPoint(1*_scale,0));

    // Draw robot position
    painter.setPen(Qt::red);
    RobotPosition pos = _posTracker->GetPosition();
    painter.drawEllipse(QPoint(pos.X, pos.Y) + center, 5, 5);
    painter.drawLine(QPoint(pos.X, pos.Y) + center, QPoint(5*sin(AngleUtils::degToRads(pos.Heading)),5*cos(AngleUtils::degToRads(180+pos.Heading))) + center);

    // Draw map
    if(_map != NULL)
    {
        if(_map->size() == 0)
        {
            painter.setPen(Qt::red);
            painter.drawText(QPoint(this->width()/2-40,this->height()/2), tr("EMPTY MAP"));
        }
        else
        {
            painter.setPen(Qt::black);
            PointCloud<PointXYZ>::iterator iter;
            for(iter = _map->begin(); iter != _map->end(); iter++)
            {
                PointXYZ mPoint = (*iter);
                QPoint sPoint = QPoint((int)(mPoint.x * _scale), (int)(mPoint.y * _scale));
                sPoint += center;
                // Displays points as 3x3 pixel crosses
                painter.drawLine(sPoint - QPoint(1,0), sPoint + QPoint(1,0));
                painter.drawLine(sPoint - QPoint(0,1), sPoint + QPoint(0,1));
            }
        }
    }
    else
    {
        painter.setPen(Qt::red);
        painter.drawText(QPoint(this->width()/2-25,this->height()/2), tr("NO MAP"));
    }

    painter.end();
}

MapAdapter::~MapAdapter()
{
    delete ui;
    if(_mapper != nullptr)
        _mapper->onNewMap -= &LonNewMap;
}

void MapAdapter::on_scaleSlider_sliderMoved(int position)
{
    setScale(position);
}

void MapAdapter::on_homeButton_clicked()
{
    _origin = QPoint(0,0);
    setScale(20);
}

void MapAdapter::mousePressEvent(QMouseEvent *e)
{
    _previousMousePosition = e->pos();
}

void MapAdapter::mouseMoveEvent(QMouseEvent *e)
{
    if(e->buttons() & Qt::LeftButton)
    {
        QPoint delta = e->pos() - _previousMousePosition;
        _origin += delta;
        _previousMousePosition = e->pos();
        update();
    }
}

void MapAdapter::wheelEvent(QWheelEvent *e)
{
    setScale(_scale + ( e->angleDelta().y() / 30 ) );
}

void MapAdapter::on_pushButton_clicked()
{
    _mapper->Clear();
}
<commit_msg>Fixes bug in map adapter position marker math.<commit_after>#include "mapadapter.h"
#include "ui_mapadapter.h"
#include <QPainter>
#include <QMouseEvent>
#include <QWheelEvent>
#include <common/utils/AngleUtils.h>

using namespace pcl;

MapAdapter::MapAdapter(MapBuilder *mapper, BasicPositionTracker *posTracker, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MapAdapter),
    _scale(20),
    LonNewMap(this),
    _mapper(mapper),
    _posTracker(posTracker)
{
    ui->setupUi(this);

    if(_mapper != nullptr)
        _mapper->onNewMap += &LonNewMap;
}

void MapAdapter::setScale(int scale)
{
    scale = std::min(scale, 100);
    scale = std::max(scale, 1);
    _scale = scale;
    ui->scaleSlider->setValue(scale);
    update();
}

void MapAdapter::onNewMap(pcl::PointCloud<PointXYZ>::Ptr map)
{
    _map = map;
    update();
}

void MapAdapter::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    // Draw axes
    painter.setPen(Qt::red);
    QPoint center = QPoint(this->width()/2, this->height()/2) + _origin;
    painter.drawLine(center, center + QPoint(0,-1*_scale));
    painter.setPen(Qt::blue);
    painter.drawLine(center, center + QPoint(1*_scale,0));

    // Draw robot position
    painter.setPen(Qt::red);
    RobotPosition pos = _posTracker->GetPosition();
    QPoint posMark = _scale * QPoint(pos.X, pos.Y) + center;
    painter.drawEllipse(posMark, 5, 5);
    painter.drawLine(posMark, posMark + QPoint(5*sin(AngleUtils::degToRads(pos.Heading)),5*cos(AngleUtils::degToRads(180+pos.Heading))));

    // Draw map
    if(_map != NULL)
    {
        if(_map->size() == 0)
        {
            painter.setPen(Qt::red);
            painter.drawText(QPoint(this->width()/2-40,this->height()/2), tr("EMPTY MAP"));
        }
        else
        {
            painter.setPen(Qt::black);
            PointCloud<PointXYZ>::iterator iter;
            for(iter = _map->begin(); iter != _map->end(); iter++)
            {
                PointXYZ mPoint = (*iter);
                QPoint sPoint = QPoint((int)(mPoint.x * _scale), (int)(mPoint.y * _scale));
                sPoint += center;
                // Displays points as 3x3 pixel crosses
                painter.drawLine(sPoint - QPoint(1,0), sPoint + QPoint(1,0));
                painter.drawLine(sPoint - QPoint(0,1), sPoint + QPoint(0,1));
            }
        }
    }
    else
    {
        painter.setPen(Qt::red);
        painter.drawText(QPoint(this->width()/2-25,this->height()/2), tr("NO MAP"));
    }

    painter.end();
}

MapAdapter::~MapAdapter()
{
    delete ui;
    if(_mapper != nullptr)
        _mapper->onNewMap -= &LonNewMap;
}

void MapAdapter::on_scaleSlider_sliderMoved(int position)
{
    setScale(position);
}

void MapAdapter::on_homeButton_clicked()
{
    _origin = QPoint(0,0);
    setScale(20);
}

void MapAdapter::mousePressEvent(QMouseEvent *e)
{
    _previousMousePosition = e->pos();
}

void MapAdapter::mouseMoveEvent(QMouseEvent *e)
{
    if(e->buttons() & Qt::LeftButton)
    {
        QPoint delta = e->pos() - _previousMousePosition;
        _origin += delta;
        _previousMousePosition = e->pos();
        update();
    }
}

void MapAdapter::wheelEvent(QWheelEvent *e)
{
    setScale(_scale + ( e->angleDelta().y() / 30 ) );
}

void MapAdapter::on_pushButton_clicked()
{
    _mapper->Clear();
}
<|endoftext|>


<commit_before>#include "gameboy.hpp"

GameBoy::GameBoy () {}
GameBoy::~GameBoy () {}

void GameBoy::Initialize () {
	cpu.Initialize(&mmu);
	mmu.Initialize();
	ppu.Initialize(&cpu, &mmu);

	timerCounter = 1024;
}

void GameBoy::LoadBios (Rom bios) {
	mmu.WriteBios(bios.GetData());
}

void GameBoy::LoadRom (Rom rom) {
	mmu.WriteBufferToRom(rom.GetData(), rom.GetSize());
}

void GameBoy::StepEmulation (const uint32_t cyclesThisUpdate) {
	size_t cylesDone = 0;
	while (cylesDone < cyclesThisUpdate) {
		this->StepInstruction();

		uint16_t numCycles = cpu.clockCycles;
		this->StepTimers(numCycles);
		this->StepGraphics(numCycles);
		ppu.StepUpdate(numCycles);
		cpu.ProcessInterrupts();

		cylesDone += numCycles;
	}

}

void GameBoy::StepInstruction () {
	cpu.EmulateCycle();
}

void GameBoy::StepTimers (uint32_t cycles) {

	if (mmu.ReadByte(DIV) + cycles >= 255) {
		mmu.WriteByte(DIV, 0);
	} else {
		mmu.WriteByte(DIV, cycles);
	}

	if (IsClockEnabled() == false)
		return;

	timerCounter -= cycles;

	// enough cpu clock cycles have happened to update the timer
	if (timerCounter <= 0) {
		ResetClockFrequency();

		// timer about to overflow
		if (mmu.ReadByte(TIMA) == 255) {
			mmu.WriteByte(TIMA, mmu.ReadByte(TMA));
			cpu.RequestInterrupt(2);
		}
		else {
			mmu.WriteByte(TIMA, mmu.ReadByte(TIMA) + 1);
		}
	}
}

void GameBoy::StepGraphics (uint32_t cycles) {

}

void GameBoy::ResetClockFrequency () {
	// Frequencies as define by the pandocs but divided by the clockspeed (4194304)
	//                                Dec:     0   1   2    3
	//                                Bin:    00  01  10   11
	static const uint32_t frequencies[] = { 1024, 16, 64, 256 };

	this->timerCounter = frequencies[mmu.ReadClockFrequency()];
}

bool GameBoy::IsClockEnabled () {
	return (mmu.ReadByte(TMC) & 0x4) == 0x4 ? true : false;
}

uint8_t* GameBoy::GetDisplayBuffer () {
	return ppu.GetDisplayBuffer();
}

MMU* GameBoy::GetMMU () {
	return &mmu;
}

bool GameBoy::GetHalt () {
	return isHalted;
}

void GameBoy::SetHalt (bool state) {
	this->isHalted = state;
}

void GameBoy::ToggleHalt () {
	this->isHalted ^= 1;
}
<commit_msg>DIV writing now happens directly without the WriteByte function in the StepTimers function<commit_after>#include "gameboy.hpp"

GameBoy::GameBoy () {}
GameBoy::~GameBoy () {}

void GameBoy::Initialize () {
	cpu.Initialize(&mmu);
	mmu.Initialize();
	ppu.Initialize(&cpu, &mmu);

	timerCounter = 1024;
}

void GameBoy::LoadBios (Rom bios) {
	mmu.WriteBios(bios.GetData());
}

void GameBoy::LoadRom (Rom rom) {
	mmu.WriteBufferToRom(rom.GetData(), rom.GetSize());
}

void GameBoy::StepEmulation (const uint32_t cyclesThisUpdate) {
	size_t cylesDone = 0;
	while (cylesDone < cyclesThisUpdate) {
		this->StepInstruction();

		uint16_t numCycles = cpu.clockCycles;
		this->StepTimers(numCycles);
		this->StepGraphics(numCycles);
		ppu.StepUpdate(numCycles);
		cpu.ProcessInterrupts();

		cylesDone += numCycles;
	}

}

void GameBoy::StepInstruction () {
	cpu.EmulateCycle();
}

void GameBoy::StepTimers (uint32_t cycles) {
	uint8_t* div = mmu.GetMemoryRef(DIV);
	if (*div + cycles >= 255) {
		*div = 0;
	} else {
		*div = cycles;
	}

	if (IsClockEnabled() == false)
		return;

	timerCounter -= cycles;

	// enough cpu clock cycles have happened to update the timer
	if (timerCounter <= 0) {
		ResetClockFrequency();

		// timer about to overflow
		if (mmu.ReadByte(TIMA) == 255) {
			mmu.WriteByte(TIMA, mmu.ReadByte(TMA));
			cpu.RequestInterrupt(2);
		}
		else {
			mmu.WriteByte(TIMA, mmu.ReadByte(TIMA) + 1);
		}
	}
}

void GameBoy::StepGraphics (uint32_t cycles) {

}

void GameBoy::ResetClockFrequency () {
	// Frequencies as define by the pandocs but divided by the clockspeed (4194304)
	//                                Dec:     0   1   2    3
	//                                Bin:    00  01  10   11
	static const uint32_t frequencies[] = { 1024, 16, 64, 256 };

	this->timerCounter = frequencies[mmu.ReadClockFrequency()];
}

bool GameBoy::IsClockEnabled () {
	return (mmu.ReadByte(TMC) & 0x4) == 0x4 ? true : false;
}

uint8_t* GameBoy::GetDisplayBuffer () {
	return ppu.GetDisplayBuffer();
}

MMU* GameBoy::GetMMU () {
	return &mmu;
}

bool GameBoy::GetHalt () {
	return isHalted;
}

void GameBoy::SetHalt (bool state) {
	this->isHalted = state;
}

void GameBoy::ToggleHalt () {
	this->isHalted ^= 1;
}
<|endoftext|>


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

#include <string>
#include <limits>

namespace miopen {

inline std::string GetDataType(miopenDataType_t type)
{
    std::string type_str;
    switch(type)
    {
    case miopenFloat: { type_str = "float";
    }
    break;
    case miopenHalf: { type_str = "half";
    }
    break;
    case miopenBFloat16: { type_str = "bfloat16";
    }
    break;
    case miopenInt8x4:
    case miopenInt8: { type_str = "int8_t";
    }
    break;
    case miopenInt32: { type_str = "int";
    }
    break;
    }
    return type_str;
}

inline std::size_t get_data_size(miopenDataType_t) { MIOPEN_THROW("not implemented"); }

inline std::size_t get_data_size(miopenIndexType_t index_type)
{
    switch(index_type)
    {
    case miopenIndexUint8: { return sizeof(uint8_t);
    }
    case miopenIndexUint16: { return sizeof(uint16_t);
    }
    case miopenIndexUint32: { return sizeof(uint32_t);
    }
    case miopenIndexUint64: { return sizeof(uint64_t);
    }
    }

    MIOPEN_THROW("not belong to any case");
}

inline std::size_t get_index_max(miopenIndexType_t index_type)
{
    // Basically, constants defined in cl.h, like CL_UCHAR_MAX, shall be used here.
    //    However, these are not available for HIP backend.
    switch(index_type)
    {
    case miopenIndexUint8: { return std::numeric_limits<uint8_t>::max();
    }
    case miopenIndexUint16: { return std::numeric_limits<uint16_t>::max();
    }
    case miopenIndexUint32: { return std::numeric_limits<uint32_t>::max();
    }
    case miopenIndexUint64: { return std::numeric_limits<uint64_t>::max();
    }
    }

    MIOPEN_THROW("not belong to any case");
}

inline std::string GetDataTypeKernelParams(miopenDataType_t type)
{
    // values for MIOPEN_USE_ macros
    int use_fp16               = 0;
    int use_fp32               = 0;
    int use_int8               = 0;
    int use_int8x4             = 0;
    int use_int32              = 0;
    int use_bfp16              = 0;
    const int use_rne_bfloat16 = MIOPEN_USE_RNE_BFLOAT16;

    switch(type)
    {
    case miopenHalf: use_fp16      = 1; break;
    case miopenFloat: use_fp32     = 1; break;
    case miopenInt8: use_int8      = 1; break;
    case miopenInt8x4: use_int8x4  = 1; break;
    case miopenBFloat16: use_bfp16 = 1; break;
    case miopenInt32: use_int32    = 1; break;
    default:
        MIOPEN_THROW("Only float, half, bfloat16, int8, int8x4 data type is supported.");
        break;
    }

    std::ostringstream ss;
    ss << " -DMIOPEN_USE_FP16=" << use_fp16;
    ss << " -DMIOPEN_USE_FP32=" << use_fp32;
    ss << " -DMIOPEN_USE_INT8=" << use_int8;
    ss << " -DMIOPEN_USE_INT8x4=" << use_int8x4;
    ss << " -DMIOPEN_USE_BFP16=" << use_bfp16;
    ss << " -DMIOPEN_USE_INT32=" << use_int32;
    ss << " -DMIOPEN_USE_RNE_BFLOAT16=" << use_rne_bfloat16;
    return ss.str();
}

} // namespace miopen

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

#include <sstream>
#include <string>
#include <limits>

namespace miopen {

inline std::string GetDataType(miopenDataType_t type)
{
    std::string type_str;
    switch(type)
    {
    case miopenFloat: { type_str = "float";
    }
    break;
    case miopenHalf: { type_str = "half";
    }
    break;
    case miopenBFloat16: { type_str = "bfloat16";
    }
    break;
    case miopenInt8x4:
    case miopenInt8: { type_str = "int8_t";
    }
    break;
    case miopenInt32: { type_str = "int";
    }
    break;
    }
    return type_str;
}

inline std::size_t get_data_size(miopenDataType_t) { MIOPEN_THROW("not implemented"); }

inline std::size_t get_data_size(miopenIndexType_t index_type)
{
    switch(index_type)
    {
    case miopenIndexUint8: { return sizeof(uint8_t);
    }
    case miopenIndexUint16: { return sizeof(uint16_t);
    }
    case miopenIndexUint32: { return sizeof(uint32_t);
    }
    case miopenIndexUint64: { return sizeof(uint64_t);
    }
    }

    MIOPEN_THROW("not belong to any case");
}

inline std::size_t get_index_max(miopenIndexType_t index_type)
{
    // Basically, constants defined in cl.h, like CL_UCHAR_MAX, shall be used here.
    //    However, these are not available for HIP backend.
    switch(index_type)
    {
    case miopenIndexUint8: { return std::numeric_limits<uint8_t>::max();
    }
    case miopenIndexUint16: { return std::numeric_limits<uint16_t>::max();
    }
    case miopenIndexUint32: { return std::numeric_limits<uint32_t>::max();
    }
    case miopenIndexUint64: { return std::numeric_limits<uint64_t>::max();
    }
    }

    MIOPEN_THROW("not belong to any case");
}

inline std::string GetDataTypeKernelParams(miopenDataType_t type)
{
    // values for MIOPEN_USE_ macros
    int use_fp16               = 0;
    int use_fp32               = 0;
    int use_int8               = 0;
    int use_int8x4             = 0;
    int use_int32              = 0;
    int use_bfp16              = 0;
    const int use_rne_bfloat16 = MIOPEN_USE_RNE_BFLOAT16;

    switch(type)
    {
    case miopenHalf: use_fp16      = 1; break;
    case miopenFloat: use_fp32     = 1; break;
    case miopenInt8: use_int8      = 1; break;
    case miopenInt8x4: use_int8x4  = 1; break;
    case miopenBFloat16: use_bfp16 = 1; break;
    case miopenInt32: use_int32    = 1; break;
    default:
        MIOPEN_THROW("Only float, half, bfloat16, int8, int8x4 data type is supported.");
        break;
    }

    std::ostringstream ss;
    ss << " -DMIOPEN_USE_FP16=" << use_fp16;
    ss << " -DMIOPEN_USE_FP32=" << use_fp32;
    ss << " -DMIOPEN_USE_INT8=" << use_int8;
    ss << " -DMIOPEN_USE_INT8x4=" << use_int8x4;
    ss << " -DMIOPEN_USE_BFP16=" << use_bfp16;
    ss << " -DMIOPEN_USE_INT32=" << use_int32;
    ss << " -DMIOPEN_USE_RNE_BFLOAT16=" << use_rne_bfloat16;
    return ss.str();
}

} // namespace miopen

#endif // GUARD_MIOPEN_DATATYPE_HPP
<|endoftext|>