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

#include "Tools/types.h"

#include "Launcher/Launcher.hpp"

#include "Launcher/BFER/Launcher_BFER_polar.hpp"
#include "Launcher/BFER/Launcher_BFER_turbo.hpp"
#include "Launcher/BFER/Launcher_BFER_LDPC.hpp"
#include "Launcher/BFER/Launcher_BFER_RSC.hpp"
#include "Launcher/BFER/Launcher_BFER_RA.hpp"
#include "Launcher/BFER/Launcher_BFER_repetition.hpp"
#include "Launcher/BFER/Launcher_BFER_uncoded.hpp"

#include "Launcher/BFERI/Launcher_BFERI_RSC.hpp"
#include "Launcher/BFERI/Launcher_BFERI_LDPC.hpp"
#include "Launcher/BFERI/Launcher_BFERI_uncoded.hpp"

#include "Launcher/EXIT/Launcher_EXIT_polar.hpp"
#include "Launcher/EXIT/Launcher_EXIT_RSC.hpp"

#include "Launcher/GEN/Launcher_GEN_polar.hpp"

#include "Tools/params.h"
#include "Tools/bash_tools.h"
#include "Tools/MIPP/mipp.h"
#include "Tools/Arguments_reader.hpp"

void print_version()
{
#if defined(_WIN64) || defined(_WIN32) || defined(WIN32) || defined(__MINGW32__)
	std::string os = "Windows";
#elif defined(__linux__) || defined(__linux)
	std::string os = "Linux";
#elif defined(__APPLE__)
	std::string os = "Mac OS X";
#else
	std::string os = "Unknown OS";
#endif

#if defined(__x86_64) || defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__)
	std::string prec = " 64-bit";
#elif defined(__i386) || defined(__i386__) || defined(i386) || defined(_WIN32) || defined(__ARM_ARCH_7__)
	std::string prec = " 32-bit";
#else
	std::string prec = "";
#endif

#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC)
	std::string compiler = "icpc";
#if defined(__INTEL_COMPILER)
	std::string compiler_version = std::to_string(__INTEL_COMPILER);
#elif defined(__ICL)
	std::string compiler_version = std::to_string(__ICL);
#else
	std::string compiler_version = std::to_string(__ICC);
#endif
	compiler_version = compiler_version.substr(0,2) + "." + compiler_version.substr(2,compiler_version.size());
#elif defined(__clang__) || defined(__llvm__)
	std::string compiler = "clang++";
	std::string compiler_version = std::to_string(__clang_major__);
	compiler_version += "." + std::to_string(__clang_minor__);
#elif defined(__GNUG__) || (defined(__GNUC__) && defined(__cplusplus))
	std::string compiler = "g++";
	std::string compiler_version = std::to_string(__GNUC__);
	compiler_version += "." + std::to_string(__GNUC_MINOR__);
#else
	std::string compiler = "Unknown compiler";
	std::string compiler_version = "";
#endif
	std::string affect_version = "1.0.0";

	std::cout << "aff3ct (" << os << prec << ", " << compiler << " " << compiler_version << ", "
	          << mipp::IntructionsType << ") " << affect_version << std::endl;
	std::cout << "Copyright (c) 2016 - MIT license."                                           << std::endl;
	std::cout << "This is free software; see the source for copying conditions.  There is NO"  << std::endl;
	std::cout << "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." << std::endl;
	exit(EXIT_SUCCESS);
}

#ifdef MULTI_PREC
void read_arguments(const int argc, const char** argv, std::string &code_type, std::string &simu_type, int &prec)
#else
void read_arguments(const int argc, const char** argv, std::string &code_type, std::string &simu_type)
#endif
{
	using namespace std::chrono;

	std::map<std::string, std::string> req_args, opt_args, doc_args;
	Arguments_reader ar(argc, argv);

	req_args["code-type"] = "code_type";
	doc_args["code-type"] = "the type of codes you want to simulate (POLAR, TURBO, REPETITION, RA or RSC).";

	opt_args["simu-type"] = "simu_type";
	doc_args["simu-type"] = "the type of simulation to run (BFER [default], EXIT or GEN).";

	opt_args["v"        ] = "";
	doc_args["v"        ] = "print informations about the version of the code.";
	opt_args["version"  ] = "";
	doc_args["version"  ] = "print informations about the version of the code.";

	opt_args["h"        ] = "";
	doc_args["h"        ] = "print this help.";
	opt_args["help"     ] = "";
	doc_args["help"     ] = "print this help.";

#ifdef MULTI_PREC
	opt_args["prec"] = "prec";
	doc_args["prec"] = "the simulation precision in bit (ex: 8, 16, 32 or 64).";
#endif

	auto display_help = true;
	auto parsing = ar.parse_arguments(req_args, opt_args);

	if (ar.exist_arg("v") || ar.exist_arg("version"))
		print_version();

	if (parsing)
	{
		// required parameters
		code_type = ar.get_arg("code-type");

		// facultative parameters
		if(ar.exist_arg("simu-type")) simu_type = ar.get_arg("simu-type");
#ifdef MULTI_PREC
		if(ar.exist_arg("prec")) prec = stoi(ar.get_arg("prec"));
#endif

		display_help = false;
	}

	if (display_help)
	{
		if (ar.parse_doc_args(doc_args))
			ar.print_usage();
		else
			std::cerr << bold_red("(EE) A problem was encountered when parsing arguments documentation, exiting.")
			          << std::endl;
		exit(EXIT_FAILURE);
	}
}

template <typename B, typename R, typename Q, typename QD>
void start_simu(const int argc, const char **argv, std::string code_type, std::string simu_type)
{
	Launcher<B,R,Q> *launcher = nullptr;

	if (code_type == "POLAR")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_polar<B,R,Q>(argc, argv);
		else if (simu_type == "EXIT" && (typeid(Q) == typeid(float) || typeid(Q) == typeid(double)))
			launcher = new Launcher_EXIT_polar<B,R,Q>(argc, argv);
		else if (simu_type == "GEN")
			launcher = new Launcher_GEN_polar<B,R,Q>(argc, argv);
	}

	if (code_type == "RSC")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_RSC<B,R,Q,QD>(argc, argv);
		else if (simu_type == "BFERI")
			launcher = new Launcher_BFERI_RSC<B,R,Q,QD>(argc, argv);
		else if (simu_type == "EXIT" && (typeid(Q) == typeid(float) || typeid(Q) == typeid(double)))
			launcher = new Launcher_EXIT_RSC<B,R,Q,QD>(argc, argv);
	}

	if (code_type == "TURBO")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_turbo<B,R,Q,QD>(argc, argv);
	}

	if (code_type == "REPETITION")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_repetition<B,R,Q>(argc, argv);
	}

	if (code_type == "RA")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_RA<B,R,Q>(argc, argv);
	}

	if (code_type == "LDPC")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_LDPC<B,R,Q>(argc, argv);
		else if (simu_type == "BFERI")
			launcher = new Launcher_BFERI_LDPC<B,R,Q>(argc, argv);
	}

	if (code_type == "UNCODED")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_uncoded<B,R,Q>(argc, argv);
		else if (simu_type == "BFERI")
			launcher = new Launcher_BFERI_uncoded<B,R,Q>(argc, argv);
	}

	if (launcher == nullptr)
	{
		std::cerr << bold_red("(EE) Unsupported type of codes/simulation.") << std::endl;
		exit(EXIT_FAILURE);
	}

	launcher->launch();
	delete launcher;
}

int main(int argc, char **argv)
{
	srand(0);

	std::string code_type, simu_type = "BFER";

#ifdef MULTI_PREC
	int prec = 32;
	read_arguments(argc, (const char**)argv, code_type, simu_type, prec);

	switch (prec)
	{
		case 8:
			start_simu<B_8, R_8, Q_8, QD_8 >(argc, (const char**)argv, code_type, simu_type); break;
		case 16:
			start_simu<B_16,R_16,Q_16,QD_16>(argc, (const char**)argv, code_type, simu_type); break;
		case 32:
			start_simu<B_32,R_32,Q_32,QD_32>(argc, (const char**)argv, code_type, simu_type); break;
#if defined(__x86_64) || defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__)
		case 64:
			start_simu<B_64,R_64,Q_64,QD_64>(argc, (const char**)argv, code_type, simu_type); break;
#endif
		default:
			std::cerr << bold_red("(EE) Unsupported number of bits.") << std::endl;
			exit(EXIT_FAILURE);
			break;
	}
#else
	read_arguments(argc, (const char**)argv, code_type, simu_type);
	start_simu<B,R,Q,QD>(argc, (const char**)argv, code_type, simu_type);
#endif

	return EXIT_SUCCESS;
}
<commit_msg>systemc: add empty sc_main<commit_after>#include <cstdlib>
#include <string>
#include <iostream>
#include <map>

#ifdef SYSTEMC
#include <systemc>
#endif

#include "Tools/types.h"

#include "Launcher/Launcher.hpp"

#include "Launcher/BFER/Launcher_BFER_polar.hpp"
#include "Launcher/BFER/Launcher_BFER_turbo.hpp"
#include "Launcher/BFER/Launcher_BFER_LDPC.hpp"
#include "Launcher/BFER/Launcher_BFER_RSC.hpp"
#include "Launcher/BFER/Launcher_BFER_RA.hpp"
#include "Launcher/BFER/Launcher_BFER_repetition.hpp"
#include "Launcher/BFER/Launcher_BFER_uncoded.hpp"

#include "Launcher/BFERI/Launcher_BFERI_RSC.hpp"
#include "Launcher/BFERI/Launcher_BFERI_LDPC.hpp"
#include "Launcher/BFERI/Launcher_BFERI_uncoded.hpp"

#include "Launcher/EXIT/Launcher_EXIT_polar.hpp"
#include "Launcher/EXIT/Launcher_EXIT_RSC.hpp"

#include "Launcher/GEN/Launcher_GEN_polar.hpp"

#include "Tools/params.h"
#include "Tools/bash_tools.h"
#include "Tools/MIPP/mipp.h"
#include "Tools/Arguments_reader.hpp"

void print_version()
{
#if defined(_WIN64) || defined(_WIN32) || defined(WIN32) || defined(__MINGW32__)
	std::string os = "Windows";
#elif defined(__linux__) || defined(__linux)
	std::string os = "Linux";
#elif defined(__APPLE__)
	std::string os = "Mac OS X";
#else
	std::string os = "Unknown OS";
#endif

#if defined(__x86_64) || defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__)
	std::string prec = " 64-bit";
#elif defined(__i386) || defined(__i386__) || defined(i386) || defined(_WIN32) || defined(__ARM_ARCH_7__)
	std::string prec = " 32-bit";
#else
	std::string prec = "";
#endif

#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC)
	std::string compiler = "icpc";
#if defined(__INTEL_COMPILER)
	std::string compiler_version = std::to_string(__INTEL_COMPILER);
#elif defined(__ICL)
	std::string compiler_version = std::to_string(__ICL);
#else
	std::string compiler_version = std::to_string(__ICC);
#endif
	compiler_version = compiler_version.substr(0,2) + "." + compiler_version.substr(2,compiler_version.size());
#elif defined(__clang__) || defined(__llvm__)
	std::string compiler = "clang++";
	std::string compiler_version = std::to_string(__clang_major__);
	compiler_version += "." + std::to_string(__clang_minor__);
#elif defined(__GNUG__) || (defined(__GNUC__) && defined(__cplusplus))
	std::string compiler = "g++";
	std::string compiler_version = std::to_string(__GNUC__);
	compiler_version += "." + std::to_string(__GNUC_MINOR__);
#else
	std::string compiler = "Unknown compiler";
	std::string compiler_version = "";
#endif
	std::string affect_version = "1.0.0";

	std::cout << "aff3ct (" << os << prec << ", " << compiler << " " << compiler_version << ", "
	          << mipp::IntructionsType << ") " << affect_version << std::endl;
	std::cout << "Copyright (c) 2016 - MIT license."                                           << std::endl;
	std::cout << "This is free software; see the source for copying conditions.  There is NO"  << std::endl;
	std::cout << "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." << std::endl;
	exit(EXIT_SUCCESS);
}

#ifdef MULTI_PREC
void read_arguments(const int argc, const char** argv, std::string &code_type, std::string &simu_type, int &prec)
#else
void read_arguments(const int argc, const char** argv, std::string &code_type, std::string &simu_type)
#endif
{
	using namespace std::chrono;

	std::map<std::string, std::string> req_args, opt_args, doc_args;
	Arguments_reader ar(argc, argv);

	req_args["code-type"] = "code_type";
	doc_args["code-type"] = "the type of codes you want to simulate (POLAR, TURBO, REPETITION, RA or RSC).";

	opt_args["simu-type"] = "simu_type";
	doc_args["simu-type"] = "the type of simulation to run (BFER [default], EXIT or GEN).";

	opt_args["v"        ] = "";
	doc_args["v"        ] = "print informations about the version of the code.";
	opt_args["version"  ] = "";
	doc_args["version"  ] = "print informations about the version of the code.";

	opt_args["h"        ] = "";
	doc_args["h"        ] = "print this help.";
	opt_args["help"     ] = "";
	doc_args["help"     ] = "print this help.";

#ifdef MULTI_PREC
	opt_args["prec"] = "prec";
	doc_args["prec"] = "the simulation precision in bit (ex: 8, 16, 32 or 64).";
#endif

	auto display_help = true;
	auto parsing = ar.parse_arguments(req_args, opt_args);

	if (ar.exist_arg("v") || ar.exist_arg("version"))
		print_version();

	if (parsing)
	{
		// required parameters
		code_type = ar.get_arg("code-type");

		// facultative parameters
		if(ar.exist_arg("simu-type")) simu_type = ar.get_arg("simu-type");
#ifdef MULTI_PREC
		if(ar.exist_arg("prec")) prec = stoi(ar.get_arg("prec"));
#endif

		display_help = false;
	}

	if (display_help)
	{
		if (ar.parse_doc_args(doc_args))
			ar.print_usage();
		else
			std::cerr << bold_red("(EE) A problem was encountered when parsing arguments documentation, exiting.")
			          << std::endl;
		exit(EXIT_FAILURE);
	}
}

template <typename B, typename R, typename Q, typename QD>
void start_simu(const int argc, const char **argv, std::string code_type, std::string simu_type)
{
	Launcher<B,R,Q> *launcher = nullptr;

	if (code_type == "POLAR")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_polar<B,R,Q>(argc, argv);
		else if (simu_type == "EXIT" && (typeid(Q) == typeid(float) || typeid(Q) == typeid(double)))
			launcher = new Launcher_EXIT_polar<B,R,Q>(argc, argv);
		else if (simu_type == "GEN")
			launcher = new Launcher_GEN_polar<B,R,Q>(argc, argv);
	}

	if (code_type == "RSC")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_RSC<B,R,Q,QD>(argc, argv);
		else if (simu_type == "BFERI")
			launcher = new Launcher_BFERI_RSC<B,R,Q,QD>(argc, argv);
		else if (simu_type == "EXIT" && (typeid(Q) == typeid(float) || typeid(Q) == typeid(double)))
			launcher = new Launcher_EXIT_RSC<B,R,Q,QD>(argc, argv);
	}

	if (code_type == "TURBO")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_turbo<B,R,Q,QD>(argc, argv);
	}

	if (code_type == "REPETITION")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_repetition<B,R,Q>(argc, argv);
	}

	if (code_type == "RA")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_RA<B,R,Q>(argc, argv);
	}

	if (code_type == "LDPC")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_LDPC<B,R,Q>(argc, argv);
		else if (simu_type == "BFERI")
			launcher = new Launcher_BFERI_LDPC<B,R,Q>(argc, argv);
	}

	if (code_type == "UNCODED")
	{
		if (simu_type == "BFER")
			launcher = new Launcher_BFER_uncoded<B,R,Q>(argc, argv);
		else if (simu_type == "BFERI")
			launcher = new Launcher_BFERI_uncoded<B,R,Q>(argc, argv);
	}

	if (launcher == nullptr)
	{
		std::cerr << bold_red("(EE) Unsupported type of codes/simulation.") << std::endl;
		exit(EXIT_FAILURE);
	}

	launcher->launch();
	delete launcher;
}

#ifndef SYSTEMC
int main(int argc, char **argv)
{
	srand(0);

	std::string code_type, simu_type = "BFER";

#ifdef MULTI_PREC
	int prec = 32;
	read_arguments(argc, (const char**)argv, code_type, simu_type, prec);

	switch (prec)
	{
		case 8:
			start_simu<B_8, R_8, Q_8, QD_8 >(argc, (const char**)argv, code_type, simu_type); break;
		case 16:
			start_simu<B_16,R_16,Q_16,QD_16>(argc, (const char**)argv, code_type, simu_type); break;
		case 32:
			start_simu<B_32,R_32,Q_32,QD_32>(argc, (const char**)argv, code_type, simu_type); break;
#if defined(__x86_64) || defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__)
		case 64:
			start_simu<B_64,R_64,Q_64,QD_64>(argc, (const char**)argv, code_type, simu_type); break;
#endif
		default:
			std::cerr << bold_red("(EE) Unsupported number of bits.") << std::endl;
			exit(EXIT_FAILURE);
			break;
	}
#else
	read_arguments(argc, (const char**)argv, code_type, simu_type);
	start_simu<B,R,Q,QD>(argc, (const char**)argv, code_type, simu_type);
#endif

	return EXIT_SUCCESS;
}
#else
int sc_main(int argc, char **argv)
{
	sc_core::sc_start(); // Start simulation

	return EXIT_SUCCESS;
}
#endif
<|endoftext|>


<commit_before>#include <iostream>

#include "Systems/OpenGLSystem.h"
#include "SCParser.h"

#ifdef OS_Win32
#include "win32.h"
#else if OS_SDL
#include "SDLSys.h"
#endif

int main(int argCount, char **argValues) {
	OpenGLSystem glsys;
	IOpSys* os = nullptr;
#ifdef OS_Win32
	os = new win32();
#else if OS_SDL
	os = new SDLSys();
#endif

	os->CreateGraphicsWindow();

	const int* version = glsys.Start();

	if (version[0] == -1) {
		std::cout<< "Error starting OpenGL!"<<std::endl;
	} else {
		std::cout<<"OpenGL version: " << version[0] << "." << version[1] << std::endl;
	}

	SCParser parser;

	parser.Parse("test.sc");

	for (int i = 0; i < parser.EntityCount(); ++i) {
		const Sigma::Parser::Entity* e = parser.GetEntity(i);
		for (auto itr = e->components.begin(); itr != e->components.end(); ++itr) {
			glsys.Factory(itr->type, e->id, const_cast<std::vector<Property>&>(itr->properties));
		}
	}

	os->SetupTimer();

	double delta;
	bool isWireframe=false;

	while (os->MessageLoop()) {
		delta = os->GetDeltaTime();
		float deltaSec = (float)delta/1000.0f;

		// Translation keys
		if (os->KeyDown('W', true)) { // Move forward
			if (os->KeyDown('B', true)) {
				glsys.Move(0.0f, 0.0f, 100.0f*deltaSec);
			} else {
				glsys.Move(0.0f, 0.0f, 10.0f*deltaSec);
			}
		} else if (os->KeyDown('S', true)) { // Move backward
			glsys.Move(0.0f, 0.0f, -10.0f*deltaSec);
		}

		if (os->KeyDown('A', true)) {
			glsys.Rotate(0.0f, -90.0f*deltaSec, 0.0f); // Yaw left.
		} else if (os->KeyDown('D', true)) {
			glsys.Rotate(0.0f, 90.0f*deltaSec, 0.0f); // Yaw right.
		}

		if (os->KeyDown('F', true)) {
			glsys.Move(-10.0f*deltaSec, 0.0f, 0.0f); // Strafe Left
		} else if (os->KeyDown('G', true)) {
			glsys.Move(10.0f*deltaSec, 0.0f, 0.0f); // Strafe Right
		}

		if (os->KeyDown('E', true)) { // Move up
			glsys.Move(0.0f, 10.0f*deltaSec, 0.0f);
		} else if (os->KeyDown('C', true)) { // Move down
			glsys.Move(0.0f, -10.0f*deltaSec, 0.0f);
		}

		if (os->KeyDown('Q', true)) { // Pitch Up
			glsys.Rotate(-90.0f * deltaSec, 0.0f, 0.0f);
		} else if (os->KeyDown('Z', true)) { // Pitch Down
			glsys.Rotate(90.0f*deltaSec, 0.0f, 0.0f);
		}

		if (os->KeyDown('R', true)) { // Roll left
			glsys.Rotate(0.0f, 0.0f, -90.0f * deltaSec);
		} else if (os->KeyDown('T', true)) { // Roll right
			glsys.Rotate(0.0f, 0.0f, 90.0f*deltaSec);
		}

		if (os->KeyUp('P', true)) { // Wireframe mode
			if (!isWireframe) {
				glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
				isWireframe = true;
			} else {
				glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
				isWireframe = false;
			}
		}

		if (glsys.Update(delta)) {
			os->Present();
		}
	}

	delete os;

	return 0;
}<commit_msg>Implemented the camera controller<commit_after>#include <iostream>

#include "Systems/OpenGLSystem.h"
#include "Controllers/GLSixDOFViewController.h"
#include "SCParser.h"

#ifdef OS_Win32
#include "win32.h"
#else if OS_SDL
#include "SDLSys.h"
#endif

int main(int argCount, char **argValues) {
	OpenGLSystem glsys;
	IOpSys* os = nullptr;
#ifdef OS_Win32
	os = new win32();
#else if OS_SDL
	os = new SDLSys();
#endif

	os->CreateGraphicsWindow();

	const int* version = glsys.Start();

	if (version[0] == -1) {
		std::cout<< "Error starting OpenGL!"<<std::endl;
	} else {
		std::cout<<"OpenGL version: " << version[0] << "." << version[1] << std::endl;
	}

	SCParser parser;

	parser.Parse("test.sc");

	for (unsigned int i = 0; i < parser.EntityCount(); ++i) {
		const Sigma::Parser::Entity* e = parser.GetEntity(i);
		for (auto itr = e->components.begin(); itr != e->components.end(); ++itr) {
			glsys.Factory(itr->type, e->id, const_cast<std::vector<Property>&>(itr->properties));
		}
	}

	Sigma::event::handler::GLSixDOFViewController cameraController(&glsys);
	IOpSys::KeybaordEventSystem.Register(&cameraController);

	os->SetupTimer();

	double delta;
	bool isWireframe=false;

	while (os->MessageLoop()) {
		delta = os->GetDeltaTime();
		float deltaSec = (float)delta/1000.0f;

		// Translation keys
		/*if (os->KeyDown('W', true)) { // Move forward
			if (os->KeyDown('B', true)) {
				glsys.Move(0.0f, 0.0f, 100.0f*deltaSec);
			} else {
				glsys.Move(0.0f, 0.0f, 10.0f*deltaSec);
			}
		} else if (os->KeyDown('S', true)) { // Move backward
			glsys.Move(0.0f, 0.0f, -10.0f*deltaSec);
		}

		if (os->KeyDown('A', true)) {
			glsys.Rotate(0.0f, -90.0f*deltaSec, 0.0f); // Yaw left.
		} else if (os->KeyDown('D', true)) {
			glsys.Rotate(0.0f, 90.0f*deltaSec, 0.0f); // Yaw right.
		}

		if (os->KeyDown('F', true)) {
			glsys.Move(-10.0f*deltaSec, 0.0f, 0.0f); // Strafe Left
		} else if (os->KeyDown('G', true)) {
			glsys.Move(10.0f*deltaSec, 0.0f, 0.0f); // Strafe Right
		}

		if (os->KeyDown('E', true)) { // Move up
			glsys.Move(0.0f, 10.0f*deltaSec, 0.0f);
		} else if (os->KeyDown('C', true)) { // Move down
			glsys.Move(0.0f, -10.0f*deltaSec, 0.0f);
		}

		if (os->KeyDown('Q', true)) { // Pitch Up
			glsys.Rotate(-90.0f * deltaSec, 0.0f, 0.0f);
		} else if (os->KeyDown('Z', true)) { // Pitch Down
			glsys.Rotate(90.0f*deltaSec, 0.0f, 0.0f);
		}

		if (os->KeyDown('R', true)) { // Roll left
			glsys.Rotate(0.0f, 0.0f, -90.0f * deltaSec);
		} else if (os->KeyDown('T', true)) { // Roll right
			glsys.Rotate(0.0f, 0.0f, 90.0f*deltaSec);
		}*/

		if (os->KeyUp('P', true)) { // Wireframe mode
			if (!isWireframe) {
				glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
				isWireframe = true;
			} else {
				glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
				isWireframe = false;
			}
		}

		if (glsys.Update(delta)) {
			os->Present();
		}
	}

	delete os;

	return 0;
}<|endoftext|>


<commit_before>#include <algorithm>
#include <array>
#include <iomanip>
#include <curl/curl.h>
#include <memory>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <system_error>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

const std::string listing("http://nwn.efupw.com/rootdir/index.dat");
const std::string patch_dir("http://nwn.efupw.com/rootdir/patch/");
const std::string update_check("");

const std::string file_checksum(const std::string &path);

size_t writefunction(const char *ptr, size_t size, size_t nmemb, void *userdata)
{
    std::string *s = static_cast<std::string *>(userdata);
    s->append(ptr, size * nmemb);
    return size * nmemb;
}

std::vector<std::string> &split(const std::string &s, char delim,
        std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim)
{
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

class Target
{
    public:
        enum class Status {
            Nonexistent,
            Outdated,
            Current
        };
        explicit Target(const std::string &name, const std::string &checksum):
            m_name(name.find_first_of('/') == std::string::npos ? name :
                    name, name.find_first_of('/') + 1, name.size() - 1),
            m_checksum(checksum)
            {}
        std::string name() const { return m_name; }
        const std::string checksum() const { return m_checksum; }

        void fetch()
        {
            std::cout << "Statting target " << name() << "...";
            std::string path;
            std::fstream fs(name(), std::ios_base::in);
            if (!fs.good())
            {
                fs.close();
                std::cout << " doesn't exist, creating new." << std::endl;
                auto elems = split(name(), '/');
                for (size_t i = 0, k = elems.size(); i < k; ++i)
                    //for (auto s : elems)
                {
                    const std::string &s(elems[i]);
                    if (s.size() && s != ".")
                    {
                        path.append((i > 0 ? "/" : "") + s);
                        // i indicates a directory.
                        if (i < k - 1)
                        {
                            auto status = mkdir(path.c_str(), S_IRWXU);
                            if (status == -1)
                            {
                                std::error_code err(errno, std::generic_category());
                                if (err != std::errc::file_exists)
                                {
                                    std::cout << "error making dir: "
                                        << path << ": "
                                        << err.message() << std::endl;
                                }
                            }
                        }
                        //std::cout << "the path: " << path << std::endl;
                    }
                }
                fs.open(path, std::ios_base::out);
                if (!fs.good())
                {
                    fs.close();
                    std::cout << "Failed to create file: " << path << std::endl;
                }
                else
                {
                    fs.close();
                    do_fetch();
                    return;
                    //std::cout << "opened path " << path << std::endl;
                }
            }
            if (fs.good())
            {
                fs.close();
                //const std::string calcsum(file_checksum(name()));
                /*
                std::cout << "calced sum for " << name()
                    << " : " << calcsum << ", expected " << checksum() << std::endl;
                    */
                //if (calcsum == checksum())
                if (status() == Status::Current)
                {
                    std::cout << " already up to date." << std::endl;
                }
                else
                {
                    std::cout << " outdated, downloading new." << std::endl;
                    do_fetch();
                }
            }
        }
        Status status()
        {
            std::ifstream is(name());
            if (!is.good())
            {
                return Status::Nonexistent;
            }
            is.close();
            auto calcsum(file_checksum(name()));
            if (calcsum == checksum())
            {
                return Status::Current;
            }
            else
            {
                return Status::Outdated;
            }
        }

    private:
        void do_fetch()
        {
            std::string s;
            std::shared_ptr<CURL *> phandle =
                std::make_shared<CURL *>(curl_easy_init());
            std::string url(patch_dir + name());
            curl_easy_setopt(*phandle, CURLOPT_URL, url.c_str());
            curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
            curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &s);
            //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
            curl_easy_perform(*phandle);
            curl_easy_cleanup(*phandle);
            phandle.reset();
            std::ofstream ofs(name());
            if (ofs.good())
            {
                ofs << s;
                ofs.close();
            }
            else
            {
                std::cout << "Couldn't write to " << name() << std::endl;
            }
        }

        std::string m_name;
        std::string m_checksum;
};

std::ostream& operator<<(std::ostream &os, const Target &t)
{
    return os << "name: " << t.name() << ", checksum: " << t.checksum();
}

class CurlGlobalInit
{
    public:
        CurlGlobalInit()
        {
            curl_global_init(CURL_GLOBAL_ALL);
        }

        ~CurlGlobalInit()
        {
            curl_global_cleanup();
        }
};

const std::string file_checksum(const std::string &path)
{
#define md_md5
#ifdef md_md5
    auto md = EVP_md5();
    const int md_len = MD5_DIGEST_LENGTH;
#else
    auto md = EVP_sha1();
    const int md_len = SHA_DIGEST_LENGTH;
#endif
    std::array<unsigned char, md_len> result;
    EVP_MD_CTX *mdctx = nullptr;
    std::ifstream is(path, std::ifstream::binary);
    if (!is.good())
    {
        std::cout << "Couldn't open file " << path
           << " for checksumming." << std::endl;
        return std::string();
    }
    else
    {
        //std::cout << "opened file " << path << std::endl;
    }

    const int length = 8192;
    std::array<unsigned char, length> buffer;
    auto buf = reinterpret_cast<char *>(buffer.data());
    mdctx = EVP_MD_CTX_create();
    int status = EVP_DigestInit_ex(mdctx, md, nullptr);
    while (status && is)
    {
        is.read(buf, length);
        status = EVP_DigestUpdate(mdctx, buffer.data(), is.gcount());
    }
    status = EVP_DigestFinal_ex(mdctx, result.data(), nullptr);
    EVP_MD_CTX_destroy(mdctx);
    std::stringstream calcsum;
    calcsum << std::setfill('0');

    for (unsigned char c : result)
    {
        calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
    }
    /*
    std::for_each(std::begin(result), std::end(result),
            [&calcsum](unsigned char c)
            {
            calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
            });
            */
    //std::cout << calcsum.str() << std::endl;
    return calcsum.str();
}

int main(int argc, char *argv[])
{
    CurlGlobalInit curl_global;
    std::string fetch;
    std::shared_ptr<CURL *> phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, listing.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);
    phandle.reset();
    //std::cout << fetch << std::endl;
    std::vector<std::string> lines(split(fetch, '\n'));
    //split(fetch, '\n', lines);
    //std::cout << lines[1] << std::endl;
    std::vector<Target> new_targets, old_targets;
    for (auto beg = std::begin(lines), end = std::end(lines);
            beg != end; ++beg)
    {
        auto data(split(*beg, '@'));
        Target t(data[0], data[data.size() - 1]);
        auto status = t.status();
        if (status == Target::Status::Nonexistent)
        {
            new_targets.push_back(std::move(t));
        }
        else if (status == Target::Status::Outdated)
        {
            old_targets.push_back(std::move(t));
        }
    }
    if (new_targets.size())
    {
        std::cout << "New targets: " << new_targets.size() << std::endl;
        for (auto &t : new_targets)
        {
            std::cout << "- " << t << std::endl;
            //t.fetch();
        }
        //std::cout << new_targets[4] << std::endl;
        new_targets[0].fetch();
        //new_targets[4].fetch();
    }
    else
    {
        std::cout << "No new targets." << std::endl;
    }

    if (old_targets.size())
    {
        std::cout << "Outdated targets: " << old_targets.size() << std::endl;
        for (auto &t : old_targets)
        {
            std::cout << "- " << t << std::endl;
        }
    }
    else
    {
        std::cout << "No targets out of date." << std::endl;
    }

    /*
    const std::string path = "bin/override/spells.2da";
    const std::string checksum("38eaad974c15e5f3119469f17e8e97a9");
    std::cout << "file checksum test: "
        << path << " = " << checksum
        << " : " << (file_checksum(path) == checksum)
        << std::endl;
    */
    std::cout << std::endl;
    return 0;
}
<commit_msg>Remove lots of commented out and/or test code.<commit_after>#include <algorithm>
#include <array>
#include <iomanip>
#include <curl/curl.h>
#include <memory>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <system_error>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

const std::string listing("http://nwn.efupw.com/rootdir/index.dat");
const std::string patch_dir("http://nwn.efupw.com/rootdir/patch/");
const std::string update_check("");

const std::string file_checksum(const std::string &path);

size_t writefunction(const char *ptr, size_t size, size_t nmemb, void *userdata)
{
    std::string *s = static_cast<std::string *>(userdata);
    s->append(ptr, size * nmemb);
    return size * nmemb;
}

std::vector<std::string> &split(const std::string &s, char delim,
        std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim)
{
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

class Target
{
    public:
        enum class Status {
            Nonexistent,
            Outdated,
            Current
        };
        explicit Target(const std::string &name, const std::string &checksum):
            m_name(name.find_first_of('/') == std::string::npos ? name :
                    name, name.find_first_of('/') + 1, name.size() - 1),
            m_checksum(checksum)
            {}
        std::string name() const { return m_name; }
        const std::string checksum() const { return m_checksum; }

        void fetch()
        {
            std::cout << "Statting target " << name() << "...";
            std::string path;
            std::fstream fs(name(), std::ios_base::in);
            if (!fs.good())
            {
                fs.close();
                std::cout << " doesn't exist, creating new." << std::endl;
                auto elems = split(name(), '/');
                for (size_t i = 0, k = elems.size(); i < k; ++i)
                {
                    const std::string &s(elems[i]);
                    if (s.size() && s != ".")
                    {
                        path.append((i > 0 ? "/" : "") + s);
                        // i indicates a directory.
                        if (i < k - 1)
                        {
                            auto status = mkdir(path.c_str(), S_IRWXU);
                            if (status == -1)
                            {
                                std::error_code err(errno, std::generic_category());
                                if (err != std::errc::file_exists)
                                {
                                    std::cout << "error making dir: "
                                        << path << ": "
                                        << err.message() << std::endl;
                                }
                            }
                        }
                    }
                }
                fs.open(path, std::ios_base::out);
                if (!fs.good())
                {
                    fs.close();
                    std::cout << "Failed to create file: " << path << std::endl;
                }
                else
                {
                    fs.close();
                    do_fetch();
                    return;
                }
            }
            if (fs.good())
            {
                fs.close();
                if (status() == Status::Current)
                {
                    std::cout << " already up to date." << std::endl;
                }
                else
                {
                    std::cout << " outdated, downloading new." << std::endl;
                    do_fetch();
                }
            }
        }
        Status status()
        {
            std::ifstream is(name());
            if (!is.good())
            {
                return Status::Nonexistent;
            }
            is.close();
            auto calcsum(file_checksum(name()));
            if (calcsum == checksum())
            {
                return Status::Current;
            }
            else
            {
                return Status::Outdated;
            }
        }

    private:
        void do_fetch()
        {
            std::string s;
            std::shared_ptr<CURL *> phandle =
                std::make_shared<CURL *>(curl_easy_init());
            std::string url(patch_dir + name());
            curl_easy_setopt(*phandle, CURLOPT_URL, url.c_str());
            curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
            curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &s);
            //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
            curl_easy_perform(*phandle);
            curl_easy_cleanup(*phandle);
            phandle.reset();
            std::ofstream ofs(name());
            if (ofs.good())
            {
                ofs << s;
                ofs.close();
            }
            else
            {
                std::cout << "Couldn't write to " << name() << std::endl;
            }
        }

        std::string m_name;
        std::string m_checksum;
};

std::ostream& operator<<(std::ostream &os, const Target &t)
{
    return os << "name: " << t.name() << ", checksum: " << t.checksum();
}

class CurlGlobalInit
{
    public:
        CurlGlobalInit()
        {
            curl_global_init(CURL_GLOBAL_ALL);
        }

        ~CurlGlobalInit()
        {
            curl_global_cleanup();
        }
};

const std::string file_checksum(const std::string &path)
{
#define md_md5
#ifdef md_md5
    auto md = EVP_md5();
    const int md_len = MD5_DIGEST_LENGTH;
#else
    auto md = EVP_sha1();
    const int md_len = SHA_DIGEST_LENGTH;
#endif
    std::array<unsigned char, md_len> result;
    EVP_MD_CTX *mdctx = nullptr;
    std::ifstream is(path, std::ifstream::binary);
    if (!is.good())
    {
        std::cout << "Couldn't open file " << path
           << " for checksumming." << std::endl;
        return std::string();
    }

    const int length = 8192;
    std::array<unsigned char, length> buffer;
    auto buf = reinterpret_cast<char *>(buffer.data());
    mdctx = EVP_MD_CTX_create();
    int status = EVP_DigestInit_ex(mdctx, md, nullptr);
    while (status && is)
    {
        is.read(buf, length);
        status = EVP_DigestUpdate(mdctx, buffer.data(), is.gcount());
    }
    status = EVP_DigestFinal_ex(mdctx, result.data(), nullptr);
    EVP_MD_CTX_destroy(mdctx);
    std::stringstream calcsum;
    calcsum << std::setfill('0');

    for (unsigned char c : result)
    {
        calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
    }
    /*
    std::for_each(std::begin(result), std::end(result),
            [&calcsum](unsigned char c)
            {
            calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
            });
            */

    return calcsum.str();
}

int main(int argc, char *argv[])
{
    CurlGlobalInit curl_global;
    std::string fetch;
    std::shared_ptr<CURL *> phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, listing.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);
    phandle.reset();

    std::vector<std::string> lines(split(fetch, '\n'));
    std::vector<Target> new_targets, old_targets;
    for (auto beg = std::begin(lines), end = std::end(lines);
            beg != end; ++beg)
    {
        auto data(split(*beg, '@'));
        Target t(data[0], data[data.size() - 1]);
        auto status = t.status();
        if (status == Target::Status::Nonexistent)
        {
            new_targets.push_back(std::move(t));
        }
        else if (status == Target::Status::Outdated)
        {
            old_targets.push_back(std::move(t));
        }
    }
    if (new_targets.size())
    {
        std::cout << "New targets: " << new_targets.size() << std::endl;
        for (auto &t : new_targets)
        {
            std::cout << "- " << t << std::endl;
            //t.fetch();
        }
    }
    else
    {
        std::cout << "No new targets." << std::endl;
    }

    if (old_targets.size())
    {
        std::cout << "Outdated targets: " << old_targets.size() << std::endl;
        for (auto &t : old_targets)
        {
            std::cout << "- " << t << std::endl;
        }
    }
    else
    {
        std::cout << "No targets out of date." << std::endl;
    }

    std::cout << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <SDL2/SDL.h>
#include "draw.hpp"

const char * game_name = "Game Of Life On Surface";
int screen_width = 640;
int screen_height = 640;
int R = 200;
field f(16, 32);
bool quit_flag = false;
SDL_Window * window = NULL;
SDL_Renderer * render = NULL;
SDL_Event event;

void game_send_error( int code ) {
    printf( "[error]: %s\n", SDL_GetError() );
    exit( code );
}

void game_event( SDL_Event * event ) {
    SDL_PollEvent( event );
    switch ( event->type ) {
        case SDL_QUIT:
            quit_flag = true;
            break;
        case SDL_WINDOWEVENT:
            if ( event->window.event == SDL_WINDOWEVENT_RESIZED ) {
                screen_width  = event->window.data1;
                screen_height = event->window.data2;
            }
            break;
        case SDL_KEYDOWN:
            switch ( event->key.keysym.sym ) {
                case SDLK_ESCAPE:
                    quit_flag = true;
                    break;
                default:
                    break;
            }
        default:
            break;
    }
}

void game_loop( void ) {
    // insert code
}

void game_render( void ) {
    SDL_RenderClear( render );
    set_coloru( COLOR_WHITE );
    draw_sphere( { screen_width / 2, screen_height / 2 }, R, f );
    set_coloru( COLOR_BLACK );
    SDL_RenderPresent( render );
}

void game_destroy( void ) {
    SDL_DestroyRenderer( render );
    SDL_DestroyWindow( window );
    SDL_Quit();
}

void game_init( void ) {
    SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS );
    window = SDL_CreateWindow( game_name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                               screen_width, screen_height, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE );
    if ( window == NULL ) {
        game_send_error( EXIT_FAILURE );
    }
    render = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC |
                                 SDL_RENDERER_TARGETTEXTURE );
    if ( render == NULL ) {
        game_send_error( EXIT_FAILURE );
    }
    SDL_SetRenderDrawBlendMode( render, SDL_BLENDMODE_BLEND );
    draw_init( render );
}

int main( int argc, char * argv[] ) {
    Uint32 FPS_MAX = 1000 / 63; // ~ 60 fps

    game_init();
    while ( quit_flag == false ) {
        game_event( &event );
        game_loop();
        game_render();
        SDL_Delay( FPS_MAX );
    }
    game_destroy();
    return EXIT_SUCCESS;
}
<commit_msg>[add] test function for draw_filled_polygon<commit_after>#include <cstdio>
#include <SDL2/SDL.h>
#include "draw.hpp"

const char * game_name = "Game Of Life On Surface";
int screen_width = 640;
int screen_height = 640;
int R = 200;
field f(16, 32);
bool quit_flag = false;
SDL_Window * window = NULL;
SDL_Renderer * render = NULL;
SDL_Event event;

void game_send_error( int code ) {
    printf( "[error]: %s\n", SDL_GetError() );
    exit( code );
}

void game_event( SDL_Event * event ) {
    SDL_PollEvent( event );
    switch ( event->type ) {
        case SDL_QUIT:
            quit_flag = true;
            break;
        case SDL_WINDOWEVENT:
            if ( event->window.event == SDL_WINDOWEVENT_RESIZED ) {
                screen_width  = event->window.data1;
                screen_height = event->window.data2;
            }
            break;
        case SDL_KEYDOWN:
            switch ( event->key.keysym.sym ) {
                case SDLK_ESCAPE:
                    quit_flag = true;
                    break;
                default:
                    break;
            }
        default:
            break;
    }
}

void game_loop( void ) {
    // insert code
}

// testing function
void draw_star( int x0, int y0, float R, float r, float angle, int n, Uint32 color ) {
    int * x = new int [n * 2 + 1];
    int * y = new int [n * 2 + 1];
    float a = 0.0f, A = 0.0f;

    angle *= M_PI / 180.0f;
    for ( int i = 0; i < n * 2; i++ ) {
        if ( i % 2 == 0 ) {
            A = R;
        } else {
            A = r / 2;
        }
        x[i] = x0 + round( A * cos( a * M_PI / 180.0f + angle ) );
        y[i] = y0 - round( A * sin( a * M_PI / 180.0f + angle ) );
        a += 180.0f / (float) n;
    }
    x[n * 2 + 1] = x[0];
    y[n * 2 + 1] = y[0];
    draw_filled_polygon( x, y, 2 * n, color );
    delete[] x;
    delete[] y;
}

void game_render( void ) {
    SDL_RenderClear( render );
    set_coloru( COLOR_WHITE );
    draw_sphere( { screen_width / 2, screen_height / 2 }, R, f );
    draw_star( screen_width / 2, screen_height / 2, R, R / 1.5f, 18.0f, 5, COLOR_RED );
    set_coloru( COLOR_BLACK );
    SDL_RenderPresent( render );
}

void game_destroy( void ) {
    SDL_DestroyRenderer( render );
    SDL_DestroyWindow( window );
    SDL_Quit();
}

void game_init( void ) {
    SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS );
    window = SDL_CreateWindow( game_name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                               screen_width, screen_height, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE );
    if ( window == NULL ) {
        game_send_error( EXIT_FAILURE );
    }
    render = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC |
                                 SDL_RENDERER_TARGETTEXTURE );
    if ( render == NULL ) {
        game_send_error( EXIT_FAILURE );
    }
    SDL_SetRenderDrawBlendMode( render, SDL_BLENDMODE_BLEND );
    draw_init( render );
}

int main( int argc, char * argv[] ) {
    Uint32 FPS_MAX = 1000 / 63; // ~ 60 fps

    game_init();
    while ( quit_flag == false ) {
        game_event( &event );
        game_loop();
        game_render();
        SDL_Delay( FPS_MAX );
    }
    game_destroy();
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "VorbisDecoder.h"
#include "libvorbis/include/vorbis/vorbisfile.h"

using namespace nqr;

class VorbisDecoderInternal
{

public:

    VorbisDecoderInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d)
    {
        void *data = const_cast<uint8_t*>(memory.data());

        ogg_file t;
        t.curPtr = t.filePtr = static_cast<char*>(data);
        t.fileSize = memory.size();

        fileHandle = new OggVorbis_File;
        memset(fileHandle, 0, sizeof(OggVorbis_File));

        ov_callbacks callbacks;
        callbacks.read_func = AR_readOgg;
        callbacks.seek_func = AR_seekOgg;
        callbacks.close_func = AR_closeOgg;
        callbacks.tell_func = AR_tellOgg;

        loadAudioData(&t, callbacks);
    }

    VorbisDecoderInternal(AudioData * d, std::string filepath) : d(d)
    {
        fileHandle = new OggVorbis_File();

        /* @todo proper steaming support + classes
         const ov_callbacks callbacks =
         {
             .read_func = s_readCallback,
             .seek_func = s_seekCallback,
             .tell_func = s_tellCallback,
             .close_func = nullptr
         };
         */

        FILE * f = fopen(filepath.c_str(), "rb");

        if (!f)
            throw std::runtime_error("Can't open file");

        loadAudioData(f, OV_CALLBACKS_DEFAULT);
    }

    ~VorbisDecoderInternal()
    {
        ov_clear(fileHandle);
    }

    size_t readInternal(size_t requestedFrameCount, size_t frameOffset = 0)
    {

        //@todo support offset

        float **buffer = nullptr;
        size_t framesRemaining = requestedFrameCount;
        size_t totalFramesRead = 0;
        int bitstream = 0;

        while(0 < framesRemaining)
        {
            int64_t framesRead = ov_read_float(fileHandle, &buffer, std::min(2048, (int) framesRemaining), &bitstream);

            // EOF
            if(!framesRead)
                break;

            if (framesRead < 0)
            {
                // Probably OV_HOLE, OV_EBADLINK, OV_EINVAL. Log warning here.
                continue;
            }

            for (int i = 0; i < framesRead; ++i)
            {
                for(int ch = 0; ch < d->channelCount; ch++)
                {
                    d->samples[totalFramesRead] = buffer[ch][i];
                    totalFramesRead++;
                }
            }

        }

        return totalFramesRead;
    }

    std::string errorAsString(int ovErrorCode)
    {
        switch(ovErrorCode)
        {
            case OV_FALSE: return "OV_FALSE";
            case OV_EOF: return "OV_EOF";
            case OV_HOLE: return "OV_HOLE";
            case OV_EREAD: return "OV_EREAD";
            case OV_EFAULT: return "OV_EFAULT";
            case OV_EIMPL: return "OV_EIMPL";
            case OV_EINVAL: return "OV_EINVAL";
            case OV_ENOTVORBIS: return "OV_ENOTVORBIS";
            case OV_EBADHEADER: return "OV_EBADHEADER";
            case OV_EVERSION: return "OV_EVERSION";
            case OV_ENOTAUDIO: return "OV_ENOTAUDIO";
            case OV_EBADPACKET: return "OV_EBADPACKET";
            case OV_EBADLINK: return "OV_EBADLINK";
            case OV_ENOSEEK: return "OV_ENOSEEK";
            default: return "OV_UNKNOWN_ERROR";
        }
    }

    //////////////////////
    // vorbis callbacks //
    //////////////////////

    //@todo: implement streaming support

private:

    struct ogg_file
    {
        char* curPtr;
        char* filePtr;
        size_t fileSize;
    };

    NO_COPY(VorbisDecoderInternal);

    OggVorbis_File * fileHandle;
    AudioData * d;

    inline int64_t getTotalSamples() const { return int64_t(ov_pcm_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
    inline int64_t getLengthInSeconds() const { return int64_t(ov_time_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
    inline int64_t getCurrentSample() const { return int64_t(ov_pcm_tell(const_cast<OggVorbis_File *>(fileHandle))); }

    static size_t AR_readOgg(void* dst, size_t size1, size_t size2, void* fh)
    {
        ogg_file* of = reinterpret_cast<ogg_file*>(fh);
        size_t len = size1 * size2;
        if ( of->curPtr + len > of->filePtr + of->fileSize )
        {
            len = of->filePtr + of->fileSize - of->curPtr;
        }
        memcpy( dst, of->curPtr, len );
        of->curPtr += len;
        return len;
    }

    static int AR_seekOgg( void *fh, ogg_int64_t to, int type ) {
        ogg_file* of = reinterpret_cast<ogg_file*>(fh);

        switch( type ) {
            case SEEK_CUR:
                of->curPtr += to;
                break;
            case SEEK_END:
                of->curPtr = of->filePtr + of->fileSize - to;
                break;
            case SEEK_SET:
                of->curPtr = of->filePtr + to;
                break;
            default:
                return -1;
        }
        if ( of->curPtr < of->filePtr ) {
            of->curPtr = of->filePtr;
            return -1;
        }
        if ( of->curPtr > of->filePtr + of->fileSize ) {
            of->curPtr = of->filePtr + of->fileSize;
            return -1;
        }
        return 0;
    }

    static int AR_closeOgg(void* fh)
    {
        return 0;
    }

    static long AR_tellOgg( void *fh )
    {
        ogg_file* of = reinterpret_cast<ogg_file*>(fh);
        return (of->curPtr - of->filePtr);
    }

    void loadAudioData(void *source, ov_callbacks callbacks)
    {
        if (auto r = ov_test_callbacks(source, fileHandle, nullptr, 0, callbacks) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("File is not a valid ogg vorbis file");
        }

        if (auto r = ov_test_open(fileHandle) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("ov_test_open failed");
        }

        // Don't need to fclose() after an open -- vorbis does this internally

        vorbis_info *ovInfo = ov_info(fileHandle, -1);

        if (ovInfo == nullptr)
        {
            throw std::runtime_error("Reading metadata failed");
        }

        if (auto r = ov_streams(fileHandle) != 1)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error( "Unsupported: file contains multiple bitstreams");
        }

        d->sampleRate = int(ovInfo->rate);
        d->channelCount = ovInfo->channels;
        d->sourceFormat = MakeFormatForBits(32, true, false);
        d->lengthSeconds = double(getLengthInSeconds());
        d->frameSize = ovInfo->channels * GetFormatBitsPerSample(d->sourceFormat);

        // Samples in a single channel
        auto totalSamples = size_t(getTotalSamples());

        d->samples.resize(totalSamples * d->channelCount);

        if (!readInternal(totalSamples))
            throw std::runtime_error("could not read any data");
    }

};

//////////////////////
// Public Interface //
//////////////////////

void VorbisDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
    VorbisDecoderInternal decoder(data, path);
}

void VorbisDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
    VorbisDecoderInternal decoder(data, memory);
}

std::vector<std::string> VorbisDecoder::GetSupportedFileExtensions()
{
    return {"ogg"};
}
<commit_msg>vorbis decoder style/formatting<commit_after>/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "VorbisDecoder.h"
#include "libvorbis/include/vorbis/vorbisfile.h"

using namespace nqr;

class VorbisDecoderInternal
{

public:

    VorbisDecoderInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d)
    {
        void * data = const_cast<uint8_t*>(memory.data());

        ogg_file t;
        t.curPtr = t.filePtr = static_cast<char*>(data);
        t.fileSize = memory.size();

        fileHandle = new OggVorbis_File;
        memset(fileHandle, 0, sizeof(OggVorbis_File));

        ov_callbacks callbacks;
        callbacks.read_func = AR_readOgg;
        callbacks.seek_func = AR_seekOgg;
        callbacks.close_func = AR_closeOgg;
        callbacks.tell_func = AR_tellOgg;

        loadAudioData(&t, callbacks);
    }

    VorbisDecoderInternal(AudioData * d, std::string filepath) : d(d)
    {
        fileHandle = new OggVorbis_File();
        FILE * f = fopen(filepath.c_str(), "rb");
        if (!f) throw std::runtime_error("Can't open file");
        loadAudioData(f, OV_CALLBACKS_DEFAULT);
    }

    ~VorbisDecoderInternal()
    {
        ov_clear(fileHandle);
    }

    size_t readInternal(size_t requestedFrameCount, size_t frameOffset = 0)
    {
        //@todo support offset

        float **buffer = nullptr;
        size_t framesRemaining = requestedFrameCount;
        size_t totalFramesRead = 0;
        int bitstream = 0;

        while(0 < framesRemaining)
        {
            int64_t framesRead = ov_read_float(fileHandle, &buffer, std::min(2048, (int) framesRemaining), &bitstream);

            // end of file
            if(!framesRead) break;

            // Probably OV_HOLE, OV_EBADLINK, OV_EINVAL. @todo - log warning here.
            if (framesRead < 0)
            {
                continue;
            }

            for (int i = 0; i < framesRead; ++i)
            {
                for(int ch = 0; ch < d->channelCount; ch++)
                {
                    d->samples[totalFramesRead] = buffer[ch][i];
                    totalFramesRead++;
                }
            }
        }

        return totalFramesRead;
    }

    std::string errorAsString(int ovErrorCode)
    {
        switch(ovErrorCode)
        {
            case OV_FALSE: return "OV_FALSE";
            case OV_EOF: return "OV_EOF";
            case OV_HOLE: return "OV_HOLE";
            case OV_EREAD: return "OV_EREAD";
            case OV_EFAULT: return "OV_EFAULT";
            case OV_EIMPL: return "OV_EIMPL";
            case OV_EINVAL: return "OV_EINVAL";
            case OV_ENOTVORBIS: return "OV_ENOTVORBIS";
            case OV_EBADHEADER: return "OV_EBADHEADER";
            case OV_EVERSION: return "OV_EVERSION";
            case OV_ENOTAUDIO: return "OV_ENOTAUDIO";
            case OV_EBADPACKET: return "OV_EBADPACKET";
            case OV_EBADLINK: return "OV_EBADLINK";
            case OV_ENOSEEK: return "OV_ENOSEEK";
            default: return "OV_UNKNOWN_ERROR";
        }
    }

    //////////////////////
    // vorbis callbacks //
    //////////////////////

    //@todo: implement streaming support

private:

    struct ogg_file
    {
        char* curPtr;
        char* filePtr;
        size_t fileSize;
    };

    NO_COPY(VorbisDecoderInternal);

    OggVorbis_File * fileHandle;
    AudioData * d;

    inline int64_t getTotalSamples() const { return int64_t(ov_pcm_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
    inline int64_t getLengthInSeconds() const { return int64_t(ov_time_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
    inline int64_t getCurrentSample() const { return int64_t(ov_pcm_tell(const_cast<OggVorbis_File *>(fileHandle))); }

    static size_t AR_readOgg(void* dst, size_t size1, size_t size2, void* fh)
    {
        ogg_file* of = reinterpret_cast<ogg_file*>(fh);
        size_t len = size1 * size2;
        if ( of->curPtr + len > of->filePtr + of->fileSize )
        {
            len = of->filePtr + of->fileSize - of->curPtr;
        }
        memcpy( dst, of->curPtr, len );
        of->curPtr += len;
        return len;
    }

    static int AR_seekOgg(void * fh, ogg_int64_t to, int type)
    {
        ogg_file * of = reinterpret_cast<ogg_file*>(fh);

        switch (type)
        {
            case SEEK_CUR: of->curPtr += to; break;
            case SEEK_END: of->curPtr = of->filePtr + of->fileSize - to; break;
            case SEEK_SET: of->curPtr = of->filePtr + to; break;
            default: return -1;
        }

        if (of->curPtr < of->filePtr)
        {
            of->curPtr = of->filePtr;
            return -1;
        }

        if (of->curPtr > of->filePtr + of->fileSize)
        {
            of->curPtr = of->filePtr + of->fileSize;
            return -1;
        }

        return 0;
    }

    static int AR_closeOgg(void * fh)
    {
        return 0;
    }

    static long AR_tellOgg(void * fh)
    {
        ogg_file * of = reinterpret_cast<ogg_file*>(fh);
        return (of->curPtr - of->filePtr);
    }

    void loadAudioData(void *source, ov_callbacks callbacks)
    {
        if (auto r = ov_test_callbacks(source, fileHandle, nullptr, 0, callbacks) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("File is not a valid ogg vorbis file");
        }

        if (auto r = ov_test_open(fileHandle) != 0)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error("ov_test_open failed");
        }

        // Don't need to fclose() after an open -- vorbis does this internally

        vorbis_info * ovInfo = ov_info(fileHandle, -1);

        if (ovInfo == nullptr) throw std::runtime_error("Reading metadata failed");

        if (auto r = ov_streams(fileHandle) != 1)
        {
            std::cerr << errorAsString(r) << std::endl;
            throw std::runtime_error( "Unsupported: file contains multiple bitstreams");
        }

        d->sampleRate = int(ovInfo->rate);
        d->channelCount = ovInfo->channels;
        d->sourceFormat = MakeFormatForBits(32, true, false);
        d->lengthSeconds = double(getLengthInSeconds());
        d->frameSize = ovInfo->channels * GetFormatBitsPerSample(d->sourceFormat);

        // Samples in a single channel
        auto totalSamples = size_t(getTotalSamples());

        d->samples.resize(totalSamples * d->channelCount);

        if (!readInternal(totalSamples)) throw std::runtime_error("could not read any data");
    }

};

//////////////////////
// Public Interface //
//////////////////////

void VorbisDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
    VorbisDecoderInternal decoder(data, path);
}

void VorbisDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
    VorbisDecoderInternal decoder(data, memory);
}

std::vector<std::string> VorbisDecoder::GetSupportedFileExtensions()
{
    return {"ogg"};
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright 2014-2015 David Simmons-Duffin.
// Distributed under the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "SDP_Solver_Parameters.hxx"

#include <El.hpp>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

int solve(const std::vector<boost::filesystem::path> &sdp_files,
          const boost::filesystem::path &out_file,
          const boost::filesystem::path &checkpoint_file_in,
          const boost::filesystem::path &checkpoint_file_out,
          const SDP_Solver_Parameters &parameters);

int main(int argc, char **argv)
{
  El::Environment env(argc, argv);

  try
    {
      std::vector<boost::filesystem::path> sdp_files;
      boost::filesystem::path out_file, checkpoint_file_in,
        checkpoint_file_out, param_file;

      SDP_Solver_Parameters parameters;

      po::options_description basic_options("Basic options");
      basic_options.add_options()("help,h", "Show this helpful message.")(
        "sdpFile,s",
        po::value<std::vector<boost::filesystem::path>>(&sdp_files)->required(),
        "SDP data file(s) in XML format. Use this option repeatedly to "
        "specify "
        "multiple data files.")(
        "paramFile,p", po::value<boost::filesystem::path>(&param_file),
        "Any parameter can optionally be set via this file in key=value "
        "format. Command line arguments override values in the parameter "
        "file.")("outFile,o", po::value<boost::filesystem::path>(&out_file),
                 "The optimal solution is saved to this file in Mathematica "
                 "format. Defaults to sdpFile with '.out' extension.")(
        "checkpointFile,c",
        po::value<boost::filesystem::path>(&checkpoint_file_out),
        "Checkpoints are saved to this file every checkpointInterval. "
        "Defaults "
        "to sdpFile with '.ck' extension.")(
        "initialCheckpointFile,i",
        po::value<boost::filesystem::path>(&checkpoint_file_in),
        "The initial checkpoint to load. Defaults to checkpointFile.");

      // We set default parameters using El::BigFloat("1e-10",10)
      // rather than a straight double precision 1e-10 so that results
      // are more reproducible at high precision.  Using double
      // precision defaults results in differences of about 1e-15 in
      // primalObjective after one step.
      po::options_description solver_params_options("Solver parameters");
      solver_params_options.add_options()(
        "precision", po::value<int>(&parameters.precision)->default_value(400),
        "Precision in binary digits.  GMP will round up to the nearest "
        "multiple of 64 (or 32 on older systems).")(
        "checkpointInterval",
        po::value<int>(&parameters.checkpoint_interval)->default_value(3600),
        "Save checkpoints to checkpointFile every checkpointInterval "
        "seconds.")(
        "noFinalCheckpoint",
        po::bool_switch(&parameters.no_final_checkpoint)->default_value(false),
        "Don't save a final checkpoint after terminating (useful when "
        "debugging).")(
        "findPrimalFeasible",
        po::bool_switch(&parameters.find_primal_feasible)->default_value(false),
        "Terminate once a primal feasible solution is found.")(
        "findDualFeasible",
        po::bool_switch(&parameters.find_dual_feasible)->default_value(false),
        "Terminate once a dual feasible solution is found.")(
        "detectPrimalFeasibleJump",
        po::bool_switch(&parameters.detect_primal_feasible_jump)
          ->default_value(false),
        "Terminate if a primal-step of 1 is taken. This often indicates that "
        "a "
        "primal feasible solution would be found if the precision were high "
        "enough. Try increasing either primalErrorThreshold or precision "
        "and run from the latest checkpoint.")(
        "detectDualFeasibleJump",
        po::bool_switch(&parameters.detect_dual_feasible_jump)
          ->default_value(false),
        "Terminate if a dual-step of 1 is taken. This often indicates that a "
        "dual feasible solution would be found if the precision were high "
        "enough. Try increasing either dualErrorThreshold or precision "
        "and run from the latest checkpoint.")(
        "maxIterations",
        po::value<int>(&parameters.max_iterations)->default_value(500),
        "Maximum number of iterations to run the solver.")(
        "maxRuntime",
        po::value<int>(&parameters.max_runtime)->default_value(86400),
        "Maximum amount of time to run the solver in seconds.")(
        "dualityGapThreshold",
        po::value<El::BigFloat>(&parameters.duality_gap_threshold_elemental)
          ->default_value(El::BigFloat("1e-30", 10)),
        "Threshold for duality gap (roughly the difference in primal and dual "
        "objective) at which the solution is considered "
        "optimal. Corresponds to SDPA's epsilonStar.")(
        "primalErrorThreshold",
        po::value<El::BigFloat>(&parameters.primal_error_threshold_elemental)
          ->default_value(El::BigFloat("1e-30", 10)),
        "Threshold for feasibility of the primal problem. Corresponds to "
        "SDPA's epsilonBar.")(
        "dualErrorThreshold",
        po::value<El::BigFloat>(&parameters.dual_error_threshold_elemental)
          ->default_value(El::BigFloat("1e-30", 10)),
        "Threshold for feasibility of the dual problem. Corresponds to SDPA's "
        "epsilonBar.")(
        "initialMatrixScalePrimal",
        po::value<El::BigFloat>(
          &parameters.initial_matrix_scale_primal_elemental)
          ->default_value(El::BigFloat("1e20", 10)),
        "The primal matrix X begins at initialMatrixScalePrimal times the "
        "identity matrix. Corresponds to SDPA's lambdaStar.")(
        "initialMatrixScaleDual",
        po::value<El::BigFloat>(
          &parameters.initial_matrix_scale_dual_elemental)
          ->default_value(El::BigFloat("1e20", 10)),
        "The dual matrix Y begins at initialMatrixScaleDual times the "
        "identity matrix. Corresponds to SDPA's lambdaStar.")(
        "feasibleCenteringParameter",
        po::value<El::BigFloat>(
          &parameters.feasible_centering_parameter_elemental)
          ->default_value(El::BigFloat("0.1", 10)),
        "Shrink the complementarity X Y by this factor when the primal and "
        "dual "
        "problems are feasible. Corresponds to SDPA's betaStar.")(
        "infeasibleCenteringParameter",
        po::value<El::BigFloat>(
          &parameters.infeasible_centering_parameter_elemental)
          ->default_value(El::BigFloat("0.3", 10)),
        "Shrink the complementarity X Y by this factor when either the primal "
        "or dual problems are infeasible. Corresponds to SDPA's betaBar.")(
        "stepLengthReduction",
        po::value<El::BigFloat>(&parameters.step_length_reduction_elemental)
          ->default_value(El::BigFloat("0.7", 10)),
        "Shrink each newton step by this factor (smaller means slower, more "
        "stable convergence). Corresponds to SDPA's gammaStar.")(
        "maxComplementarity",
        po::value<El::BigFloat>(&parameters.max_complementarity_elemental)
          ->default_value(El::BigFloat("1e100", 10)),
        "Terminate if the complementarity mu = Tr(X Y)/dim(X) "
        "exceeds this value.");

      po::options_description cmd_line_options;
      cmd_line_options.add(basic_options).add(solver_params_options);

      po::variables_map variables_map;

      try
        {
          po::store(po::parse_command_line(argc, argv, cmd_line_options),
                    variables_map);

          if(variables_map.count("help"))
            {
              std::cout << cmd_line_options << '\n';
              return 0;
            }

          if(variables_map.count("paramFile"))
            {
              param_file
                = variables_map["paramFile"].as<boost::filesystem::path>();
              std::ifstream ifs(param_file.string().c_str());
              po::store(po::parse_config_file(ifs, solver_params_options),
                        variables_map);
            }

          po::notify(variables_map);

          if(!variables_map.count("outFile"))
            {
              out_file = sdp_files[0];
              out_file.replace_extension("out");
            }

          if(!variables_map.count("checkpointFile"))
            {
              checkpoint_file_out = sdp_files[0];
              checkpoint_file_out.replace_extension("ck");
            }

          if(!variables_map.count("initialCheckpointFile"))
            {
              checkpoint_file_in = checkpoint_file_out;
            }

          std::ofstream ofs(out_file.string().c_str());
          ofs.close();
          if(!ofs)
            {
              std::cerr << "Cannot write to outFile." << '\n';
              return 1;
            }
        }
      catch(po::error &e)
        {
          std::cerr << "ERROR: " << e.what() << '\n';
          std::cerr << cmd_line_options << '\n';
          return 1;
        }

      // Set the default precision of all Real numbers to that specified
      // by the 'precision' parameter.
      mpf_set_default_prec(parameters.precision);
      El::gmp::SetPrecision(1024);
      El::mpfr::SetPrecision(parameters.precision);

      // Set std::cout to print the appropriate number of digits
      std::cout.precision(
        std::min(static_cast<int>(parameters.precision * 0.31 + 5), 30));

      return solve(sdp_files, out_file, checkpoint_file_in,
                   checkpoint_file_out, parameters);
    }
  catch(std::exception &e)
    {
      El::ReportException(e);
    }
  return 1;
}
<commit_msg>Do not set cout.precision since it gets overwritten anyway.<commit_after>//=======================================================================
// Copyright 2014-2015 David Simmons-Duffin.
// Distributed under the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "SDP_Solver_Parameters.hxx"

#include <El.hpp>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

int solve(const std::vector<boost::filesystem::path> &sdp_files,
          const boost::filesystem::path &out_file,
          const boost::filesystem::path &checkpoint_file_in,
          const boost::filesystem::path &checkpoint_file_out,
          const SDP_Solver_Parameters &parameters);

int main(int argc, char **argv)
{
  El::Environment env(argc, argv);

  try
    {
      std::vector<boost::filesystem::path> sdp_files;
      boost::filesystem::path out_file, checkpoint_file_in,
        checkpoint_file_out, param_file;

      SDP_Solver_Parameters parameters;

      po::options_description basic_options("Basic options");
      basic_options.add_options()("help,h", "Show this helpful message.")(
        "sdpFile,s",
        po::value<std::vector<boost::filesystem::path>>(&sdp_files)->required(),
        "SDP data file(s) in XML format. Use this option repeatedly to "
        "specify "
        "multiple data files.")(
        "paramFile,p", po::value<boost::filesystem::path>(&param_file),
        "Any parameter can optionally be set via this file in key=value "
        "format. Command line arguments override values in the parameter "
        "file.")("outFile,o", po::value<boost::filesystem::path>(&out_file),
                 "The optimal solution is saved to this file in Mathematica "
                 "format. Defaults to sdpFile with '.out' extension.")(
        "checkpointFile,c",
        po::value<boost::filesystem::path>(&checkpoint_file_out),
        "Checkpoints are saved to this file every checkpointInterval. "
        "Defaults "
        "to sdpFile with '.ck' extension.")(
        "initialCheckpointFile,i",
        po::value<boost::filesystem::path>(&checkpoint_file_in),
        "The initial checkpoint to load. Defaults to checkpointFile.");

      // We set default parameters using El::BigFloat("1e-10",10)
      // rather than a straight double precision 1e-10 so that results
      // are more reproducible at high precision.  Using double
      // precision defaults results in differences of about 1e-15 in
      // primalObjective after one step.
      po::options_description solver_params_options("Solver parameters");
      solver_params_options.add_options()(
        "precision", po::value<int>(&parameters.precision)->default_value(400),
        "Precision in binary digits.  GMP will round up to the nearest "
        "multiple of 64 (or 32 on older systems).")(
        "checkpointInterval",
        po::value<int>(&parameters.checkpoint_interval)->default_value(3600),
        "Save checkpoints to checkpointFile every checkpointInterval "
        "seconds.")(
        "noFinalCheckpoint",
        po::bool_switch(&parameters.no_final_checkpoint)->default_value(false),
        "Don't save a final checkpoint after terminating (useful when "
        "debugging).")(
        "findPrimalFeasible",
        po::bool_switch(&parameters.find_primal_feasible)->default_value(false),
        "Terminate once a primal feasible solution is found.")(
        "findDualFeasible",
        po::bool_switch(&parameters.find_dual_feasible)->default_value(false),
        "Terminate once a dual feasible solution is found.")(
        "detectPrimalFeasibleJump",
        po::bool_switch(&parameters.detect_primal_feasible_jump)
          ->default_value(false),
        "Terminate if a primal-step of 1 is taken. This often indicates that "
        "a "
        "primal feasible solution would be found if the precision were high "
        "enough. Try increasing either primalErrorThreshold or precision "
        "and run from the latest checkpoint.")(
        "detectDualFeasibleJump",
        po::bool_switch(&parameters.detect_dual_feasible_jump)
          ->default_value(false),
        "Terminate if a dual-step of 1 is taken. This often indicates that a "
        "dual feasible solution would be found if the precision were high "
        "enough. Try increasing either dualErrorThreshold or precision "
        "and run from the latest checkpoint.")(
        "maxIterations",
        po::value<int>(&parameters.max_iterations)->default_value(500),
        "Maximum number of iterations to run the solver.")(
        "maxRuntime",
        po::value<int>(&parameters.max_runtime)->default_value(86400),
        "Maximum amount of time to run the solver in seconds.")(
        "dualityGapThreshold",
        po::value<El::BigFloat>(&parameters.duality_gap_threshold_elemental)
          ->default_value(El::BigFloat("1e-30", 10)),
        "Threshold for duality gap (roughly the difference in primal and dual "
        "objective) at which the solution is considered "
        "optimal. Corresponds to SDPA's epsilonStar.")(
        "primalErrorThreshold",
        po::value<El::BigFloat>(&parameters.primal_error_threshold_elemental)
          ->default_value(El::BigFloat("1e-30", 10)),
        "Threshold for feasibility of the primal problem. Corresponds to "
        "SDPA's epsilonBar.")(
        "dualErrorThreshold",
        po::value<El::BigFloat>(&parameters.dual_error_threshold_elemental)
          ->default_value(El::BigFloat("1e-30", 10)),
        "Threshold for feasibility of the dual problem. Corresponds to SDPA's "
        "epsilonBar.")(
        "initialMatrixScalePrimal",
        po::value<El::BigFloat>(
          &parameters.initial_matrix_scale_primal_elemental)
          ->default_value(El::BigFloat("1e20", 10)),
        "The primal matrix X begins at initialMatrixScalePrimal times the "
        "identity matrix. Corresponds to SDPA's lambdaStar.")(
        "initialMatrixScaleDual",
        po::value<El::BigFloat>(
          &parameters.initial_matrix_scale_dual_elemental)
          ->default_value(El::BigFloat("1e20", 10)),
        "The dual matrix Y begins at initialMatrixScaleDual times the "
        "identity matrix. Corresponds to SDPA's lambdaStar.")(
        "feasibleCenteringParameter",
        po::value<El::BigFloat>(
          &parameters.feasible_centering_parameter_elemental)
          ->default_value(El::BigFloat("0.1", 10)),
        "Shrink the complementarity X Y by this factor when the primal and "
        "dual "
        "problems are feasible. Corresponds to SDPA's betaStar.")(
        "infeasibleCenteringParameter",
        po::value<El::BigFloat>(
          &parameters.infeasible_centering_parameter_elemental)
          ->default_value(El::BigFloat("0.3", 10)),
        "Shrink the complementarity X Y by this factor when either the primal "
        "or dual problems are infeasible. Corresponds to SDPA's betaBar.")(
        "stepLengthReduction",
        po::value<El::BigFloat>(&parameters.step_length_reduction_elemental)
          ->default_value(El::BigFloat("0.7", 10)),
        "Shrink each newton step by this factor (smaller means slower, more "
        "stable convergence). Corresponds to SDPA's gammaStar.")(
        "maxComplementarity",
        po::value<El::BigFloat>(&parameters.max_complementarity_elemental)
          ->default_value(El::BigFloat("1e100", 10)),
        "Terminate if the complementarity mu = Tr(X Y)/dim(X) "
        "exceeds this value.");

      po::options_description cmd_line_options;
      cmd_line_options.add(basic_options).add(solver_params_options);

      po::variables_map variables_map;

      try
        {
          po::store(po::parse_command_line(argc, argv, cmd_line_options),
                    variables_map);

          if(variables_map.count("help"))
            {
              std::cout << cmd_line_options << '\n';
              return 0;
            }

          if(variables_map.count("paramFile"))
            {
              param_file
                = variables_map["paramFile"].as<boost::filesystem::path>();
              std::ifstream ifs(param_file.string().c_str());
              po::store(po::parse_config_file(ifs, solver_params_options),
                        variables_map);
            }

          po::notify(variables_map);

          if(!variables_map.count("outFile"))
            {
              out_file = sdp_files[0];
              out_file.replace_extension("out");
            }

          if(!variables_map.count("checkpointFile"))
            {
              checkpoint_file_out = sdp_files[0];
              checkpoint_file_out.replace_extension("ck");
            }

          if(!variables_map.count("initialCheckpointFile"))
            {
              checkpoint_file_in = checkpoint_file_out;
            }

          std::ofstream ofs(out_file.string().c_str());
          ofs.close();
          if(!ofs)
            {
              std::cerr << "Cannot write to outFile." << '\n';
              return 1;
            }
        }
      catch(po::error &e)
        {
          std::cerr << "ERROR: " << e.what() << '\n';
          std::cerr << cmd_line_options << '\n';
          return 1;
        }

      // Set the default precision of all Real numbers to that specified
      // by the 'precision' parameter.
      mpf_set_default_prec(parameters.precision);
      El::gmp::SetPrecision(1024);
      El::mpfr::SetPrecision(parameters.precision);

      return solve(sdp_files, out_file, checkpoint_file_in,
                   checkpoint_file_out, parameters);
    }
  catch(std::exception &e)
    {
      El::ReportException(e);
    }
  return 1;
}
<|endoftext|>


<commit_before>#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <iostream>
using namespace std;

std::mutex mut;
std::condition_variable cond;
bool go = false;

typedef char buffer[4096*2];
using atom = std::atomic<size_t>;
typedef void (*fnc_type)(size_t, size_t);

atom lock_instr_test;

struct {
    atom v1;
    atom v2;
} __attribute__((aligned(64))) test_same_line;

struct test_different_line {
    buffer back;
    atom value;
    buffer front;
};

test_different_line *lines;

void test_single_add(size_t id, size_t nrun) {
    for (size_t i = 0; i < nrun; i++) {
        lock_instr_test.fetch_add(1, std::memory_order_relaxed);
    }
}

void test_single_cas(size_t id, size_t nrun) {
    size_t dummy;
    for (size_t i = 0; i < nrun; i++) {
        while (!lock_instr_test.compare_exchange_weak(dummy,
                                                      dummy+1,
                                                      std::memory_order_relaxed,
                                                      std::memory_order_relaxed))
        {}
    }
}

void test_mfence(size_t id, size_t nrun) {
    for (size_t i = 0; i < nrun; i++) {
        std::atomic_thread_fence(std::memory_order_seq_cst);
    }
}

void test_same_line_f(size_t id, size_t nrun) {
    atom *a;
    if (id % 2) {
        a = &test_same_line.v1;
    }
    else {
        a = &test_same_line.v2;
    }

    for (size_t i = 0; i < nrun; i++) {
        a->fetch_add(1, std::memory_order_relaxed);
    }
}

void test_different_line_f(size_t id, size_t nrun) {
    atom *a = &lines[id].value;
    for (size_t i = 0; i < nrun; i++) {
        a->fetch_add(1, std::memory_order_relaxed);
    }
}

void time_threads(size_t ntesters, size_t nrun, fnc_type op, std::string name) {
    std::thread *ths = new std::thread[ntesters];
    for (size_t i = 0; i < ntesters; i++) {
        ths[i] = std::thread([=i, &]() {
            {
                std::unique_lock<std::mutex> lck(mut);
                cond.wait(lck, [&]() {return go; });
            }
            op(i, nrun);
        });
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
    auto cclock = std::chrono::steady_clock::now();
    go = true;
    cond.notify_all();
    for (size_t i = 0; i < ntesters; i++) {
        ths[i].join();
    }
    auto diff = std::chrono::steady_clock::now() - cclock;
    auto td = chrono::duration_cast<chrono::milliseconds>(diff).count() - 5;
    double tdiff = ((double)td / 1000.0);
    auto nthread = ntesters;
    auto total_elem = (nthread * nrun); //* 2 since popping them all
    auto elempt = total_elem / tdiff;
    auto elemptpt = elempt / nthread;
    cout << "Took " << tdiff
         << " seconds for " << nthread << " threads and "
         << nrun << " elements per thread" << endl
         << "This amounts to " << elemptpt
         << " operations per thread per second "
         << "for " << name << endl << endl;
    delete[] ths;
}

int main() {
    size_t num_test = 3e7;
    for (size_t i = 1; i <= 10; i++) {
        time_threads(i, num_test, test_single_add, "same add");
        time_threads(i, num_test, test_single_cas, "same cas");
        time_threads(i, num_test, test_mfence, "mfence");
        time_threads(i, num_test, test_same_line_f, "same line");
        lines = new test_different_line[i+1];
        time_threads(i, num_test, test_different_line_f, "different_lines");
        delete[] lines;
        cout << endl << endl;
    }

    return 0;
}
<commit_msg>Fixed error<commit_after>#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <iostream>
using namespace std;

std::mutex mut;
std::condition_variable cond;
bool go = false;

typedef char buffer[4096*2];
using atom = std::atomic<size_t>;
typedef void (*fnc_type)(size_t, size_t);

atom lock_instr_test;

struct {
    atom v1;
    atom v2;
} __attribute__((aligned(64))) test_same_line;

struct test_different_line {
    buffer back;
    atom value;
    buffer front;
};

test_different_line *lines;

void test_single_add(size_t id, size_t nrun) {
    for (size_t i = 0; i < nrun; i++) {
        lock_instr_test.fetch_add(1, std::memory_order_relaxed);
    }
}

void test_single_cas(size_t id, size_t nrun) {
    size_t dummy;
    for (size_t i = 0; i < nrun; i++) {
        while (!lock_instr_test.compare_exchange_weak(dummy,
                                                      dummy+1,
                                                      std::memory_order_relaxed,
                                                      std::memory_order_relaxed))
        {}
    }
}

void test_mfence(size_t id, size_t nrun) {
    for (size_t i = 0; i < nrun; i++) {
        std::atomic_thread_fence(std::memory_order_seq_cst);
    }
}

void test_same_line_f(size_t id, size_t nrun) {
    atom *a;
    if (id % 2) {
        a = &test_same_line.v1;
    }
    else {
        a = &test_same_line.v2;
    }

    for (size_t i = 0; i < nrun; i++) {
        a->fetch_add(1, std::memory_order_relaxed);
    }
}

void test_different_line_f(size_t id, size_t nrun) {
    atom *a = &lines[id].value;
    for (size_t i = 0; i < nrun; i++) {
        a->fetch_add(1, std::memory_order_relaxed);
    }
}

void time_threads(size_t ntesters, size_t nrun, fnc_type op, std::string name) {
    std::thread *ths = new std::thread[ntesters];
    for (size_t i = 0; i < ntesters; i++) {
        ths[i] = std::thread([&]() {
            {
                std::unique_lock<std::mutex> lck(mut);
                cond.wait(lck, [&]() {return go; });
            }
            op(i, nrun);
        });
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
    auto cclock = std::chrono::steady_clock::now();
    go = true;
    cond.notify_all();
    for (size_t i = 0; i < ntesters; i++) {
        ths[i].join();
    }
    auto diff = std::chrono::steady_clock::now() - cclock;
    auto td = chrono::duration_cast<chrono::milliseconds>(diff).count() - 5;
    double tdiff = ((double)td / 1000.0);
    auto nthread = ntesters;
    auto total_elem = (nthread * nrun); //* 2 since popping them all
    auto elempt = total_elem / tdiff;
    auto elemptpt = elempt / nthread;
    cout << "Took " << tdiff
         << " seconds for " << nthread << " threads and "
         << nrun << " elements per thread" << endl
         << "This amounts to " << elemptpt
         << " operations per thread per second "
         << "for " << name << endl << endl;
    delete[] ths;
}

int main() {
    size_t num_test = 3e7;
    for (size_t i = 1; i <= 10; i++) {
        time_threads(i, num_test, test_single_add, "same add");
        time_threads(i, num_test, test_single_cas, "same cas");
        time_threads(i, num_test, test_mfence, "mfence");
        time_threads(i, num_test, test_same_line_f, "same line");
        lines = new test_different_line[i+1];
        time_threads(i, num_test, test_different_line_f, "different_lines");
        delete[] lines;
        cout << endl << endl;
    }

    return 0;
}
<|endoftext|>