<commit_before>/*===========================================================================*
 * This file is part of the BiCePS Linear Integer Solver (BLIS).             *
 *                                                                           *
 * BLIS is distributed under the Eclipse Public License as part of the       *
 * COIN-OR repository (http://www.coin-or.org).                              *
 *                                                                           *
 * Authors:                                                                  *
 *                                                                           *
 *          Yan Xu, Lehigh University                                        *
 *          Ted Ralphs, Lehigh University                                    *
 *                                                                           *
 * Conceptual Design:                                                        *
 *                                                                           *
 *          Yan Xu, Lehigh University                                        *
 *          Ted Ralphs, Lehigh University                                    *
 *          Laszlo Ladanyi, IBM T.J. Watson Research Center                  *
 *          Matthew Saltzman, Clemson University                             *
 *                                                                           *
 *                                                                           *
 * Copyright (C) 2001-2015, Lehigh University, Yan Xu, and Ted Ralphs.       *
 * All Rights Reserved.                                                      *
 *===========================================================================*/

#include <iostream>

#include "CoinError.hpp"
#include "CoinTime.hpp"

#include "OsiConicSolverInterface.hpp"
#include "OsiMosekSolverInterface.hpp"
#include "OsiCplexSolverInterface.hpp"
#include "ColaModel.hpp"
//#ifdef COIN_HAS_CLP
#include "OsiClpSolverInterface.hpp"
//#endif

#include "CglFlowCover.hpp"
#include "CglGomory.hpp"
#include "CglProbing.hpp"
#include "CglKnapsackCover.hpp"
#include "CglOddHole.hpp"

#include "DcoConfig.hpp"
#include "DcoModel.hpp"

#if  COIN_HAS_MPI
#include "AlpsKnowledgeBrokerMPI.h"
#else
#include "AlpsKnowledgeBrokerSerial.h"
#endif

// NOTE: gcc compiler doesn't recognize COIN_HAS_CLP, COIN_HAS_MPI

//#############################################################################

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

	try{
	  //Set up lp solver
	  // OsiConicSolverInterface * solver = new ColaModel();
	  // solver.getModelPtr()->setDualBound(1.0e10);
	  // solver.messageHandler()->setLogLevel(0);

	  // if both mosek and cplex is available, choose mosek.
	  // if both not available then choose cola
#if defined(__OSI_MOSEK__)
	  OsiConicSolverInterface * solver = new OsiMosekSolverInterface();
#else
#if defined(__OSI_CPLEX__)
	  OsiConicSolverInterface * solver = new OsiCplexSolverInterface();
#else
#if defined(__COLA__)
	  OsiConicSolverInterface * solver = new ColaModel();
#endif
#endif
#endif
	  // Create DisCO model
	  DcoModel model;
	  model.setSolver(solver);

#ifdef  COIN_HAS_MPI
		AlpsKnowledgeBrokerMPI broker(argc, argv, model);
#else
		AlpsKnowledgeBrokerSerial broker(argc, argv, model);
#endif

		// Search for best solution
		broker.search(&model);

		// Report the best solution found and its ojective value
		broker.printBestSolution();
 }

	catch(CoinError& er) {
 	std::cerr << "\nDISCO ERROR: \"" << er.message()
		  << "\""<< std::endl
		  << "             from function \"" << er.methodName()
		  << "\""<< std::endl
		  << "             from class \"" << er.className()
		  << "\"" << std::endl;
	}
  catch(...) {
		std::cerr << "Something went wrong!" << std::endl;
  }

  return 0;
}

//#############################################################################

<commit_msg>format update<commit_after>/*===========================================================================*
 * This file is part of the BiCePS Linear Integer Solver (BLIS).             *
 *                                                                           *
 * BLIS is distributed under the Eclipse Public License as part of the       *
 * COIN-OR repository (http://www.coin-or.org).                              *
 *                                                                           *
 * Authors:                                                                  *
 *                                                                           *
 *          Yan Xu, Lehigh University                                        *
 *          Ted Ralphs, Lehigh University                                    *
 *                                                                           *
 * Conceptual Design:                                                        *
 *                                                                           *
 *          Yan Xu, Lehigh University                                        *
 *          Ted Ralphs, Lehigh University                                    *
 *          Laszlo Ladanyi, IBM T.J. Watson Research Center                  *
 *          Matthew Saltzman, Clemson University                             *
 *                                                                           *
 *                                                                           *
 * Copyright (C) 2001-2015, Lehigh University, Yan Xu, and Ted Ralphs.       *
 * All Rights Reserved.                                                      *
 *===========================================================================*/

#include <iostream>

#include "CoinError.hpp"
#include "CoinTime.hpp"

#include "OsiConicSolverInterface.hpp"
#include "OsiMosekSolverInterface.hpp"
#include "OsiCplexSolverInterface.hpp"
#include "ColaModel.hpp"
//#ifdef COIN_HAS_CLP
#include "OsiClpSolverInterface.hpp"
//#endif

#include "CglFlowCover.hpp"
#include "CglGomory.hpp"
#include "CglProbing.hpp"
#include "CglKnapsackCover.hpp"
#include "CglOddHole.hpp"

#include "DcoConfig.hpp"
#include "DcoModel.hpp"

#if  COIN_HAS_MPI
#include "AlpsKnowledgeBrokerMPI.h"
#else
#include "AlpsKnowledgeBrokerSerial.h"
#endif

// NOTE: gcc compiler doesn't recognize COIN_HAS_CLP, COIN_HAS_MPI

//#############################################################################

int main(int argc, char *argv[]) {
  try {
    //Set up lp solver
    // OsiConicSolverInterface * solver = new ColaModel();
    // solver.getModelPtr()->setDualBound(1.0e10);
    // solver.messageHandler()->setLogLevel(0);

    // if both mosek and cplex is available, choose mosek.
    // if both not available then choose cola
#if defined(__OSI_MOSEK__)
    OsiConicSolverInterface * solver = new OsiMosekSolverInterface();
#else
#if defined(__OSI_CPLEX__)
    OsiConicSolverInterface * solver = new OsiCplexSolverInterface();
#else
#if defined(__COLA__)
    OsiConicSolverInterface * solver = new ColaModel();
#endif
#endif
#endif
    // Create DisCO model
    DcoModel model;
    model.setSolver(solver);

#ifdef  COIN_HAS_MPI
    AlpsKnowledgeBrokerMPI broker(argc, argv, model);
#else
    AlpsKnowledgeBrokerSerial broker(argc, argv, model);
#endif
    // Search for best solution
    broker.search(&model);
    // Report the best solution found and its ojective value
    broker.printBestSolution();
  }
  catch(CoinError& er) {
    std::cerr << "\nDISCO ERROR: \"" << er.message()
	      << "\""<< std::endl
	      << "             from function \"" << er.methodName()
	      << "\""<< std::endl
	      << "             from class \"" << er.className()
	      << "\"" << std::endl;
  }
  catch(...) {
    std::cerr << "Something went wrong!" << std::endl;
  }
  return 0;
}
//#############################################################################
<|endoftext|>


<commit_before>// DepthOp.cpp
/*
 * Copyright (c) 2009, Dan Heeks
 * This program is released under the BSD license. See the file COPYING for
 * details.
 */

#include "stdafx.h"
#include "DepthOp.h"
#include "CNCConfig.h"
#include "ProgramCanvas.h"
#include "Program.h"
#include "interface/PropertyInt.h"
#include "interface/PropertyDouble.h"
#include "interface/PropertyLength.h"
#include "tinyxml/tinyxml.h"
#include "interface/Tool.h"

CDepthOpParams::CDepthOpParams()
{
	m_tool_number = 0;
	m_tool_diameter = 0.0;
	m_clearance_height = 0.0;
	m_start_depth = 0.0;
	m_step_down = 0.0;
	m_final_depth = 0.0;
	m_rapid_down_to_height = 0.0;
	m_horizontal_feed_rate = 0.0;
	m_vertical_feed_rate = 0.0;
	m_spindle_speed = 0.0;
}

void CDepthOpParams::set_initial_values()
{
	CNCConfig config;
    config.Read(_T("DepthFixtureOffset"), &m_workplane,1);
	config.Read(_T("DepthOpToolNumber"), &m_tool_number, 1);
	config.Read(_T("DepthOpToolDiameter"), &m_tool_diameter, 3.0);
	config.Read(_T("DepthOpClearanceHeight"), &m_clearance_height, 5.0);
	config.Read(_T("DepthOpStartDepth"), &m_start_depth, 0.0);
	config.Read(_T("DepthOpStepDown"), &m_step_down, 1.0);
	config.Read(_T("DepthOpFinalDepth"), &m_final_depth, -1.0);
	config.Read(_T("DepthOpRapidDown"), &m_rapid_down_to_height, 2.0);
	config.Read(_T("DepthOpHorizFeed"), &m_horizontal_feed_rate, 100.0);
	config.Read(_T("DepthOpVertFeed"), &m_vertical_feed_rate, 100.0);
	config.Read(_T("DepthOpSpindleSpeed"), &m_spindle_speed, 7000);
}

void CDepthOpParams::write_values_to_config()
{
	CNCConfig config;
	config.Write(_T("DepthFixtureOffset"), m_workplane);
	config.Write(_T("DepthOpToolNumber"), m_tool_number);
	config.Write(_T("DepthOpToolDiameter"), m_tool_diameter);
	config.Write(_T("DepthOpClearanceHeight"), m_clearance_height);
	config.Write(_T("DepthOpStartDepth"), m_start_depth);
	config.Write(_T("DepthOpStepDown"), m_step_down);
	config.Write(_T("DepthOpFinalDepth"), m_final_depth);
	config.Write(_T("DepthOpRapidDown"), m_rapid_down_to_height);
	config.Write(_T("DepthOpHorizFeed"), m_horizontal_feed_rate);
	config.Write(_T("DepthOpVertFeed"), m_vertical_feed_rate);
	config.Write(_T("DepthOpSpindleSpeed"), m_spindle_speed);
}

static void on_set_workplane(int value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_workplane = value;}
static void on_set_tool_number(int value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_tool_number = value;}
static void on_set_tool_diameter(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_tool_diameter = value;}
static void on_set_clearance_height(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_clearance_height = value;}
static void on_set_step_down(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_step_down = value;}
static void on_set_start_depth(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_start_depth = value;}
static void on_set_final_depth(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_final_depth = value;}
static void on_set_rapid_down_to_height(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_rapid_down_to_height = value;}
static void on_set_horizontal_feed_rate(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_horizontal_feed_rate = value;}
static void on_set_vertical_feed_rate(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_vertical_feed_rate = value;}
static void on_set_spindle_speed(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_spindle_speed = value;}

void CDepthOpParams::GetProperties(CDepthOp* parent, std::list<Property *> *list)
{
	list->push_back(new PropertyInt(_("fixture offset"), m_workplane, parent, on_set_workplane));
	list->push_back(new PropertyInt(_("tool number"), m_tool_number, parent, on_set_tool_number));
	list->push_back(new PropertyLength(_("tool diameter"), m_tool_diameter, parent, on_set_tool_diameter));
	list->push_back(new PropertyLength(_("clearance height"), m_clearance_height, parent, on_set_clearance_height));
	list->push_back(new PropertyLength(_("step down"), m_step_down, parent, on_set_step_down));
	list->push_back(new PropertyLength(_("start depth"), m_start_depth, parent, on_set_start_depth));
	list->push_back(new PropertyLength(_("final depth"), m_final_depth, parent, on_set_final_depth));
	list->push_back(new PropertyLength(_("rapid down to height"), m_rapid_down_to_height, parent, on_set_rapid_down_to_height));
	list->push_back(new PropertyDouble(_("horizontal feed rate"), m_horizontal_feed_rate, parent, on_set_horizontal_feed_rate));
	list->push_back(new PropertyDouble(_("vertical feed rate"), m_vertical_feed_rate, parent, on_set_vertical_feed_rate));
	list->push_back(new PropertyDouble(_("spindle speed"), m_spindle_speed, parent, on_set_spindle_speed));
}

void CDepthOpParams::WriteXMLAttributes(TiXmlNode* pElem)
{
	TiXmlElement * element = new TiXmlElement( "depthop" );
	pElem->LinkEndChild( element );
	element->SetAttribute("fixture offset", m_workplane);
	element->SetAttribute("tooln", m_tool_number);
	element->SetDoubleAttribute("toold", m_tool_diameter);
	element->SetDoubleAttribute("clear", m_clearance_height);
	element->SetDoubleAttribute("down", m_step_down);
	element->SetDoubleAttribute("startdepth", m_start_depth);
	element->SetDoubleAttribute("depth", m_final_depth);
	element->SetDoubleAttribute("r", m_rapid_down_to_height);
	element->SetDoubleAttribute("hfeed", m_horizontal_feed_rate);
	element->SetDoubleAttribute("vfeed", m_vertical_feed_rate);
	element->SetDoubleAttribute("spin", m_spindle_speed);
}

void CDepthOpParams::ReadFromXMLElement(TiXmlElement* pElem)
{
	TiXmlElement* depthop = TiXmlHandle(pElem).FirstChildElement("depthop").Element();
	if(depthop)
	{

		depthop->Attribute("fixture offset", &m_workplane);
		depthop->Attribute("tooln", &m_tool_number);
		depthop->Attribute("toold", &m_tool_diameter);
		depthop->Attribute("clear", &m_clearance_height);
		depthop->Attribute("down", &m_step_down);
		depthop->Attribute("startdepth", &m_start_depth);
		depthop->Attribute("depth", &m_final_depth);
		depthop->Attribute("r", &m_rapid_down_to_height);
		depthop->Attribute("hfeed", &m_horizontal_feed_rate);
		depthop->Attribute("vfeed", &m_vertical_feed_rate);
		depthop->Attribute("spin", &m_spindle_speed);
	}
}

void CDepthOp::WriteBaseXML(TiXmlElement *element)
{
	m_depth_op_params.WriteXMLAttributes(element);
	COp::WriteBaseXML(element);
}

void CDepthOp::ReadBaseXML(TiXmlElement* element)
{
	m_depth_op_params.ReadFromXMLElement(element);
	COp::ReadBaseXML(element);
}

void CDepthOp::GetProperties(std::list<Property *> *list)
{
	m_depth_op_params.GetProperties(this, list);
	COp::GetProperties(list);
}

void CDepthOp::AppendTextToProgram()
{
	COp::AppendTextToProgram();

	theApp.m_program_canvas->AppendText(_T("clearance = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_clearance_height / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("rapid_down_to_height = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_rapid_down_to_height / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("start_depth = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_start_depth / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("step_down = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_step_down / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("final_depth = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_final_depth / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("tool_diameter = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_tool_diameter / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("spindle("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_spindle_speed);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("feedrate_hv("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_horizontal_feed_rate);
	theApp.m_program_canvas->AppendText(_T(", "));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_vertical_feed_rate);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("tool_change("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_tool_number);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("workplane("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_workplane);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("flush_nc()\n"));

}

<commit_msg>the xml file didn't like 'fixture offset'-changed to 'fixture_offset'<commit_after>// DepthOp.cpp
/*
 * Copyright (c) 2009, Dan Heeks
 * This program is released under the BSD license. See the file COPYING for
 * details.
 */

#include "stdafx.h"
#include "DepthOp.h"
#include "CNCConfig.h"
#include "ProgramCanvas.h"
#include "Program.h"
#include "interface/PropertyInt.h"
#include "interface/PropertyDouble.h"
#include "interface/PropertyLength.h"
#include "tinyxml/tinyxml.h"
#include "interface/Tool.h"

CDepthOpParams::CDepthOpParams()
{
	m_tool_number = 0;
	m_tool_diameter = 0.0;
	m_clearance_height = 0.0;
	m_start_depth = 0.0;
	m_step_down = 0.0;
	m_final_depth = 0.0;
	m_rapid_down_to_height = 0.0;
	m_horizontal_feed_rate = 0.0;
	m_vertical_feed_rate = 0.0;
	m_spindle_speed = 0.0;
}

void CDepthOpParams::set_initial_values()
{
	CNCConfig config;
    config.Read(_T("DepthFixtureOffset"), &m_workplane,1);
	config.Read(_T("DepthOpToolNumber"), &m_tool_number, 1);
	config.Read(_T("DepthOpToolDiameter"), &m_tool_diameter, 3.0);
	config.Read(_T("DepthOpClearanceHeight"), &m_clearance_height, 5.0);
	config.Read(_T("DepthOpStartDepth"), &m_start_depth, 0.0);
	config.Read(_T("DepthOpStepDown"), &m_step_down, 1.0);
	config.Read(_T("DepthOpFinalDepth"), &m_final_depth, -1.0);
	config.Read(_T("DepthOpRapidDown"), &m_rapid_down_to_height, 2.0);
	config.Read(_T("DepthOpHorizFeed"), &m_horizontal_feed_rate, 100.0);
	config.Read(_T("DepthOpVertFeed"), &m_vertical_feed_rate, 100.0);
	config.Read(_T("DepthOpSpindleSpeed"), &m_spindle_speed, 7000);
}

void CDepthOpParams::write_values_to_config()
{
	CNCConfig config;
	config.Write(_T("DepthFixtureOffset"), m_workplane);
	config.Write(_T("DepthOpToolNumber"), m_tool_number);
	config.Write(_T("DepthOpToolDiameter"), m_tool_diameter);
	config.Write(_T("DepthOpClearanceHeight"), m_clearance_height);
	config.Write(_T("DepthOpStartDepth"), m_start_depth);
	config.Write(_T("DepthOpStepDown"), m_step_down);
	config.Write(_T("DepthOpFinalDepth"), m_final_depth);
	config.Write(_T("DepthOpRapidDown"), m_rapid_down_to_height);
	config.Write(_T("DepthOpHorizFeed"), m_horizontal_feed_rate);
	config.Write(_T("DepthOpVertFeed"), m_vertical_feed_rate);
	config.Write(_T("DepthOpSpindleSpeed"), m_spindle_speed);
}

static void on_set_workplane(int value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_workplane = value;}
static void on_set_tool_number(int value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_tool_number = value;}
static void on_set_tool_diameter(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_tool_diameter = value;}
static void on_set_clearance_height(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_clearance_height = value;}
static void on_set_step_down(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_step_down = value;}
static void on_set_start_depth(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_start_depth = value;}
static void on_set_final_depth(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_final_depth = value;}
static void on_set_rapid_down_to_height(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_rapid_down_to_height = value;}
static void on_set_horizontal_feed_rate(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_horizontal_feed_rate = value;}
static void on_set_vertical_feed_rate(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_vertical_feed_rate = value;}
static void on_set_spindle_speed(double value, HeeksObj* object){((CDepthOp*)object)->m_depth_op_params.m_spindle_speed = value;}

void CDepthOpParams::GetProperties(CDepthOp* parent, std::list<Property *> *list)
{
	list->push_back(new PropertyInt(_("fixture offset"), m_workplane, parent, on_set_workplane));
	list->push_back(new PropertyInt(_("tool number"), m_tool_number, parent, on_set_tool_number));
	list->push_back(new PropertyLength(_("tool diameter"), m_tool_diameter, parent, on_set_tool_diameter));
	list->push_back(new PropertyLength(_("clearance height"), m_clearance_height, parent, on_set_clearance_height));
	list->push_back(new PropertyLength(_("step down"), m_step_down, parent, on_set_step_down));
	list->push_back(new PropertyLength(_("start depth"), m_start_depth, parent, on_set_start_depth));
	list->push_back(new PropertyLength(_("final depth"), m_final_depth, parent, on_set_final_depth));
	list->push_back(new PropertyLength(_("rapid down to height"), m_rapid_down_to_height, parent, on_set_rapid_down_to_height));
	list->push_back(new PropertyDouble(_("horizontal feed rate"), m_horizontal_feed_rate, parent, on_set_horizontal_feed_rate));
	list->push_back(new PropertyDouble(_("vertical feed rate"), m_vertical_feed_rate, parent, on_set_vertical_feed_rate));
	list->push_back(new PropertyDouble(_("spindle speed"), m_spindle_speed, parent, on_set_spindle_speed));
}

void CDepthOpParams::WriteXMLAttributes(TiXmlNode* pElem)
{
	TiXmlElement * element = new TiXmlElement( "depthop" );
	pElem->LinkEndChild( element );
	element->SetAttribute("fixture_offset", m_workplane);
	element->SetAttribute("tooln", m_tool_number);
	element->SetDoubleAttribute("toold", m_tool_diameter);
	element->SetDoubleAttribute("clear", m_clearance_height);
	element->SetDoubleAttribute("down", m_step_down);
	element->SetDoubleAttribute("startdepth", m_start_depth);
	element->SetDoubleAttribute("depth", m_final_depth);
	element->SetDoubleAttribute("r", m_rapid_down_to_height);
	element->SetDoubleAttribute("hfeed", m_horizontal_feed_rate);
	element->SetDoubleAttribute("vfeed", m_vertical_feed_rate);
	element->SetDoubleAttribute("spin", m_spindle_speed);
}

void CDepthOpParams::ReadFromXMLElement(TiXmlElement* pElem)
{
	TiXmlElement* depthop = TiXmlHandle(pElem).FirstChildElement("depthop").Element();
	if(depthop)
	{

		depthop->Attribute("fixture offset", &m_workplane);
		depthop->Attribute("tooln", &m_tool_number);
		depthop->Attribute("toold", &m_tool_diameter);
		depthop->Attribute("clear", &m_clearance_height);
		depthop->Attribute("down", &m_step_down);
		depthop->Attribute("startdepth", &m_start_depth);
		depthop->Attribute("depth", &m_final_depth);
		depthop->Attribute("r", &m_rapid_down_to_height);
		depthop->Attribute("hfeed", &m_horizontal_feed_rate);
		depthop->Attribute("vfeed", &m_vertical_feed_rate);
		depthop->Attribute("spin", &m_spindle_speed);
	}
}

void CDepthOp::WriteBaseXML(TiXmlElement *element)
{
	m_depth_op_params.WriteXMLAttributes(element);
	COp::WriteBaseXML(element);
}

void CDepthOp::ReadBaseXML(TiXmlElement* element)
{
	m_depth_op_params.ReadFromXMLElement(element);
	COp::ReadBaseXML(element);
}

void CDepthOp::GetProperties(std::list<Property *> *list)
{
	m_depth_op_params.GetProperties(this, list);
	COp::GetProperties(list);
}

void CDepthOp::AppendTextToProgram()
{
	COp::AppendTextToProgram();

	theApp.m_program_canvas->AppendText(_T("clearance = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_clearance_height / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("rapid_down_to_height = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_rapid_down_to_height / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("start_depth = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_start_depth / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("step_down = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_step_down / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("final_depth = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_final_depth / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("tool_diameter = float("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_tool_diameter / theApp.m_program->m_units);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("spindle("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_spindle_speed);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("feedrate_hv("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_horizontal_feed_rate);
	theApp.m_program_canvas->AppendText(_T(", "));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_vertical_feed_rate);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("tool_change("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_tool_number);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("workplane("));
	theApp.m_program_canvas->AppendText(m_depth_op_params.m_workplane);
	theApp.m_program_canvas->AppendText(_T(")\n"));
	theApp.m_program_canvas->AppendText(_T("flush_nc()\n"));

}

<|endoftext|>


<commit_before>//
// Created by Austin on 6/11/2015.
//

#include "Display.hpp"
#include "Processor.hpp"
#include "MemoryManagementUnit.hpp"

#include <iostream>

Display::Display() {
    Reset();
}

/**
 * Initializes references to other Gameboy components
 */
void Display::Initialize(Processor* cpu_, MemoryManagementUnit* mmu_) {
    cpu = cpu_;
    mmu = mmu_;
}

void Display::Reset() {
	frame = sf::Image();
    frame.create(160, 144);

    background = std::vector<sf::Color>(256*256, sf::Color::White);
    show_background = std::vector<bool>(256*256, false);

    window = std::vector<sf::Color>(256*256, sf::Color::White);
    show_window = std::vector<bool>(256*256, false);

    sprite_map = std::vector<sf::Color>(256*256, sf::Color::White);
    show_sprite = std::vector<bool>(256*256, false);
}

/**
 * Returns the current frame for the GameBoy screen.
 */
sf::Image Display::RenderFrame() {
    // Draw background onto frame, then add window and sprite
    uint8_t scroll_y = mmu->ReadByte(0xFF42);
    uint8_t scroll_x = mmu->ReadByte(0xFF43);

    for (int x = 0; x < 160; ++x) {
        int x_offset = scroll_x;
        if (x+x_offset >= 256) {
            x_offset -= 256;
        }
        for (int y = 0; y < 144; ++y) {
            int y_offset = scroll_y;
            if (y+y_offset >= 256) {
                y_offset -= 256;
            }
            if (show_background[(y+y_offset)*256+(x+x_offset)]) {
                frame.setPixel(x, y, background[(y+y_offset)*256+(x+x_offset)]);
            }
        }
    }

    // Draw Window now
    scroll_y = mmu->ReadByte(0xFF4A);
    scroll_x = mmu->ReadByte(0xFF4B);

    for (int x = 0; x < 160; ++x) {
        int x_offset = static_cast<int>(scroll_x)-7;
        for (int y = 0; y < 144; ++y) {
            int y_offset = scroll_y;
            if (x+x_offset >= 0 and x+x_offset < 256 and y+y_offset >= 0 and y+y_offset < 256) {
                if (show_window[(y+y_offset)*256+(x+x_offset)]) {
                    frame.setPixel(x, y, window[(y+y_offset)*256+(x+x_offset)]);
                }
            }
        }
    }

    // Draw Sprites
    for (int x = 0; x < 160; ++x) {
        for (int y = 0; y < 144; ++y) {
            if (show_sprite[y*256 + x]) {
                frame.setPixel(x, y, sprite_map[y * 256 + x]);
            }
        }
    }

    // Reset frames
    show_background = std::vector<bool>(256*256, false);
    show_window = std::vector<bool>(256*256, false);

    return frame;
}

/**
 * Renders the current scanline.
 */
void Display::RenderScanline(uint8_t line_number) {
    // First draw background (if enabled)
    uint8_t lcd_control = mmu->zram[0xFF40&0xFF];
    if (lcd_control & 0x01) {
        DrawBackground(lcd_control, line_number);
    }

    // Then draw Window
    if ((lcd_control & 0x20) and (lcd_control & 0x01)) { // I believe both need to be set to draw Window
        DrawWindow(lcd_control, line_number);
    }

    // Finally draw Sprites
    if (lcd_control & 0x02) {
        DrawSprites(lcd_control, line_number);
    }
}

/**
 * Updates Background vector for current scanline of background.
 */
void Display::DrawBackground(uint8_t lcd_control, uint8_t line_number) {
    // Determine if using tile map 0 or 1
    uint16_t tile_map_address;
    if ((lcd_control & 0x08) == 0) {
        tile_map_address = 0x9800; // tile map #0
    } else {
        tile_map_address = 0x9c00; // tile map #1
    }

    // Determine if using tile set 0 or 1
    uint16_t tile_set_address;
    int tile_set_offset;
    if ((lcd_control & 0x10) == 0) {
        tile_set_address = 0x8800; // tile set #0
        tile_set_offset = -128;
    } else {
        tile_set_address = 0x8000; // tile set #1
        tile_set_offset = 0;
    }

    // Determine which tile row and line of tile to draw
    uint8_t row = static_cast<uint8_t>(std::floor(static_cast<double>(line_number) / 8.0));
    uint8_t tile_row = line_number % 8;
    for (std::size_t x = 0; x < 32; ++x) {
        uint8_t tile_number = mmu->ReadByte(tile_map_address + (32*row+x));
        uint16_t tile_address = tile_set_address - tile_set_offset + tile_number*16;

        DrawTilePattern(background, show_background, x, row, tile_row, tile_address);
    }
}

/**
 * Updates frame buffer for current scanline of Window.
 */
void Display::DrawWindow(uint8_t lcd_control, uint8_t line_number) {
    // Determine if using tile map 0 or 1
    uint16_t tile_map_address;
    if ((lcd_control & 0x40) == 0) {
        tile_map_address = 0x9800; // tile map #0
    } else {
        tile_map_address = 0x9c00; // tile map #1
    }

    // Determine if using tile set 0 or 1
    uint16_t tile_set_address;
    int tile_set_offset;
    if ((lcd_control & 0x10) == 0) {
        tile_set_address = 0x8800; // tile set #0
        tile_set_offset = -128;
    } else {
        tile_set_address = 0x8000; // tile set #1
        tile_set_offset = 0;
    }

    // Determine which tile row and line of tile to draw
    uint8_t row = static_cast<uint8_t>(std::floor(static_cast<double>(line_number) / 8.0));
    uint8_t tile_row = line_number % 8;
    for (std::size_t x = 0; x < 32; ++x) {
        uint8_t tile_number = mmu->ReadByte(tile_map_address + (32*row+x));
        uint16_t tile_address = tile_set_address - tile_set_offset + tile_number*16;

        DrawTilePattern(window, show_window, x, row, tile_row, tile_address);
    }
}

void Display::DrawSprites(uint8_t lcd_control, uint8_t line_number) {
    uint16_t oam_table_address = 0xFE00;
    uint16_t sprite_pattern_table = 0x8000; // Unsigned numbering

    uint8_t sprite_height = (lcd_control & 0x04)?16:8; // Height of each sprite in pixels

    // Iterate through all 40 sprites, drawing the first 10 on the current line_number
    //std::cout << "New draw" << std::endl;
    std::vector<Sprite> sprites;
    for (int sprite = 0; sprite < 40; ++sprite) {
        // TODO: It's far more efficient to only read y_position and read the rest after determining if it's on the scanline
        // Each sprite is made up of 4 attributes
        uint8_t y_position = mmu->ReadByte(oam_table_address+sprite*4+0);
        uint8_t x_position = mmu->ReadByte(oam_table_address+sprite*4+1);
        uint8_t tile_number = mmu->ReadByte(oam_table_address+sprite*4+2);
        uint8_t attributes = mmu->ReadByte(oam_table_address+sprite*4+3);
        //if (sprite == 0)
        //    std::cout << "Sprite number and tile number: " << std::hex << static_cast<unsigned int>(sprite) << ", " << static_cast<unsigned int>(tile_number) << ", at address: " << static_cast<unsigned int>(oam_table_address+sprite*4+2) << std::endl;

        bool y_flip = (attributes & 0x40)?true:false;
        bool x_flip = (attributes & 0x20)?true:false;
        bool draw_priority = (attributes & 0x80)?true:false; // If true, don't draw over background/window colors 1-3
                                                             // TODO: Might need to create another bool vector for this
        uint8_t palette = (attributes & 0x10)?mmu->ReadByte(0xFF49):mmu->ReadByte(0xFF48); // Which palette to use

        // If on the scanline, add to sprites vector
        if (y_position >= line_number and y_position < line_number + sprite_height) {
            // Construct the sprite and add it to sprites
            Sprite new_sprite;
            new_sprite.x = x_position;
            new_sprite.y = y_position;
            new_sprite.tile_number = tile_number;
            new_sprite.attributes = attributes;
            new_sprite.x_flip = x_flip;
            new_sprite.y_flip = y_flip;
            new_sprite.draw_priority = draw_priority;
            new_sprite.palette = palette;
            new_sprite.height = sprite_height;

            sprites.push_back(new_sprite);
        }
    }

    // Sort each sprite by its x position (the lowest x position is drawn last)
    std::sort(sprites.begin(), sprites.end(),
        [](Sprite const& first, Sprite const& second) -> bool {
            return first.x < second.x;
        });

    // Draw the last 10 sprites
    //std::cout << "Start drawing" << std::endl;
    for (int index = sprites.size()-1; (index > 0) and (index > sprites.size()-11); --index) {
        if (index < 0) break;

        uint16_t tile_address = sprite_pattern_table + sprites[index].tile_number*16;

        //std::cout << "Drawing sprites with tile number: " << index << ", " << std::hex << static_cast<unsigned int>(sprites[index].tile_number) << std::endl;
        DrawTilePattern(sprite_map, show_sprite, sprites[index].x, sprites[index].y, line_number - sprites[index].x, tile_address, true);
    }
}

void Display::DrawTilePattern(std::vector<sf::Color>& map, std::vector<bool>& show_map, std::size_t x, std::size_t y, std::size_t tile_x, uint16_t tile_address, bool is_sprite) {
    uint16_t line = tile_address + 2*tile_x;
    // A line is made up of two bytes
    uint8_t line_0 = mmu->ReadByte(line);
    uint8_t line_1 = mmu->ReadByte(line+1);
    for (int bit = 7; bit >= 0; --bit) {
        bool bit_0 = line_0 & (0x1<<bit);
        bool bit_1 = line_1 & (0x1<<bit);

        int color;
        if (!bit_1 and !bit_0) {
            color = 0;
        } else if (!bit_1 and bit_0) {
            color = 1;
        } else if (bit_1 and !bit_0) {
            color = 2;
        } else {
            color = 3;
        }

        // Create a palette conversion
        uint8_t palette = mmu->zram[0x47];
        sf::Color white;
        sf::Color light_gray;
        sf::Color dark_gray;
        sf::Color black;
        for (uint8_t bits = 0; bits < 7; bits+=2) {
            uint8_t bit0 = (palette & (1<<bits))>>bits;
            uint8_t bit1 = (palette & (1<<(bits+1)))>>(bits+1);
            uint8_t value = bit0 + (bit1 << 1);

            sf::Color new_color;
            if (value == 0x00) {
                new_color = kBlack;
            } else if (value == 0x01) {
                new_color = kDarkGray;
            } else if (value == 0x02) {
                new_color = kLightGray;
            } else if (value == 0x03) {
                new_color = kWhite;
            }

            if (bits == 0) {
                black = new_color;
            } else if (bits == 2) {
                dark_gray = new_color;
            } else if (bits == 4) {
                light_gray = new_color;
            } else if (bits == 6) {
                white = new_color;
            }
        }

        std::size_t x_pixel = x*8 + 7-bit;
        std::size_t y_pixel = (y*8+tile_x);
        if (color == 0) {
            map[y_pixel*256+x_pixel] = white;
        } else if (color == 1) {
            map[y_pixel*256+x_pixel] = light_gray;
        } else if (color == 2) {
            map[y_pixel*256+x_pixel] = dark_gray;
        } else {
            map[y_pixel*256+x_pixel] = black;
        }

        show_map[y_pixel*256+x_pixel] = true;
    }
}<commit_msg>Add Sprite -8,-16 offset<commit_after>//
// Created by Austin on 6/11/2015.
//

#include "Display.hpp"
#include "Processor.hpp"
#include "MemoryManagementUnit.hpp"

#include <iostream>

Display::Display() {
    Reset();
}

/**
 * Initializes references to other Gameboy components
 */
void Display::Initialize(Processor* cpu_, MemoryManagementUnit* mmu_) {
    cpu = cpu_;
    mmu = mmu_;
}

void Display::Reset() {
	frame = sf::Image();
    frame.create(160, 144);

    background = std::vector<sf::Color>(256*256, sf::Color::White);
    show_background = std::vector<bool>(256*256, false);

    window = std::vector<sf::Color>(256*256, sf::Color::White);
    show_window = std::vector<bool>(256*256, false);

    sprite_map = std::vector<sf::Color>(256*256, sf::Color::White);
    show_sprite = std::vector<bool>(256*256, false);
}

/**
 * Returns the current frame for the GameBoy screen.
 */
sf::Image Display::RenderFrame() {
    // Draw background onto frame, then add window and sprite
    uint8_t scroll_y = mmu->ReadByte(0xFF42);
    uint8_t scroll_x = mmu->ReadByte(0xFF43);

    for (int x = 0; x < 160; ++x) {
        int x_offset = scroll_x;
        if (x+x_offset >= 256) {
            x_offset -= 256;
        }
        for (int y = 0; y < 144; ++y) {
            int y_offset = scroll_y;
            if (y+y_offset >= 256) {
                y_offset -= 256;
            }
            if (show_background[(y+y_offset)*256+(x+x_offset)]) {
                frame.setPixel(x, y, background[(y+y_offset)*256+(x+x_offset)]);
            }
        }
    }

    // Draw Window now
    scroll_y = mmu->ReadByte(0xFF4A);
    scroll_x = mmu->ReadByte(0xFF4B);

    for (int x = 0; x < 160; ++x) {
        int x_offset = static_cast<int>(scroll_x)-7;
        for (int y = 0; y < 144; ++y) {
            int y_offset = scroll_y;
            if (x+x_offset >= 0 and x+x_offset < 256 and y+y_offset >= 0 and y+y_offset < 256) {
                if (show_window[(y+y_offset)*256+(x+x_offset)]) {
                    frame.setPixel(x, y, window[(y+y_offset)*256+(x+x_offset)]);
                }
            }
        }
    }

    // Draw Sprites
    for (int x = 0; x < 160; ++x) {
        for (int y = 0; y < 144; ++y) {
            if (show_sprite[y*256 + x]) {
                frame.setPixel(x, y, sprite_map[y * 256 + x]);
            }
        }
    }

    // Reset frames
    show_background = std::vector<bool>(256*256, false);
    show_window = std::vector<bool>(256*256, false);

    return frame;
}

/**
 * Renders the current scanline.
 */
void Display::RenderScanline(uint8_t line_number) {
    // First draw background (if enabled)
    uint8_t lcd_control = mmu->zram[0xFF40&0xFF];
    if (lcd_control & 0x01) {
        DrawBackground(lcd_control, line_number);
    }

    // Then draw Window
    if ((lcd_control & 0x20) and (lcd_control & 0x01)) { // I believe both need to be set to draw Window
        DrawWindow(lcd_control, line_number);
    }

    // Finally draw Sprites
    if (lcd_control & 0x02) {
        DrawSprites(lcd_control, line_number);
    }
}

/**
 * Updates Background vector for current scanline of background.
 */
void Display::DrawBackground(uint8_t lcd_control, uint8_t line_number) {
    // Determine if using tile map 0 or 1
    uint16_t tile_map_address;
    if ((lcd_control & 0x08) == 0) {
        tile_map_address = 0x9800; // tile map #0
    } else {
        tile_map_address = 0x9c00; // tile map #1
    }

    // Determine if using tile set 0 or 1
    uint16_t tile_set_address;
    int tile_set_offset;
    if ((lcd_control & 0x10) == 0) {
        tile_set_address = 0x8800; // tile set #0
        tile_set_offset = -128;
    } else {
        tile_set_address = 0x8000; // tile set #1
        tile_set_offset = 0;
    }

    // Determine which tile row and line of tile to draw
    uint8_t row = static_cast<uint8_t>(std::floor(static_cast<double>(line_number) / 8.0));
    uint8_t tile_row = line_number % 8;
    for (std::size_t x = 0; x < 32; ++x) {
        uint8_t tile_number = mmu->ReadByte(tile_map_address + (32*row+x));
        uint16_t tile_address = tile_set_address - tile_set_offset + tile_number*16;

        DrawTilePattern(background, show_background, x, row, tile_row, tile_address);
    }
}

/**
 * Updates frame buffer for current scanline of Window.
 */
void Display::DrawWindow(uint8_t lcd_control, uint8_t line_number) {
    // Determine if using tile map 0 or 1
    uint16_t tile_map_address;
    if ((lcd_control & 0x40) == 0) {
        tile_map_address = 0x9800; // tile map #0
    } else {
        tile_map_address = 0x9c00; // tile map #1
    }

    // Determine if using tile set 0 or 1
    uint16_t tile_set_address;
    int tile_set_offset;
    if ((lcd_control & 0x10) == 0) {
        tile_set_address = 0x8800; // tile set #0
        tile_set_offset = -128;
    } else {
        tile_set_address = 0x8000; // tile set #1
        tile_set_offset = 0;
    }

    // Determine which tile row and line of tile to draw
    uint8_t row = static_cast<uint8_t>(std::floor(static_cast<double>(line_number) / 8.0));
    uint8_t tile_row = line_number % 8;
    for (std::size_t x = 0; x < 32; ++x) {
        uint8_t tile_number = mmu->ReadByte(tile_map_address + (32*row+x));
        uint16_t tile_address = tile_set_address - tile_set_offset + tile_number*16;

        DrawTilePattern(window, show_window, x, row, tile_row, tile_address);
    }
}

void Display::DrawSprites(uint8_t lcd_control, uint8_t line_number) {
    uint16_t oam_table_address = 0xFE00;
    uint16_t sprite_pattern_table = 0x8000; // Unsigned numbering

    uint8_t sprite_height = (lcd_control & 0x04)?16:8; // Height of each sprite in pixels

    // Iterate through all 40 sprites, drawing the first 10 on the current line_number
    //std::cout << "New draw" << std::endl;
    std::vector<Sprite> sprites;
    for (int sprite = 0; sprite < 40; ++sprite) {
        // TODO: It's far more efficient to only read y_position and read the rest after determining if it's on the scanline
        // Each sprite is made up of 4 attributes
        uint8_t y_position = mmu->ReadByte(oam_table_address+sprite*4+0);
        uint8_t x_position = mmu->ReadByte(oam_table_address+sprite*4+1);
        uint8_t tile_number = mmu->ReadByte(oam_table_address+sprite*4+2);
        uint8_t attributes = mmu->ReadByte(oam_table_address+sprite*4+3);
        //if (sprite == 0)
        //    std::cout << "Sprite number and tile number: " << std::hex << static_cast<unsigned int>(sprite) << ", " << static_cast<unsigned int>(tile_number) << ", at address: " << static_cast<unsigned int>(oam_table_address+sprite*4+2) << std::endl;

        bool y_flip = (attributes & 0x40)?true:false;
        bool x_flip = (attributes & 0x20)?true:false;
        bool draw_priority = (attributes & 0x80)?true:false; // If true, don't draw over background/window colors 1-3
                                                             // TODO: Might need to create another bool vector for this
        uint8_t palette = (attributes & 0x10)?mmu->ReadByte(0xFF49):mmu->ReadByte(0xFF48); // Which palette to use

        // If on the scanline, add to sprites vector
        if (y_position <= line_number+16 and y_position+16 + sprite_height >= line_number) {
            // Construct the sprite and add it to sprites
            Sprite new_sprite;
            new_sprite.x = x_position;
            new_sprite.y = y_position;
            new_sprite.tile_number = tile_number;
            new_sprite.attributes = attributes;
            new_sprite.x_flip = x_flip;
            new_sprite.y_flip = y_flip;
            new_sprite.draw_priority = draw_priority;
            new_sprite.palette = palette;
            new_sprite.height = sprite_height;

            sprites.push_back(new_sprite);
        }
    }

    // Sort each sprite by its x position (the lowest x position is drawn last)
    std::sort(sprites.begin(), sprites.end(),
        [](Sprite const& first, Sprite const& second) -> bool {
            return first.x < second.x;
        });

    // Draw the last 10 sprites
    //std::cout << "Start drawing" << std::endl;
    for (int index = sprites.size()-1; (index > 0) and (index > sprites.size()-11); --index) {
        if (index < 0) break;

        uint16_t tile_address = sprite_pattern_table + sprites[index].tile_number*16;

        //std::cout << "Drawing sprites with tile number: " << index << ", " << std::hex << static_cast<unsigned int>(sprites[index].tile_number) << std::endl;
        DrawTilePattern(sprite_map, show_sprite, sprites[index].x, sprites[index].y, line_number - sprites[index].y, tile_address, true);
    }
}

void Display::DrawTilePattern(std::vector<sf::Color>& map, std::vector<bool>& show_map, std::size_t x, std::size_t y, std::size_t tile_x, uint16_t tile_address, bool is_sprite) {
    uint16_t line = tile_address + 2*tile_x;
    // A line is made up of two bytes
    uint8_t line_0 = mmu->ReadByte(line);
    uint8_t line_1 = mmu->ReadByte(line+1);
    for (int bit = 7; bit >= 0; --bit) {
        bool bit_0 = line_0 & (0x1<<bit);
        bool bit_1 = line_1 & (0x1<<bit);

        int color;
        if (!bit_1 and !bit_0) {
            color = 0;
        } else if (!bit_1 and bit_0) {
            color = 1;
        } else if (bit_1 and !bit_0) {
            color = 2;
        } else {
            color = 3;
        }

        // Create a palette conversion
        uint8_t palette = mmu->zram[0x47];
        sf::Color white;
        sf::Color light_gray;
        sf::Color dark_gray;
        sf::Color black;
        for (uint8_t bits = 0; bits < 7; bits+=2) {
            uint8_t bit0 = (palette & (1<<bits))>>bits;
            uint8_t bit1 = (palette & (1<<(bits+1)))>>(bits+1);
            uint8_t value = bit0 + (bit1 << 1);

            sf::Color new_color;
            if (value == 0x00) {
                new_color = kBlack;
            } else if (value == 0x01) {
                new_color = kDarkGray;
            } else if (value == 0x02) {
                new_color = kLightGray;
            } else if (value == 0x03) {
                new_color = kWhite;
            }

            if (bits == 0) {
                black = new_color;
            } else if (bits == 2) {
                dark_gray = new_color;
            } else if (bits == 4) {
                light_gray = new_color;
            } else if (bits == 6) {
                white = new_color;
            }
        }

        // Todo: For sprites, don't render "white" pixels
        int x_pixel;
        int y_pixel;
        int destination;
        if (is_sprite) {
            x_pixel = (static_cast<int>(x)-8)*8 + 7-bit;
            y_pixel = (static_cast<int>(x)-16)*8+tile_x;
            destination = y_pixel*256+x_pixel;
        } else {
            x_pixel = x*8 + 7-bit;
            y_pixel = (y*8+tile_x);
            destination = y_pixel*256+x_pixel;
        }

        if (x_pixel >= 0 and x_pixel < 160 and y_pixel >= 0 and y_pixel < 144) {
            if (color == 0) {
                map[destination] = white;
            } else if (color == 1) {
                map[destination] = light_gray;
            } else if (color == 2) {
                map[destination] = dark_gray;
            } else {
                map[destination] = black;
            }

            show_map[destination] = true;
        }
    }
}<|endoftext|>


<commit_before>//
// EigenJS.cpp
// ~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot com)
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#include <cstdlib>
#include <ctime>

#include "Complex.hpp"
#include "Matrix.hpp"
#include "CMatrix.hpp"

#include "Vector.hpp"
#include "CVector.hpp"

#include "RowVector.hpp"
#include "CRowVector.hpp"

namespace EigenJS {

void Init(v8::Handle<v8::Object> exports) {
  std::srand(static_cast<unsigned int>(std::time(0)));
  std::rand();

  Complex<>::Init(exports);
  Matrix<>::Init(exports);
  CMatrix<>::Init(exports);

  Vector<>::Init(exports);
  CVector<>::Init(exports);

  RowVector<>::Init(exports);
  CRowVector<>::Init(exports);
}

}  // namespace EigenJS

NODE_MODULE(eigen, EigenJS::Init)
<commit_msg>src: added 'Block'<commit_after>//
// EigenJS.cpp
// ~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot com)
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#include <cstdlib>
#include <ctime>

#include "Complex.hpp"
#include "Matrix.hpp"
#include "CMatrix.hpp"

#include "Vector.hpp"
#include "CVector.hpp"

#include "RowVector.hpp"
#include "CRowVector.hpp"

#include "Block.hpp"

namespace EigenJS {

void Init(v8::Handle<v8::Object> exports) {
  std::srand(static_cast<unsigned int>(std::time(0)));
  std::rand();

  Complex<>::Init(exports);
  Matrix<>::Init(exports);
  CMatrix<>::Init(exports);

  Vector<>::Init(exports);
  CVector<>::Init(exports);

  RowVector<>::Init(exports);
  CRowVector<>::Init(exports);

  Block<>::Init(exports);
}

}  // namespace EigenJS

NODE_MODULE(eigen, EigenJS::Init)
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
* more details.                                                               *
*                                                                             *
* You should have received a copy of the GNU General Public License along     *
* with this program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/component/init.h>
#include <sofa/core/ObjectFactory.h>

#include <iostream>
#include <fstream>
#include <string>

using std::string;
using namespace sofa::core;
using namespace sofa::core::objectmodel;

string make_link(ObjectFactory::Creator::SPtr creator) {
    const BaseClass* Class = creator->getClass();
    string str(Class->namespaceName + "::" + Class->className);
    size_t index;
    while ((index = str.find("::", 0)) != string::npos)
        str.replace(index, 2, "_1_1");
    for (char c = 'A'; c <= 'Z' ; c++)
        while ((index = str.find(c, 0)) != string::npos)
            str.replace(index, 1, "_"+string(1, c-'A'+'a'));
    string link(string(creator->getTarget()) + "/class" + str + ".html");
    return "" + Class->className +"";
}

void print(const std::string& s) {
    std::cout << s << std::endl;
}

int main()
{
    sofa::component::init();
    std::vector<ObjectFactory::ClassEntry::SPtr> entries;
    ObjectFactory::getInstance()->getAllEntries(entries);
    print("/**");
    print("   \\page component_list Component List");
    print("
");
    for (size_t i = 0 ; i != entries.size() ; i++)
        if (!entries[i]->creatorMap.empty()) {
            const ObjectFactory::Creator::SPtr creator = entries[i]->creatorMap.begin()->second;
            print("
" + make_link(creator) + "
");
        }
    print("
");
    print("*/");
    return 0;
}
<commit_msg>doxygen: minor fix<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
* more details.                                                               *
*                                                                             *
* You should have received a copy of the GNU General Public License along     *
* with this program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <SofaComponentMain/init.h>
#include <sofa/core/ObjectFactory.h>

#include <iostream>
#include <fstream>
#include <string>

using std::string;
using namespace sofa::core;
using namespace sofa::core::objectmodel;

string make_link(ObjectFactory::Creator::SPtr creator) {
    const BaseClass* Class = creator->getClass();
    string str(Class->namespaceName + "::" + Class->className);
    size_t index;
    while ((index = str.find("::", 0)) != string::npos)
        str.replace(index, 2, "_1_1");
    for (char c = 'A'; c <= 'Z' ; c++)
        while ((index = str.find(c, 0)) != string::npos)
            str.replace(index, 1, "_"+string(1, c-'A'+'a'));
    string link(string(creator->getTarget()) + "/class" + str + ".html");
    return "" + Class->className +"";
}

void print(const std::string& s) {
    std::cout << s << std::endl;
}

int main()
{
    sofa::component::init();
    std::vector<ObjectFactory::ClassEntry::SPtr> entries;
    ObjectFactory::getInstance()->getAllEntries(entries);
    print("/**");
    print("   \\page component_list Component List");
    print("
");
    for (size_t i = 0 ; i != entries.size() ; i++)
        if (!entries[i]->creatorMap.empty()) {
            const ObjectFactory::Creator::SPtr creator = entries[i]->creatorMap.begin()->second;
            print("
" + make_link(creator) + "
");
        }
    print("
");
    print("*/");
    return 0;
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
// BOSSA
//
// Copyright (c) 2011-2018, ShumaTech
// 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 <organization> 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 <COPYRIGHT HOLDER> 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 <string>
#include <exception>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "Flasher.h"

using namespace std;

void
FlasherInfo::print()
{
    bool first;

    printf("Device       : %s\n", name.c_str());
    printf("Version      : %s\n", version.c_str());
    printf("Address      : 0x%x\n", address);
    printf("Pages        : %d\n", numPages);
    printf("Page Size    : %d bytes\n", pageSize);
    printf("Total Size   : %dKB\n", totalSize / 1024);
    printf("Planes       : %d\n", numPlanes);
    printf("Lock Regions : %zd\n", lockRegions.size());
    printf("Locked       : ");
    first = true;
    for (uint32_t region = 0; region < lockRegions.size(); region++)
    {
        if (lockRegions[region])
        {
            printf("%s%d", first ? "" : ",", region);
            first = false;
        }
    }
    printf("%s\n", first ? "none" : "");
    printf("Security     : %s\n", security ? "true" : "false");
    if (canBootFlash)
        printf("Boot Flash   : %s\n", bootFlash ? "true" : "false");
    if (canBod)
        printf("BOD          : %s\n", bod ? "true" : "false");
    if (canBor)
        printf("BOR          : %s\n", bor ? "true" : "false");
}

void
Flasher::erase(uint32_t foffset)
{
    _observer.onStatus("Erase flash\n");
    _flash->eraseAll(foffset);
    _flash->eraseAuto(false);
}

void
Flasher::write(const char* filename, uint32_t foffset)
{
    FILE* infile;
    uint32_t pageSize = _flash->pageSize();
    uint32_t pageNum = 0;
    uint32_t numPages;
    long fsize;
    size_t fbytes;

    if (foffset % pageSize != 0 || foffset >= _flash->totalSize())
        throw FlashOffsetError();

    infile = fopen(filename, "rb");
    if (!infile)
        throw FileOpenError(errno);

    try
    {
        if (fseek(infile, 0, SEEK_END) != 0 || (fsize = ftell(infile)) < 0)
            throw FileIoError(errno);

        rewind(infile);

        numPages = (fsize + pageSize - 1) / pageSize;
        if (numPages > _flash->numPages())
            throw FileSizeError();

        _observer.onStatus("Write %ld bytes to flash (%u pages)\n", fsize, numPages);

        if (_samba.canWriteBuffer())
        {
            uint32_t offset = 0;
            uint32_t bufferSize = _samba.writeBufferSize();
            uint8_t buffer[bufferSize];

            while ((fbytes = fread(buffer, 1, bufferSize, infile)) > 0)
            {
                _observer.onProgress(offset / pageSize, numPages);

                if (fbytes < bufferSize)
                {
                    memset(buffer + fbytes, 0, bufferSize - fbytes);
                    fbytes = (fbytes + pageSize - 1) / pageSize * pageSize;
                }

                _flash->loadBuffer(buffer, fbytes);
                _flash->writeBuffer(foffset + offset, fbytes);
                offset += fbytes;
            }

        }
        else
        {
            uint8_t buffer[pageSize];
            uint32_t pageOffset = foffset / pageSize;

            while ((fbytes = fread(buffer, 1, pageSize, infile)) > 0)
            {
                _observer.onProgress(pageNum, numPages);

                _flash->loadBuffer(buffer, fbytes);
                _flash->writePage(pageOffset + pageNum);

                pageNum++;
                if (pageNum == numPages || fbytes != pageSize)
                    break;
            }

        }
    }
    catch(...)
    {
        fclose(infile);
        throw;
    }

    fclose(infile);
    _observer.onProgress(numPages, numPages);
}

bool
Flasher::verify(const char* filename, uint32_t& pageErrors, uint32_t& totalErrors, uint32_t foffset)
{
    FILE* infile;
    uint32_t pageSize = _flash->pageSize();
    uint8_t bufferA[pageSize];
    uint8_t bufferB[pageSize];
    uint32_t pageNum = 0;
    uint32_t numPages;
    uint32_t pageOffset;
    uint32_t byteErrors = 0;
    uint16_t calcCrc = 0;
    uint16_t flashCrc;
    long fsize;
    size_t fbytes;

    pageErrors = 0;
    totalErrors = 0;

    if (foffset % pageSize != 0 || foffset >= _flash->totalSize())
        throw FlashOffsetError();

    pageOffset = foffset / pageSize;

    infile = fopen(filename, "rb");
    if (!infile)
        throw FileOpenError(errno);

    try
    {
        if (fseek(infile, 0, SEEK_END) != 0 || (fsize = ftell(infile)) < 0)
            throw FileIoError(errno);

        rewind(infile);

        numPages = (fsize + pageSize - 1) / pageSize;
        if (numPages > _flash->numPages())
            throw FileSizeError();

        _observer.onStatus("Verify %ld bytes of flash\n", fsize);

        while ((fbytes = fread(bufferA, 1, pageSize, infile)) > 0)
        {
            byteErrors = 0;

            _observer.onProgress(pageNum, numPages);

            if (_samba.canChecksumBuffer())
            {
                for (uint32_t i = 0; i < fbytes; i++)
                    calcCrc = _samba.checksumCalc(bufferA[i], calcCrc);

                flashCrc = _samba.checksumBuffer((pageOffset + pageNum) * pageSize, fbytes);

                if (flashCrc != calcCrc)
                {
                    _flash->readPage(pageOffset + pageNum, bufferB);

                    for (uint32_t i = 0; i < fbytes; i++)
                    {
                        if (bufferA[i] != bufferB[i])
                            byteErrors++;
                    }
                }
            }
            else
            {
                _flash->readPage(pageOffset + pageNum, bufferB);

                for (uint32_t i = 0; i < fbytes; i++)
                {
                    if (bufferA[i] != bufferB[i])
                        byteErrors++;
                }
            }

            if (byteErrors != 0)
            {
                pageErrors++;
                totalErrors += byteErrors;
            }

            pageNum++;
            if (pageNum == numPages || fbytes != pageSize)
                break;
        }
    }
    catch(...)
    {
        fclose(infile);
        throw;
    }

    fclose(infile);

     _observer.onProgress(numPages, numPages);

    if (pageErrors != 0)
        return false;

    return true;
}

void
Flasher::read(const char* filename, uint32_t fsize, uint32_t foffset)
{
    FILE* outfile;
    uint32_t pageSize = _flash->pageSize();
    uint8_t buffer[pageSize];
    uint32_t pageNum = 0;
    uint32_t pageOffset;
    uint32_t numPages;
    size_t fbytes;

    if (foffset % pageSize != 0 || foffset >= _flash->totalSize())
        throw FlashOffsetError();

    pageOffset = foffset / pageSize;

    if (fsize == 0)
        fsize = pageSize * (_flash->numPages() - pageOffset);

    numPages = (fsize + pageSize - 1) / pageSize;
    if (pageOffset + numPages > _flash->numPages())
        throw FileSizeError();

    outfile = fopen(filename, "wb");
    if (!outfile)
        throw FileOpenError(errno);

    _observer.onStatus("Read %d bytes from flash\n", fsize);

    try
    {
        for (pageNum = 0; pageNum < numPages; pageNum++)
        {
            _observer.onProgress(pageNum, numPages);

            _flash->readPage(pageOffset + pageNum, buffer);

            if (pageNum == numPages - 1 && fsize % pageSize > 0)
                pageSize = fsize % pageSize;
            fbytes = fwrite(buffer, 1, pageSize, outfile);
            if (fbytes != pageSize)
                throw FileShortError();
        }
    }
    catch(...)
    {
        fclose(outfile);
        throw;
    }

    _observer.onProgress(numPages, numPages);

    fclose(outfile);
}

void
Flasher::lock(string& regionArg, bool enable)
{
    if (regionArg.empty())
    {
        _observer.onStatus("%s all regions\n", enable ? "Lock" : "Unlock");
        std::vector<bool> regions(_flash->lockRegions(), enable);
        _flash->setLockRegions(regions);
    }
    else
    {
        size_t pos = 0;
        size_t delim;
        uint32_t region;
        string sub;
        std::vector<bool> regions = _flash->getLockRegions();

        do
        {
            delim = regionArg.find(',', pos);
            sub = regionArg.substr(pos, delim - pos);
            region = strtol(sub.c_str(), NULL, 0);
            _observer.onStatus("%s region %d\n", enable ? "Lock" : "Unlock", region);
            regions[region] = enable;
            pos = delim + 1;
        } while (delim != string::npos);

        _flash->setLockRegions(regions);
    }
}

void
Flasher::info(FlasherInfo& info)
{
    info.name = _flash->name();
    info.version = _samba.version();
    info.address = _flash->address();
    info.numPages = _flash->numPages();
    info.pageSize = _flash->pageSize();
    info.totalSize = _flash->numPages() * _flash->pageSize();
    info.numPlanes = _flash->numPlanes();
    info.security = _flash->getSecurity();
    info.bootFlash = _flash->getBootFlash();
    info.bod = _flash->getBod();
    info.bor = _flash->getBor();

    info.canBootFlash = _flash->canBootFlash();
    info.canBod = _flash->canBod();
    info.canBor = _flash->canBor();
    info.canChipErase = _samba.canChipErase();
    info.canWriteBuffer = _samba.canWriteBuffer();
    info.canChecksumBuffer = _samba.canChecksumBuffer();
    info.lockRegions = _flash->getLockRegions();
}
<commit_msg>Fix CRC calculation on verify for crc-capable bootloaders<commit_after>///////////////////////////////////////////////////////////////////////////////
// BOSSA
//
// Copyright (c) 2011-2018, ShumaTech
// 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 <organization> 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 <COPYRIGHT HOLDER> 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 <string>
#include <exception>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "Flasher.h"

using namespace std;

void
FlasherInfo::print()
{
    bool first;

    printf("Device       : %s\n", name.c_str());
    printf("Version      : %s\n", version.c_str());
    printf("Address      : 0x%x\n", address);
    printf("Pages        : %d\n", numPages);
    printf("Page Size    : %d bytes\n", pageSize);
    printf("Total Size   : %dKB\n", totalSize / 1024);
    printf("Planes       : %d\n", numPlanes);
    printf("Lock Regions : %zd\n", lockRegions.size());
    printf("Locked       : ");
    first = true;
    for (uint32_t region = 0; region < lockRegions.size(); region++)
    {
        if (lockRegions[region])
        {
            printf("%s%d", first ? "" : ",", region);
            first = false;
        }
    }
    printf("%s\n", first ? "none" : "");
    printf("Security     : %s\n", security ? "true" : "false");
    if (canBootFlash)
        printf("Boot Flash   : %s\n", bootFlash ? "true" : "false");
    if (canBod)
        printf("BOD          : %s\n", bod ? "true" : "false");
    if (canBor)
        printf("BOR          : %s\n", bor ? "true" : "false");
}

void
Flasher::erase(uint32_t foffset)
{
    _observer.onStatus("Erase flash\n");
    _flash->eraseAll(foffset);
    _flash->eraseAuto(false);
}

void
Flasher::write(const char* filename, uint32_t foffset)
{
    FILE* infile;
    uint32_t pageSize = _flash->pageSize();
    uint32_t pageNum = 0;
    uint32_t numPages;
    long fsize;
    size_t fbytes;

    if (foffset % pageSize != 0 || foffset >= _flash->totalSize())
        throw FlashOffsetError();

    infile = fopen(filename, "rb");
    if (!infile)
        throw FileOpenError(errno);

    try
    {
        if (fseek(infile, 0, SEEK_END) != 0 || (fsize = ftell(infile)) < 0)
            throw FileIoError(errno);

        rewind(infile);

        numPages = (fsize + pageSize - 1) / pageSize;
        if (numPages > _flash->numPages())
            throw FileSizeError();

        _observer.onStatus("Write %ld bytes to flash (%u pages)\n", fsize, numPages);

        if (_samba.canWriteBuffer())
        {
            uint32_t offset = 0;
            uint32_t bufferSize = _samba.writeBufferSize();
            uint8_t buffer[bufferSize];

            while ((fbytes = fread(buffer, 1, bufferSize, infile)) > 0)
            {
                _observer.onProgress(offset / pageSize, numPages);

                if (fbytes < bufferSize)
                {
                    memset(buffer + fbytes, 0, bufferSize - fbytes);
                    fbytes = (fbytes + pageSize - 1) / pageSize * pageSize;
                }

                _flash->loadBuffer(buffer, fbytes);
                _flash->writeBuffer(foffset + offset, fbytes);
                offset += fbytes;
            }

        }
        else
        {
            uint8_t buffer[pageSize];
            uint32_t pageOffset = foffset / pageSize;

            while ((fbytes = fread(buffer, 1, pageSize, infile)) > 0)
            {
                _observer.onProgress(pageNum, numPages);

                _flash->loadBuffer(buffer, fbytes);
                _flash->writePage(pageOffset + pageNum);

                pageNum++;
                if (pageNum == numPages || fbytes != pageSize)
                    break;
            }

        }
    }
    catch(...)
    {
        fclose(infile);
        throw;
    }

    fclose(infile);
    _observer.onProgress(numPages, numPages);
}

bool
Flasher::verify(const char* filename, uint32_t& pageErrors, uint32_t& totalErrors, uint32_t foffset)
{
    FILE* infile;
    uint32_t pageSize = _flash->pageSize();
    uint8_t bufferA[pageSize];
    uint8_t bufferB[pageSize];
    uint32_t pageNum = 0;
    uint32_t numPages;
    uint32_t pageOffset;
    uint32_t byteErrors = 0;
    uint16_t flashCrc;
    long fsize;
    size_t fbytes;

    pageErrors = 0;
    totalErrors = 0;

    if (foffset % pageSize != 0 || foffset >= _flash->totalSize())
        throw FlashOffsetError();

    pageOffset = foffset / pageSize;

    infile = fopen(filename, "rb");
    if (!infile)
        throw FileOpenError(errno);

    try
    {
        if (fseek(infile, 0, SEEK_END) != 0 || (fsize = ftell(infile)) < 0)
            throw FileIoError(errno);

        rewind(infile);

        numPages = (fsize + pageSize - 1) / pageSize;
        if (numPages > _flash->numPages())
            throw FileSizeError();

        _observer.onStatus("Verify %ld bytes of flash\n", fsize);

        while ((fbytes = fread(bufferA, 1, pageSize, infile)) > 0)
        {
            byteErrors = 0;

            _observer.onProgress(pageNum, numPages);

            if (_samba.canChecksumBuffer())
            {
                uint16_t calcCrc = 0;
                for (uint32_t i = 0; i < fbytes; i++)
                    calcCrc = _samba.checksumCalc(bufferA[i], calcCrc);

                flashCrc = _samba.checksumBuffer((pageOffset + pageNum) * pageSize, fbytes);

                if (flashCrc != calcCrc)
                {
                    _flash->readPage(pageOffset + pageNum, bufferB);

                    for (uint32_t i = 0; i < fbytes; i++)
                    {
                        if (bufferA[i] != bufferB[i])
                            byteErrors++;
                    }
                }
            }
            else
            {
                _flash->readPage(pageOffset + pageNum, bufferB);

                for (uint32_t i = 0; i < fbytes; i++)
                {
                    if (bufferA[i] != bufferB[i])
                        byteErrors++;
                }
            }

            if (byteErrors != 0)
            {
                pageErrors++;
                totalErrors += byteErrors;
            }

            pageNum++;
            if (pageNum == numPages || fbytes != pageSize)
                break;
        }
    }
    catch(...)
    {
        fclose(infile);
        throw;
    }

    fclose(infile);

     _observer.onProgress(numPages, numPages);

    if (pageErrors != 0)
        return false;

    return true;
}

void
Flasher::read(const char* filename, uint32_t fsize, uint32_t foffset)
{
    FILE* outfile;
    uint32_t pageSize = _flash->pageSize();
    uint8_t buffer[pageSize];
    uint32_t pageNum = 0;
    uint32_t pageOffset;
    uint32_t numPages;
    size_t fbytes;

    if (foffset % pageSize != 0 || foffset >= _flash->totalSize())
        throw FlashOffsetError();

    pageOffset = foffset / pageSize;

    if (fsize == 0)
        fsize = pageSize * (_flash->numPages() - pageOffset);

    numPages = (fsize + pageSize - 1) / pageSize;
    if (pageOffset + numPages > _flash->numPages())
        throw FileSizeError();

    outfile = fopen(filename, "wb");
    if (!outfile)
        throw FileOpenError(errno);

    _observer.onStatus("Read %d bytes from flash\n", fsize);

    try
    {
        for (pageNum = 0; pageNum < numPages; pageNum++)
        {
            _observer.onProgress(pageNum, numPages);

            _flash->readPage(pageOffset + pageNum, buffer);

            if (pageNum == numPages - 1 && fsize % pageSize > 0)
                pageSize = fsize % pageSize;
            fbytes = fwrite(buffer, 1, pageSize, outfile);
            if (fbytes != pageSize)
                throw FileShortError();
        }
    }
    catch(...)
    {
        fclose(outfile);
        throw;
    }

    _observer.onProgress(numPages, numPages);

    fclose(outfile);
}

void
Flasher::lock(string& regionArg, bool enable)
{
    if (regionArg.empty())
    {
        _observer.onStatus("%s all regions\n", enable ? "Lock" : "Unlock");
        std::vector<bool> regions(_flash->lockRegions(), enable);
        _flash->setLockRegions(regions);
    }
    else
    {
        size_t pos = 0;
        size_t delim;
        uint32_t region;
        string sub;
        std::vector<bool> regions = _flash->getLockRegions();

        do
        {
            delim = regionArg.find(',', pos);
            sub = regionArg.substr(pos, delim - pos);
            region = strtol(sub.c_str(), NULL, 0);
            _observer.onStatus("%s region %d\n", enable ? "Lock" : "Unlock", region);
            regions[region] = enable;
            pos = delim + 1;
        } while (delim != string::npos);

        _flash->setLockRegions(regions);
    }
}

void
Flasher::info(FlasherInfo& info)
{
    info.name = _flash->name();
    info.version = _samba.version();
    info.address = _flash->address();
    info.numPages = _flash->numPages();
    info.pageSize = _flash->pageSize();
    info.totalSize = _flash->numPages() * _flash->pageSize();
    info.numPlanes = _flash->numPlanes();
    info.security = _flash->getSecurity();
    info.bootFlash = _flash->getBootFlash();
    info.bod = _flash->getBod();
    info.bor = _flash->getBor();

    info.canBootFlash = _flash->canBootFlash();
    info.canBod = _flash->canBod();
    info.canBor = _flash->canBor();
    info.canChipErase = _samba.canChipErase();
    info.canWriteBuffer = _samba.canWriteBuffer();
    info.canChecksumBuffer = _samba.canChecksumBuffer();
    info.lockRegions = _flash->getLockRegions();
}
<|endoftext|>


<commit_before>#include "common.h"
#include <string>

#include <rtosc/thread-link.h>

void verify_msg(rtosc::msg_t read_msg, const char *portname, int value, const char *test_id, int line)
{
    const std::string test_string = test_id;

    assert_str_eq(portname, read_msg, (test_string + " (portname)").c_str(), line);
    const char* arg_str = rtosc_argument_string(read_msg);
    assert_str_eq("i", arg_str, (test_string + " (arg type)").c_str(), line);
    if(!strcmp(arg_str, "i"))
        assert_int_eq(value, rtosc_argument(read_msg, 0).i, (test_string + " (arg value)").c_str(), line);
}

void test_contiguous_write()
{
    // max 4 messages of each 32 -> 128 bytes size
    rtosc::ThreadLink thread_link(32,4);
    char portname[] = "abcdefghijklmnop"; // length 16, array size 17
    rtosc::msg_t read_msg;

    // always write one message ahead, to check that a second message
    // does not corrupt the "message under test"
    thread_link.write(portname, "i", 42);

    // 10 rounds are enough to have 1 discontigous write
    for (int round = 0; round < 10; ++round)
    {
        // write 17 bytes + 3 bytes padding + 4 bytes argstr + 4 bytes args = 28 bytes
        thread_link.write(portname, "i", 42);
        read_msg = thread_link.read();

        char test_name [] = "round 0";
        test_name[6] += round % 10;
        verify_msg(read_msg, portname, 42, test_name, __LINE__);
    }
}

int main()
{
    test_contiguous_write();

    return test_summary();
}

<commit_msg>thread_link_test: Augment contiguous write test<commit_after>#include "common.h"
#include <string>

#include <rtosc/thread-link.h>

void verify_msg(rtosc::msg_t read_msg, const char *portname, int value, const char *test_id, int line)
{
    const std::string test_string = test_id;

    assert_str_eq(portname, read_msg, (test_string + " (portname)").c_str(), line);
    const char* arg_str = rtosc_argument_string(read_msg);
    assert_str_eq("i", arg_str, (test_string + " (arg type)").c_str(), line);
    if(!strcmp(arg_str, "i"))
        assert_int_eq(value, rtosc_argument(read_msg, 0).i, (test_string + " (arg value)").c_str(), line);
}

void test_contiguous_write()
{
    // max 4 messages of each 32 -> 128 bytes size
    rtosc::ThreadLink thread_link(32,4);
    char portname[] = "abcdefghijklmnop"; // length 16, array size 17
    rtosc::msg_t read_msg;

    // always write one message ahead, to check that a second message
    // does not corrupt the "message under test"
    thread_link.write(portname, "i", 42);

    // 10 rounds are enough to have 1 discontigous write
    for (int round = 0; round < 10; ++round)
    {
        // write 17 bytes + 3 bytes padding + 4 bytes argstr + 4 bytes args = 28 bytes
        thread_link.write(portname, "i", 43 + round);
        read_msg = thread_link.read();

        char test_name [] = "round 0";
        test_name[6] += round % 10;
        verify_msg(read_msg, portname, 42 + round, test_name, __LINE__);
    }
}

int main()
{
    test_contiguous_write();

    return test_summary();
}

<|endoftext|>


<commit_before>// Petter Strandmark 2012.

#include <cstring>
#include <iostream>
#include <limits>
#include <memory>
#include <random>
#include <stdexcept>

#include <Eigen/Dense>
#include <Eigen/Eigenvalues>
#include <Eigen/Sparse>

extern "C" {
	#include "matrix.h"
	#include "matrix2.h"
	#undef min
	#undef max
	#undef catch
	#undef SPARSE
}

#include <spii/spii.h>
#include <spii/solver.h>

namespace spii {

template<typename EigenMat>
void Eigen_to_Meschach(const EigenMat& eigen_matrix, MAT* A)
{
	int m = eigen_matrix.rows();
	int n = eigen_matrix.cols();

	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < n; ++j) {
			A->me[i][j] = eigen_matrix(i, j);
		}
	}
}

struct FactorizationCacheInternal
{
	PERM* pivot;
	PERM* block;
	MAT* Hmat;
	VEC* x;
	VEC* b;
};

FactorizationCache::FactorizationCache(int n)
{
	auto cache = new FactorizationCacheInternal;
	cache->pivot = px_get(n);
	cache->block = px_get(n);
	cache->Hmat  = m_get(n, n);
	cache->x     = v_get(n);
	cache->b     = v_get(n);
	this->data = cache;
}

FactorizationCache::~FactorizationCache()
{
	auto cache = reinterpret_cast<FactorizationCacheInternal*>(this->data);
	v_free(cache->b);
	v_free(cache->x);
	m_free(cache->Hmat);
	px_free(cache->pivot);
	px_free(cache->block);
	delete cache;
}

void Solver::BKP_dense(const Eigen::MatrixXd& H,
                       const Eigen::VectorXd& g,
                       const FactorizationCache& cache_input,
                       Eigen::VectorXd* p,
                       SolverResults* results) const
{
	using namespace Eigen;
	double start_time = wall_time();

	auto cache = reinterpret_cast<FactorizationCacheInternal*>(cache_input.data);
	int n = H.rows();

	Eigen_to_Meschach(H, cache->Hmat);

	//m_foutput(stderr, cache->Hmat);

	BKPfactor(cache->Hmat, cache->pivot, cache->block);

	//m_foutput(stderr, cache->Hmat);

	MatrixXd B(n, n);
	MatrixXd Q(n, n);
	VectorXd tau(n);
	VectorXd lambda(n);
	B.setZero();
	Q.setZero();

	SelfAdjointEigenSolver<MatrixXd> eigensolver;

	double delta = 1e-12;

	int onebyone;
	for (int i = 0; i < n; i = onebyone ? i+1 : i+2 ) {
		onebyone = ( cache->block->pe[i] == i );
		if ( onebyone ) {
		    B(i, i) = m_entry(cache->Hmat, i, i);
			lambda(i) = B(i, i);
			if (lambda(i) >= delta) {
				tau(i) = 0;
			}
			else {
				tau(i) = delta - (1.0 + delta) * lambda(i);
			}
			Q(i, i) = 1;
		}
		else {
		    auto a11 = m_entry(cache->Hmat, i, i);
		    auto a22 = m_entry(cache->Hmat, i+1, i+1);
		    auto a12 = m_entry(cache->Hmat, i+1, i);
			B(i,   i)   = a11;
			B(i+1, i)   = a12;
			B(i,   i+1) = a12;
			B(i+1, i+1) = a22;
			eigensolver.compute(B.block(i, i, 2, 2));

			lambda(i)   = eigensolver.eigenvalues()(0);
			lambda(i+1) = eigensolver.eigenvalues()(1);
			for (int k = i; k <= i + 1; ++k) {
				if (lambda(k) >= delta) {
					tau(k) = 0;
				}
				else {
					tau(k) = delta - (1.0 + delta) * lambda(k);
				}
			}

			Q.block(i, i, 2, 2) = eigensolver.eigenvectors();
		}
	}

	//std::cerr << "B = \n" << B << "\n\n";
	//std::cerr << "F = \n" <<  Q * tau.asDiagonal() * Q.transpose() << "\n\n";

	B = B + Q * tau.asDiagonal() * Q.transpose();

	//std::cerr << "B = \n" << B << "\n\n";

	for (int i = 0; i < n; i = onebyone ? i+1 : i+2 ) {
		onebyone = ( cache->block->pe[i] == i );
		if ( onebyone ) {
		   m_entry(cache->Hmat, i, i) = B(i, i);
		}
		else {
		    m_entry(cache->Hmat, i,   i)   = B(i,   i);
		    m_entry(cache->Hmat, i+1, i+1) = B(i+1, i+1);
		    m_entry(cache->Hmat, i+1, i)   = B(i+1, i);
			m_entry(cache->Hmat, i,   i+1) = B(i,   i+1);
		}
	}

	results->matrix_factorization_time += wall_time() - start_time;
	start_time = wall_time();

	//m_foutput(stderr, cache->Hmat);

	for (int i = 0; i < n; ++i) {
		cache->b->ve[i] = -g(i);
	}
	BKPsolve(cache->Hmat, cache->pivot, cache->block, cache->b, cache->x);
	for (int i = 0; i < n; ++i) {
		(*p)(i) = cache->x->ve[i];
	}

	results->linear_solver_time += wall_time() - start_time;
	start_time = wall_time();

	results->matrix_factorization_time += wall_time() - start_time;
}

}  // namespace spii
<commit_msg>FactorizationCache without reinterpret_cast.<commit_after>// Petter Strandmark 2012.

#include <cstring>
#include <iostream>
#include <limits>
#include <memory>
#include <random>
#include <stdexcept>

#include <Eigen/Dense>
#include <Eigen/Eigenvalues>
#include <Eigen/Sparse>

extern "C" {
	#include "matrix.h"
	#include "matrix2.h"
	#undef min
	#undef max
	#undef catch
	#undef SPARSE
}

#include <spii/spii.h>
#include <spii/solver.h>

namespace spii {

template<typename EigenMat>
void Eigen_to_Meschach(const EigenMat& eigen_matrix, MAT* A)
{
	int m = eigen_matrix.rows();
	int n = eigen_matrix.cols();

	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < n; ++j) {
			A->me[i][j] = eigen_matrix(i, j);
		}
	}
}

struct FactorizationCacheInternal
{
	PERM* pivot;
	PERM* block;
	MAT* Hmat;
	VEC* x;
	VEC* b;
};

FactorizationCache::FactorizationCache(int n)
{
	auto cache = new FactorizationCacheInternal;
	cache->pivot = px_get(n);
	cache->block = px_get(n);
	cache->Hmat  = m_get(n, n);
	cache->x     = v_get(n);
	cache->b     = v_get(n);
	this->data = cache;
}

FactorizationCache::~FactorizationCache()
{
	v_free(this->data->b);
	v_free(this->data->x);
	m_free(this->data->Hmat);
	px_free(this->data->pivot);
	px_free(this->data->block);
	delete this->data;
}

void Solver::BKP_dense(const Eigen::MatrixXd& H,
                       const Eigen::VectorXd& g,
                       const FactorizationCache& cache_input,
                       Eigen::VectorXd* p,
                       SolverResults* results) const
{
	using namespace Eigen;
	double start_time = wall_time();

	auto cache = reinterpret_cast<FactorizationCacheInternal*>(cache_input.data);
	int n = H.rows();

	Eigen_to_Meschach(H, cache->Hmat);

	//m_foutput(stderr, cache->Hmat);

	BKPfactor(cache->Hmat, cache->pivot, cache->block);

	//m_foutput(stderr, cache->Hmat);

	MatrixXd B(n, n);
	MatrixXd Q(n, n);
	VectorXd tau(n);
	VectorXd lambda(n);
	B.setZero();
	Q.setZero();

	SelfAdjointEigenSolver<MatrixXd> eigensolver;

	double delta = 1e-12;

	int onebyone;
	for (int i = 0; i < n; i = onebyone ? i+1 : i+2 ) {
		onebyone = ( cache->block->pe[i] == i );
		if ( onebyone ) {
		    B(i, i) = m_entry(cache->Hmat, i, i);
			lambda(i) = B(i, i);
			if (lambda(i) >= delta) {
				tau(i) = 0;
			}
			else {
				tau(i) = delta - (1.0 + delta) * lambda(i);
			}
			Q(i, i) = 1;
		}
		else {
		    auto a11 = m_entry(cache->Hmat, i, i);
		    auto a22 = m_entry(cache->Hmat, i+1, i+1);
		    auto a12 = m_entry(cache->Hmat, i+1, i);
			B(i,   i)   = a11;
			B(i+1, i)   = a12;
			B(i,   i+1) = a12;
			B(i+1, i+1) = a22;
			eigensolver.compute(B.block(i, i, 2, 2));

			lambda(i)   = eigensolver.eigenvalues()(0);
			lambda(i+1) = eigensolver.eigenvalues()(1);
			for (int k = i; k <= i + 1; ++k) {
				if (lambda(k) >= delta) {
					tau(k) = 0;
				}
				else {
					tau(k) = delta - (1.0 + delta) * lambda(k);
				}
			}

			Q.block(i, i, 2, 2) = eigensolver.eigenvectors();
		}
	}

	//std::cerr << "B = \n" << B << "\n\n";
	//std::cerr << "F = \n" <<  Q * tau.asDiagonal() * Q.transpose() << "\n\n";

	B = B + Q * tau.asDiagonal() * Q.transpose();

	//std::cerr << "B = \n" << B << "\n\n";

	for (int i = 0; i < n; i = onebyone ? i+1 : i+2 ) {
		onebyone = ( cache->block->pe[i] == i );
		if ( onebyone ) {
		   m_entry(cache->Hmat, i, i) = B(i, i);
		}
		else {
		    m_entry(cache->Hmat, i,   i)   = B(i,   i);
		    m_entry(cache->Hmat, i+1, i+1) = B(i+1, i+1);
		    m_entry(cache->Hmat, i+1, i)   = B(i+1, i);
			m_entry(cache->Hmat, i,   i+1) = B(i,   i+1);
		}
	}

	results->matrix_factorization_time += wall_time() - start_time;
	start_time = wall_time();

	//m_foutput(stderr, cache->Hmat);

	for (int i = 0; i < n; ++i) {
		cache->b->ve[i] = -g(i);
	}
	BKPsolve(cache->Hmat, cache->pivot, cache->block, cache->b, cache->x);
	for (int i = 0; i < n; ++i) {
		(*p)(i) = cache->x->ve[i];
	}

	results->linear_solver_time += wall_time() - start_time;
	start_time = wall_time();

	results->matrix_factorization_time += wall_time() - start_time;
}

}  // namespace spii
<|endoftext|>