<commit_before>/******************************************************************************

  This source file is part of the Avogadro project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "glrenderer.h"

#include "avogadrogl.h"

#include "shader.h"
#include "shaderprogram.h"
#include "geometrynode.h"
#include "glrendervisitor.h"
#include "textlabel2d.h"
#include "textlabel3d.h"
#include "textrenderstrategy.h"
#include "visitor.h"

#include <avogadro/core/matrix.h>

#include <iostream>

namespace Avogadro {
namespace Rendering {

GLRenderer::GLRenderer()
  : m_valid(false),
    m_textRenderStrategy(NULL),
    m_center(Vector3f::Zero()),
    m_radius(20.0)
{
  m_overlayCamera.setIdentity();
}

GLRenderer::~GLRenderer()
{
  delete m_textRenderStrategy;
}

void GLRenderer::initialize()
{
  GLenum result = glewInit();
  m_valid = (result == GLEW_OK);
  if (!m_valid) {
    m_error += "GLEW could not be initialized.\n";
    return;
  }

  if (!GLEW_VERSION_2_0) {
    m_error += "GL version 2.0 is not supported by your graphics driver.\n";
    m_valid = false;
    return;
  }

  resetCamera();
}

void GLRenderer::resize(int width, int height)
{
  if (!m_valid)
    return;

  glViewport(0, 0, static_cast<GLint>(width), static_cast<GLint>(height));
  m_camera.setViewport(width, height);
  m_overlayCamera.setViewport(width, height);
}

void GLRenderer::render()
{
  if (!m_valid)
    return;

  Vector4ub c = m_scene.backgroundColor();
  glClearColor(c[0] / 255.0f, c[1] / 255.0f, c[2] / 255.0f, c[3] / 255.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  applyProjection();

  GLRenderVisitor visitor(m_camera, m_textRenderStrategy);
  // Setup for opaque geometry
  visitor.setRenderPass(OpaquePass);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_BLEND);
  m_scene.rootNode().accept(visitor);

  // Setup for transparent geometry
  visitor.setRenderPass(TranslucentPass);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  m_scene.rootNode().accept(visitor);

  // Setup for 3d overlay rendering
  visitor.setRenderPass(Overlay3DPass);
  glClear(GL_DEPTH_BUFFER_BIT);
  m_scene.rootNode().accept(visitor);

  // Setup for 2d overlay rendering
  visitor.setRenderPass(Overlay2DPass);
  visitor.setCamera(m_overlayCamera);
  glDisable(GL_DEPTH_TEST);
  m_scene.rootNode().accept(visitor);
}

void GLRenderer::resetCamera()
{
  resetGeometry();
  m_camera.setIdentity();
  m_camera.translate(-m_center);
  m_camera.preTranslate(-2.22f * m_radius * Vector3f::UnitZ());
}

void GLRenderer::resetGeometry()
{
  m_center = m_scene.center();
  m_radius = m_scene.radius();
}

void GLRenderer::setTextRenderStrategy(TextRenderStrategy *tren)
{
  if (tren != m_textRenderStrategy) {
    // Force all labels to be regenerated on the next render:
    class ResetTextLabelVisitor : public Visitor
    {
    public:
      void visit(Node &) { return; }
      void visit(GroupNode &) { return; }
      void visit(GeometryNode &) { return; }
      void visit(Drawable &) { return; }
      void visit(SphereGeometry &) { return; }
      void visit(AmbientOcclusionSphereGeometry &) { return; }
      void visit(CylinderGeometry &) { return; }
      void visit(MeshGeometry &) { return; }
      void visit(Texture2D &) { return; }
      void visit(TextLabel2D &l) { l.resetTexture(); }
      void visit(TextLabel3D &l) { l.resetTexture(); }
      void visit(LineStripGeometry &) { return; }
    } labelResetter;

    m_scene.rootNode().accept(labelResetter);

    delete m_textRenderStrategy;
    m_textRenderStrategy = tren;
  }
}

void GLRenderer::applyProjection()
{
  float distance = m_camera.distance(m_center);
  if (m_camera.projectionType() == Perspective) {
    m_camera.calculatePerspective(40.0f,
                                  std::max(2.0f, distance - m_radius),
                                  distance + m_radius);
  }
  else {
    // Renders the orthographic projection of the molecule
    const double halfHeight = m_radius;
    const double halfWidth = halfHeight * m_camera.width() / m_camera.height();
    m_camera.calculateOrthographic(-halfWidth, halfWidth,
                                   -halfHeight, halfHeight,
                                   std::max(2.0f, distance - m_radius),
                                   distance + m_radius);
  }
  m_overlayCamera.calculateOrthographic(
        0.f, static_cast<float>(m_overlayCamera.width()),
        0.f, static_cast<float>(m_overlayCamera.height()),
        -1.f, 1.f);
}

std::multimap<float, Identifier>
GLRenderer::hits(const GroupNode *group, const Vector3f &rayOrigin,
                 const Vector3f &rayEnd, const Vector3f &rayDirection) const
{
  std::multimap<float, Identifier> result;
  if (!group)
    return result;

  for (std::vector<Node *>::const_iterator it = group->children().begin();
       it != group->children().end(); ++it) {
    std::multimap<float, Identifier> loopHits;
    const Node *itNode = *it;
    const GroupNode *childGroup = dynamic_cast<const GroupNode *>(itNode);
    if (childGroup) {
      loopHits = hits(childGroup, rayOrigin, rayEnd, rayDirection);
      result.insert(loopHits.begin(), loopHits.end());
      continue;
    }
    const GeometryNode *childGeometry = (*it)->cast<GeometryNode>();
    if (childGeometry) {
      loopHits = hits(childGeometry, rayOrigin, rayEnd, rayDirection);
      result.insert(loopHits.begin(), loopHits.end());
      continue;
    }
  }
  return result;
}

std::multimap<float, Identifier>
GLRenderer::hits(const GeometryNode *geometry, const Vector3f &rayOrigin,
                 const Vector3f &rayEnd, const Vector3f &rayDirection) const
{
  if (!geometry)
    return std::multimap<float, Identifier>();
  return geometry->hits(rayOrigin, rayEnd, rayDirection);
}

std::multimap<float, Identifier> GLRenderer::hits(int x, int y) const
{
  // Our ray:
  const Vector3f origin(m_camera.unProject(Vector3f(static_cast<float>(x),
                                                    static_cast<float>(y),
                                                    0.f)));
  const Vector3f end(m_camera.unProject(Vector3f(static_cast<float>(x),
                                                 static_cast<float>(y), 1.f)));
  const Vector3f direction((end - origin).normalized());

  return hits(&m_scene.rootNode(), origin, end, direction);
}

} // End Rendering namespace
} // End Avogadro namespace
<commit_msg>Don't reset the camera on scene initialization<commit_after>/******************************************************************************

  This source file is part of the Avogadro project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "glrenderer.h"

#include "avogadrogl.h"

#include "shader.h"
#include "shaderprogram.h"
#include "geometrynode.h"
#include "glrendervisitor.h"
#include "textlabel2d.h"
#include "textlabel3d.h"
#include "textrenderstrategy.h"
#include "visitor.h"

#include <avogadro/core/matrix.h>

#include <iostream>

namespace Avogadro {
namespace Rendering {

GLRenderer::GLRenderer()
  : m_valid(false),
    m_textRenderStrategy(NULL),
    m_center(Vector3f::Zero()),
    m_radius(20.0)
{
  m_overlayCamera.setIdentity();
}

GLRenderer::~GLRenderer()
{
  delete m_textRenderStrategy;
}

void GLRenderer::initialize()
{
  GLenum result = glewInit();
  m_valid = (result == GLEW_OK);
  if (!m_valid) {
    m_error += "GLEW could not be initialized.\n";
    return;
  }

  if (!GLEW_VERSION_2_0) {
    m_error += "GL version 2.0 is not supported by your graphics driver.\n";
    m_valid = false;
    return;
  }
}

void GLRenderer::resize(int width, int height)
{
  if (!m_valid)
    return;

  glViewport(0, 0, static_cast<GLint>(width), static_cast<GLint>(height));
  m_camera.setViewport(width, height);
  m_overlayCamera.setViewport(width, height);
}

void GLRenderer::render()
{
  if (!m_valid)
    return;

  Vector4ub c = m_scene.backgroundColor();
  glClearColor(c[0] / 255.0f, c[1] / 255.0f, c[2] / 255.0f, c[3] / 255.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  applyProjection();

  GLRenderVisitor visitor(m_camera, m_textRenderStrategy);
  // Setup for opaque geometry
  visitor.setRenderPass(OpaquePass);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_BLEND);
  m_scene.rootNode().accept(visitor);

  // Setup for transparent geometry
  visitor.setRenderPass(TranslucentPass);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  m_scene.rootNode().accept(visitor);

  // Setup for 3d overlay rendering
  visitor.setRenderPass(Overlay3DPass);
  glClear(GL_DEPTH_BUFFER_BIT);
  m_scene.rootNode().accept(visitor);

  // Setup for 2d overlay rendering
  visitor.setRenderPass(Overlay2DPass);
  visitor.setCamera(m_overlayCamera);
  glDisable(GL_DEPTH_TEST);
  m_scene.rootNode().accept(visitor);
}

void GLRenderer::resetCamera()
{
  resetGeometry();
  m_camera.setIdentity();
  m_camera.translate(-m_center);
  m_camera.preTranslate(-2.22f * m_radius * Vector3f::UnitZ());
}

void GLRenderer::resetGeometry()
{
  m_center = m_scene.center();
  m_radius = m_scene.radius();
}

void GLRenderer::setTextRenderStrategy(TextRenderStrategy *tren)
{
  if (tren != m_textRenderStrategy) {
    // Force all labels to be regenerated on the next render:
    class ResetTextLabelVisitor : public Visitor
    {
    public:
      void visit(Node &) { return; }
      void visit(GroupNode &) { return; }
      void visit(GeometryNode &) { return; }
      void visit(Drawable &) { return; }
      void visit(SphereGeometry &) { return; }
      void visit(AmbientOcclusionSphereGeometry &) { return; }
      void visit(CylinderGeometry &) { return; }
      void visit(MeshGeometry &) { return; }
      void visit(Texture2D &) { return; }
      void visit(TextLabel2D &l) { l.resetTexture(); }
      void visit(TextLabel3D &l) { l.resetTexture(); }
      void visit(LineStripGeometry &) { return; }
    } labelResetter;

    m_scene.rootNode().accept(labelResetter);

    delete m_textRenderStrategy;
    m_textRenderStrategy = tren;
  }
}

void GLRenderer::applyProjection()
{
  float distance = m_camera.distance(m_center);
  if (m_camera.projectionType() == Perspective) {
    m_camera.calculatePerspective(40.0f,
                                  std::max(2.0f, distance - m_radius),
                                  distance + m_radius);
  }
  else {
    // Renders the orthographic projection of the molecule
    const double halfHeight = m_radius;
    const double halfWidth = halfHeight * m_camera.width() / m_camera.height();
    m_camera.calculateOrthographic(-halfWidth, halfWidth,
                                   -halfHeight, halfHeight,
                                   std::max(2.0f, distance - m_radius),
                                   distance + m_radius);
  }
  m_overlayCamera.calculateOrthographic(
        0.f, static_cast<float>(m_overlayCamera.width()),
        0.f, static_cast<float>(m_overlayCamera.height()),
        -1.f, 1.f);
}

std::multimap<float, Identifier>
GLRenderer::hits(const GroupNode *group, const Vector3f &rayOrigin,
                 const Vector3f &rayEnd, const Vector3f &rayDirection) const
{
  std::multimap<float, Identifier> result;
  if (!group)
    return result;

  for (std::vector<Node *>::const_iterator it = group->children().begin();
       it != group->children().end(); ++it) {
    std::multimap<float, Identifier> loopHits;
    const Node *itNode = *it;
    const GroupNode *childGroup = dynamic_cast<const GroupNode *>(itNode);
    if (childGroup) {
      loopHits = hits(childGroup, rayOrigin, rayEnd, rayDirection);
      result.insert(loopHits.begin(), loopHits.end());
      continue;
    }
    const GeometryNode *childGeometry = (*it)->cast<GeometryNode>();
    if (childGeometry) {
      loopHits = hits(childGeometry, rayOrigin, rayEnd, rayDirection);
      result.insert(loopHits.begin(), loopHits.end());
      continue;
    }
  }
  return result;
}

std::multimap<float, Identifier>
GLRenderer::hits(const GeometryNode *geometry, const Vector3f &rayOrigin,
                 const Vector3f &rayEnd, const Vector3f &rayDirection) const
{
  if (!geometry)
    return std::multimap<float, Identifier>();
  return geometry->hits(rayOrigin, rayEnd, rayDirection);
}

std::multimap<float, Identifier> GLRenderer::hits(int x, int y) const
{
  // Our ray:
  const Vector3f origin(m_camera.unProject(Vector3f(static_cast<float>(x),
                                                    static_cast<float>(y),
                                                    0.f)));
  const Vector3f end(m_camera.unProject(Vector3f(static_cast<float>(x),
                                                 static_cast<float>(y), 1.f)));
  const Vector3f direction((end - origin).normalized());

  return hits(&m_scene.rootNode(), origin, end, direction);
}

} // End Rendering namespace
} // End Avogadro namespace
<|endoftext|>


<commit_before>/*-------------------------------
PASA LA CALCULADORA
Autores:
Jaime Sevilla Molina
Victor Gonzalez
Fecha
2014/11
Version: 2.0
---------------------------------*/

//BIBLIOTECAS
#include <iostream>
#include <cstdlib>
#include <string>
#include <ctime>
#include <fstream>
#include <iomanip>

using namespace std;

//TIPOS PROPIOS
typedef enum tJugador
{
	Nadie,
	Jugador,
	Automata
};

//FUNCIONES
//FUNCIONES DE JUEGO

string saludar ();

//Dependiendo de quien gane, la despedida sera distinta
void despedirse (tJugador ganador, string nombre);

//Muestra un menu que permite al jugador jugar, salir, o ver las reglas del juego
int menu();

//Muestra las instrucciones del juego, siempre que su archivo no contenga errores
bool acerca();

//Actualiza las estadisticas
bool actualizar_stats(tJugador ganador);

//Muestra las estadisticas
bool stats();

//Anota el numero de partidas ganadas y perdidas del jugador
bool stats(int ganadas, int perdidas);

//Conduce el desarrollo del juego y devuelve el ganador.
//Si se abandona, devuelve Nadie.
tJugador pasaCalculadora();

//Decide aleatoriamente quien empieza.
tJugador quienEmpieza();

//Devuelve true si nuevo esta en la misma fila que ultimo
bool mismaFila(int ultimo, int nuevo);

//Devuelve true si nuevo esta en la misma columna que ultimo
bool mismaColumna(int ultimo, int nuevo);

//Devuelve true si nuevo cumple las reglas del juego con respecto a ultimo
//Si ultimo == 0, este es el primer digito de la partida, y devuelve true
bool digitoValido(int ultimo, int nuevo);

//FUNCIONES DE IA NIVEL 1
//Devuelve un digito del 1 al 9
int digitoAleatorio();

//Devuelve un digito que cumpla las reglas del juego con respecto a ultimo.
int digitoAutomata(int ultimo);

//FUNCIONES DE JUGADOR
//Pide un digito al jugador. Solo devolvera un valor valido (entre 0 y 9).
//Para un valor no valido, mostrara un error.
int digitoPersona();

//Pide un digito al jugador mostrando el teclado. Solo devolvera un valor
//que cumpla las reglas del juego o 0. Para un valor no valido, mostrara un error.
int digitoPersona(int ultimo);

//Determina si el numero de la calculadora se muestra o no, en funcion de si es valido
char mNumero(int ultimo, int n);

//Muestra los botones de la calculadora (solo los que se pueden pulsar en cada turno)
void mostrarCalculadora(int ultimo);

/* Las funciones a continuacion se implementaran en un futuro
//FUNCIONES DE INFORME
//Actualiza el archivo informePC.txt con los tres argumentos. En caso de no encontrar
//el archivo, lo crea y devuelve false; en otro caso devuelve true.
bool actInforme(int jugadas, int ganadas, int abandonos);

//FUNCIONES DE DIFICULTAD AVANZADA
int botDificil(int ultimo);

-----------------------------------------------------------------------------------*/

int main()
{
	tJugador ganador;
	int opcion;

	string nombre = saludar();
	//Bucle Menu
	do
	{
		opcion = menu();
		if(opcion == 1){
			ganador = pasaCalculadora();
			despedirse(ganador, nombre);
		}
		else if(opcion == 2) acerca();

	}
	while(opcion != 0);

	cout << "Hasta la proxima " << nombre << "(pulsa enter)";
	cin;

	return 0;
}

//Saluda al jugador y le pregunta su nombre
string saludar()
{
	string nombre;
	cout << "Bienvenido a Pasa la calculadora!" << endl;
	cout << "Como te llamas? ";
	cin >> nombre;
	cout << "Hola " << nombre << endl << endl;
	return nombre;
}

//Se despide del jugador, la despedida varia segun gane el jugador, el automata o ninguno de ellos (el jugador abandone)
void despedirse(tJugador ganador, string nombre)
{
	int ganadas = 0, perdidas = 0;
	if (ganador == Nadie){
		cout << "Abandonas, " << nombre << "? Ohhh..." << endl << endl;
	}
	else if (ganador == Jugador){
		cout << "Enhorabuena " << nombre << ", has ganado!" << endl << endl;
	}
	else /*if (ganador == Automata)*/{
		cout << "Lo siento " << nombre << ", he ganado" << endl << endl;
	}
}

//Proporciona al jugador la posibilidad de jugar, ver las instrucciones del juego o salir.
int menu()
{
	int seleccionar = -1; //Error flag
	cout << "1 - Jugar" << endl;
	cout << "2 - Acerca de" << endl;
	cout << "0 - Salir" << endl;

	do
	{
		cin.sync(); //Por si quedan datos basura en el buffer
		cin >> seleccionar;

		if(cin.fail())
		{
			cout << "Error! Introduce un digito" << endl;
			cin.clear();
		}

		else if (seleccionar < 0 || seleccionar > 2)
		{
			cout << "Error! Introduce un digito entre 0 y 2" << endl;
			seleccionar = -1;
		}

	}
	while (seleccionar == -1);

	return seleccionar;
}

//Muestra el archivo "acerca.txt" siempre que este no contenga errores
bool acerca()
{
	bool ok;
	ifstream acerca;
	char c;

	acerca.open("acerca.txt");

	if(acerca.is_open())
	{
		acerca.get(c); //Lee el primer caracter

		while(!acerca.fail()) //Mientras la lectura no falle
		{
			cout << c;
			acerca.get(c); //Lee el siguiente caracter
		}

		ok = true;
		acerca.close();

	}
	else
	{
		ok = false;
		cout << "Error, el archivo 'acerca.txt' no existe" << endl;
	}

	return ok;
}

//Actualiza las estadisticas
bool actualizar_stats(tJugador ganador)
{
	bool ok;
	int ganadas, perdidas, abandonadas;
	ifstream stats;
	ofstream actualizar;

	stats.open("stats.txt");
	if(stats.is_open())
	{
		stats >> ganadas;
		stats >> perdidas;
		stats >> abandonadas;

		ok = true;
	}
	else
	{
		ganadas = 0;
		perdidas = 0;
		abandonadas = 0;

		ok = false;
	}

	if(ganador == Jugador) ganadas += 1;
	else if(ganador == Automata) perdidas += 1;
	else if(ganador == Nadie) abandonadas += 1;

	stats.close();

	actualizar.open("stats.txt")

	actualizar << ganadas;
	actualizar << perdidas;
	actualizar << abandonadas;

	actualizar.close();
	return ok;
}

//Muestra las estadisticas
void stats()
{
	actualizar_stats(ganador);
	ifstream stats;

	stats.open("stats.txt")

	stats << "Partidas jugadas: " << (ganadas+perdidas+abandonadas) << endl;
	stats << "	Partidas ganadas: " << ganadas << endl;
	stats << "	Partidas perdidas: " << perdidas << endl;
	stats << "	Partidas abandonadas: " << abandonadas << endl;

	stats.close();
}

//Conduce el desarrollo del juego y devuelve el ganador.
//Si se abandona, devuelve Nadie.
tJugador pasaCalculadora()
{
	//Variables
	tJugador turno;
	int total = 0, ultimoDigito = 0;
	const int META=31;
		//Inicializar partida
	srand(time(NULL));//Semilla
	turno = quienEmpieza();

	//Bucle de juego
	do
	{
		//Turno jugador
		if (turno == Jugador)
		{
			ultimoDigito = digitoPersona(ultimoDigito);
			turno = Automata;
		}
		//Turno bot
		else /*if (turno == Automata)*/
		{
			ultimoDigito = digitoAutomata(ultimoDigito);
			turno = Jugador;
		}
		total += ultimoDigito;
		cout << "Total = " << total << endl;
	}
	while ((total < META) && (ultimoDigito != 0));

	if (ultimoDigito == 0) turno = Nadie;
	//Si el jugador abandona, no gana nadie

	return turno;
}

//Decide aleatoriamente quien empieza la partida, si el automata o el jugador
tJugador quienEmpieza()
{
	if (rand() % 2)
	{
		cout << "Tu empiezas" << endl;
		return Jugador;
	}
	else
	{
		cout << "Empiezo yo" << endl;
		return Automata;
	}
}

//Define que numeros se encuentran en la misma fila que el ultimo pulsado
bool mismaFila(int ultimo, int nuevo)
{
	int filaUltimo, filaNuevo;
	filaUltimo = ((ultimo - 1)/3);
	filaNuevo = ((nuevo - 1)/3);
	return (filaUltimo) == (filaNuevo);
}

//Define que numeros se encuentran en la misma columna que el ultimo
bool mismaColumna(int ultimo, int nuevo)
{
	int columnaUltimo, columnaNuevo;
	columnaUltimo = (ultimo % 3);
	columnaNuevo = (nuevo % 3);
	return columnaUltimo == columnaNuevo;
}

//Determina que digitos se pueden pulsar en funcion de las reglas del juego
bool digitoValido(int ultimo, int nuevo)  //hay un bug
{
	if (ultimo == 0) return true;//Si es el primer turno, todos los numeros valen

	return ((mismaFila(ultimo, nuevo))||(mismaColumna(ultimo, nuevo)))&&(ultimo!=nuevo);
}

//Genera un digito aleatorio
int digitoAleatorio()
{
	return (rand() % 9) + 1;
}

//Devuelve un digito que cumpla las reglas del juego con respecto a ultimo.
int digitoAutomata(int ultimo)
{
	int digito;

	do
	{
	digito = digitoAleatorio();
	}
	while (!digitoValido(ultimo, digito));

	cout << "Elijo el numero " << digito << endl;

	return digito;
}

//Pide un digito al jugador. Solo devolvera un valor valido (entre 0 y 9).
//Para un valor no valido, mostrara un error.
int digitoPersona()
{
	int digito = -1;

	do
	{
		cin.sync(); //Por si quedan datos basura en el buffer
		cin >> digito;

		if (cin.fail())
		{
			cout << "Error! Introduce un digito" << endl;
			cin.clear();
		}

		else if (digito < 0 || digito > 9)
		{
		cout << "Error! Introduce un digito entre 0 y 9" << endl;
		digito = -1;
		}

	}
	while (digito == -1);

	return digito;
}

//Pide un digito al jugador mostrando el teclado. Solo devolvera un valor
//que cumpla las reglas del juego o 0. Para un valor no valido, mostrara un error.
int digitoPersona(int ultimo)
{
	int digito = -1; //-1 es mi error flag

	mostrarCalculadora(ultimo);

	do
	{
		digito = digitoPersona();
		if (!digitoValido(ultimo, digito))
		{
			cout << "Error! El digito debe estar en la misma fila y columna que el ultimo" << endl;
			digito = -1;
		}
	}
	while (digito == -1);

	cout << "Has elegido el " << digito << endl;

	return digito;
}

//Determina si el numero de la calculadora se muestra o no, en funcion de si es valido
char mNumero(int ultimo, int n)
{
	if(digitoValido(ultimo, n))
	{
		return char (n+int('0'));

	}
	else
	{
		return ' ';
	}
}

//Muestra los botones de la calculadora (solo los que se pueden pulsar en cada turno)
void mostrarCalculadora(int ultimo)
{
	for (int i = 7; i<10; i++)
	{
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
	for (int i = 4; i<7; i++)
	{
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
	for (int i = 1; i<4; i++)
	{
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
}
<commit_msg>corregida stats(), y llamada actualizar()<commit_after>/*-------------------------------
PASA LA CALCULADORA
Autores:
Jaime Sevilla Molina
Victor Gonzalez
Fecha
2014/11
Version: 2.0
---------------------------------*/

//BIBLIOTECAS
#include <iostream>
#include <cstdlib>
#include <string>
#include <ctime>
#include <fstream>
#include <iomanip>

using namespace std;

//TIPOS PROPIOS
typedef enum tJugador
{
	Nadie,
	Jugador,
	Automata
};

//FUNCIONES
//FUNCIONES DE JUEGO

string saludar ();

//Dependiendo de quien gane, la despedida sera distinta
void despedirse (tJugador ganador, string nombre);

//Muestra un menu que permite al jugador jugar, salir, o ver las reglas del juego
int menu();

//Muestra las instrucciones del juego, siempre que su archivo no contenga errores
bool acerca();

//Actualiza las estadisticas
bool actualizar_stats(tJugador ganador);

//Muestra las estadisticas
bool stats();

//Anota el numero de partidas ganadas y perdidas del jugador
bool stats(int ganadas, int perdidas);

//Conduce el desarrollo del juego y devuelve el ganador.
//Si se abandona, devuelve Nadie.
tJugador pasaCalculadora();

//Decide aleatoriamente quien empieza.
tJugador quienEmpieza();

//Devuelve true si nuevo esta en la misma fila que ultimo
bool mismaFila(int ultimo, int nuevo);

//Devuelve true si nuevo esta en la misma columna que ultimo
bool mismaColumna(int ultimo, int nuevo);

//Devuelve true si nuevo cumple las reglas del juego con respecto a ultimo
//Si ultimo == 0, este es el primer digito de la partida, y devuelve true
bool digitoValido(int ultimo, int nuevo);

//FUNCIONES DE IA NIVEL 1
//Devuelve un digito del 1 al 9
int digitoAleatorio();

//Devuelve un digito que cumpla las reglas del juego con respecto a ultimo.
int digitoAutomata(int ultimo);

//FUNCIONES DE JUGADOR
//Pide un digito al jugador. Solo devolvera un valor valido (entre 0 y 9).
//Para un valor no valido, mostrara un error.
int digitoPersona();

//Pide un digito al jugador mostrando el teclado. Solo devolvera un valor
//que cumpla las reglas del juego o 0. Para un valor no valido, mostrara un error.
int digitoPersona(int ultimo);

//Determina si el numero de la calculadora se muestra o no, en funcion de si es valido
char mNumero(int ultimo, int n);

//Muestra los botones de la calculadora (solo los que se pueden pulsar en cada turno)
void mostrarCalculadora(int ultimo);

/* Las funciones a continuacion se implementaran en un futuro
//FUNCIONES DE INFORME
//Actualiza el archivo informePC.txt con los tres argumentos. En caso de no encontrar
//el archivo, lo crea y devuelve false; en otro caso devuelve true.
bool actInforme(int jugadas, int ganadas, int abandonos);

//FUNCIONES DE DIFICULTAD AVANZADA
int botDificil(int ultimo);

-----------------------------------------------------------------------------------*/

int main()
{
	tJugador ganador;
	int opcion;

	string nombre = saludar();
	//Bucle Menu
	do
	{
		opcion = menu();
		if(opcion == 1){
			ganador = pasaCalculadora();
			actualizar_stats(ganador);
			despedirse(ganador, nombre);
		}
		else if(opcion == 2) acerca();

	}
	while(opcion != 0);

	cout << "Hasta la proxima " << nombre << "(pulsa enter)";
	cin;

	return 0;
}

//Saluda al jugador y le pregunta su nombre
string saludar()
{
	string nombre;
	cout << "Bienvenido a Pasa la calculadora!" << endl;
	cout << "Como te llamas? ";
	cin >> nombre;
	cout << "Hola " << nombre << endl << endl;
	return nombre;
}

//Se despide del jugador, la despedida varia segun gane el jugador, el automata o ninguno de ellos (el jugador abandone)
void despedirse(tJugador ganador, string nombre)
{
	int ganadas = 0, perdidas = 0;
	if (ganador == Nadie){
		cout << "Abandonas, " << nombre << "? Ohhh..." << endl << endl;
	}
	else if (ganador == Jugador){
		cout << "Enhorabuena " << nombre << ", has ganado!" << endl << endl;
	}
	else /*if (ganador == Automata)*/{
		cout << "Lo siento " << nombre << ", he ganado" << endl << endl;
	}
}

//Proporciona al jugador la posibilidad de jugar, ver las instrucciones del juego o salir.
int menu()
{
	int seleccionar = -1; //Error flag
	cout << "1 - Jugar" << endl;
	cout << "2 - Acerca de" << endl;
	cout << "0 - Salir" << endl;

	do
	{
		cin.sync(); //Por si quedan datos basura en el buffer
		cin >> seleccionar;

		if(cin.fail())
		{
			cout << "Error! Introduce un digito" << endl;
			cin.clear();
		}

		else if (seleccionar < 0 || seleccionar > 2)
		{
			cout << "Error! Introduce un digito entre 0 y 2" << endl;
			seleccionar = -1;
		}

	}
	while (seleccionar == -1);

	return seleccionar;
}

//Muestra el archivo "acerca.txt" siempre que este no contenga errores
bool acerca()
{
	bool ok;
	ifstream acerca;
	char c;

	acerca.open("acerca.txt");

	if(acerca.is_open())
	{
		acerca.get(c); //Lee el primer caracter

		while(!acerca.fail()) //Mientras la lectura no falle
		{
			cout << c;
			acerca.get(c); //Lee el siguiente caracter
		}

		ok = true;
		acerca.close();

	}
	else
	{
		ok = false;
		cout << "Error, el archivo 'acerca.txt' no existe" << endl;
	}

	return ok;
}

//Actualiza las estadisticas
bool actualizar_stats(tJugador ganador)
{
	bool ok;
	int ganadas, perdidas, abandonadas;
	ifstream stats;
	ofstream actualizar;

	stats.open("stats.txt");
	if(stats.is_open())
	{
		stats >> ganadas;
		stats >> perdidas;
		stats >> abandonadas;

		ok = true;
	}
	else
	{
		ganadas = 0;
		perdidas = 0;
		abandonadas = 0;

		ok = false;
	}

	if(ganador == Jugador) ganadas += 1;
	else if(ganador == Automata) perdidas += 1;
	else if(ganador == Nadie) abandonadas += 1;

	stats.close();

	actualizar.open("stats.txt")

	actualizar << ganadas;
	actualizar << perdidas;
	actualizar << abandonadas;

	actualizar.close();
	return ok;
}

//Muestra las estadisticas
void stats()
{
	ifstream stats;

	stats.open("stats.txt")

	cout << "Partidas jugadas: " << (ganadas+perdidas+abandonadas) << endl;
	cout << "	Partidas ganadas: " << ganadas << endl;
	cout << "	Partidas perdidas: " << perdidas << endl;
	cout << "	Partidas abandonadas: " << abandonadas << endl;

	stats.close();
}

//Conduce el desarrollo del juego y devuelve el ganador.
//Si se abandona, devuelve Nadie.
tJugador pasaCalculadora()
{
	//Variables
	tJugador turno;
	int total = 0, ultimoDigito = 0;
	const int META=31;
		//Inicializar partida
	srand(time(NULL));//Semilla
	turno = quienEmpieza();

	//Bucle de juego
	do
	{
		//Turno jugador
		if (turno == Jugador)
		{
			ultimoDigito = digitoPersona(ultimoDigito);
			turno = Automata;
		}
		//Turno bot
		else /*if (turno == Automata)*/
		{
			ultimoDigito = digitoAutomata(ultimoDigito);
			turno = Jugador;
		}
		total += ultimoDigito;
		cout << "Total = " << total << endl;
	}
	while ((total < META) && (ultimoDigito != 0));

	if (ultimoDigito == 0) turno = Nadie;
	//Si el jugador abandona, no gana nadie

	return turno;
}

//Decide aleatoriamente quien empieza la partida, si el automata o el jugador
tJugador quienEmpieza()
{
	if (rand() % 2)
	{
		cout << "Tu empiezas" << endl;
		return Jugador;
	}
	else
	{
		cout << "Empiezo yo" << endl;
		return Automata;
	}
}

//Define que numeros se encuentran en la misma fila que el ultimo pulsado
bool mismaFila(int ultimo, int nuevo)
{
	int filaUltimo, filaNuevo;
	filaUltimo = ((ultimo - 1)/3);
	filaNuevo = ((nuevo - 1)/3);
	return (filaUltimo) == (filaNuevo);
}

//Define que numeros se encuentran en la misma columna que el ultimo
bool mismaColumna(int ultimo, int nuevo)
{
	int columnaUltimo, columnaNuevo;
	columnaUltimo = (ultimo % 3);
	columnaNuevo = (nuevo % 3);
	return columnaUltimo == columnaNuevo;
}

//Determina que digitos se pueden pulsar en funcion de las reglas del juego
bool digitoValido(int ultimo, int nuevo)  //hay un bug
{
	if (ultimo == 0) return true;//Si es el primer turno, todos los numeros valen

	return ((mismaFila(ultimo, nuevo))||(mismaColumna(ultimo, nuevo)))&&(ultimo!=nuevo);
}

//Genera un digito aleatorio
int digitoAleatorio()
{
	return (rand() % 9) + 1;
}

//Devuelve un digito que cumpla las reglas del juego con respecto a ultimo.
int digitoAutomata(int ultimo)
{
	int digito;

	do
	{
	digito = digitoAleatorio();
	}
	while (!digitoValido(ultimo, digito));

	cout << "Elijo el numero " << digito << endl;

	return digito;
}

//Pide un digito al jugador. Solo devolvera un valor valido (entre 0 y 9).
//Para un valor no valido, mostrara un error.
int digitoPersona()
{
	int digito = -1;

	do
	{
		cin.sync(); //Por si quedan datos basura en el buffer
		cin >> digito;

		if (cin.fail())
		{
			cout << "Error! Introduce un digito" << endl;
			cin.clear();
		}

		else if (digito < 0 || digito > 9)
		{
		cout << "Error! Introduce un digito entre 0 y 9" << endl;
		digito = -1;
		}

	}
	while (digito == -1);

	return digito;
}

//Pide un digito al jugador mostrando el teclado. Solo devolvera un valor
//que cumpla las reglas del juego o 0. Para un valor no valido, mostrara un error.
int digitoPersona(int ultimo)
{
	int digito = -1; //-1 es mi error flag

	mostrarCalculadora(ultimo);

	do
	{
		digito = digitoPersona();
		if (!digitoValido(ultimo, digito))
		{
			cout << "Error! El digito debe estar en la misma fila y columna que el ultimo" << endl;
			digito = -1;
		}
	}
	while (digito == -1);

	cout << "Has elegido el " << digito << endl;

	return digito;
}

//Determina si el numero de la calculadora se muestra o no, en funcion de si es valido
char mNumero(int ultimo, int n)
{
	if(digitoValido(ultimo, n))
	{
		return char (n+int('0'));

	}
	else
	{
		return ' ';
	}
}

//Muestra los botones de la calculadora (solo los que se pueden pulsar en cada turno)
void mostrarCalculadora(int ultimo)
{
	for (int i = 7; i<10; i++)
	{
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
	for (int i = 4; i<7; i++)
	{
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
	for (int i = 1; i<4; i++)
	{
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Luke San Antonio
 * All rights reserved.
 */
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <vector>

#include "common/log.h"

#include "gfx/gl/program.h"
#include "gfx/gl/driver.h"

#include "gfx/scene.h"

#include "texture.h"
#include "mesh.h"

#include "glad/glad.h"
#include "glfw3.h"

#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#include "uv.h"

#define CATCH_CONFIG_RUNNER
#include "catch/catch.hpp"

struct Command_Options
{
  bool test = false;
};

Command_Options parse_command_line(int argc, char** argv)
{
  Command_Options opt;
  for(int i = 0; i < argc; ++i)
  {
    auto option = argv[i];
    if(strcmp(option, "--test") == 0)
    {
      opt.test = true;
    }
  }
  return opt;
}

int main(int argc, char** argv)
{
  using namespace survive;

  uv_chdir("assets/");

  // Initialize logger.
  Scoped_Log_Init log_init_raii_lock{};

  // Parse command line arguments.
  auto options = parse_command_line(argc - 1, argv+1);

  // Should be run the testing whatchamacallit?
  if(options.test)
  {
    int result = Catch::Session().run(1, argv);
    if(result)
    {
      return EXIT_FAILURE;
    }
  }

  // Init glfw.
  if(!glfwInit())
    return EXIT_FAILURE;

  auto window = glfwCreateWindow(1000, 1000, "Hello World", NULL, NULL);
  if(!window)
  {
    glfwTerminate();
    return EXIT_FAILURE;
  }

  // Init context + load gl functions.
  glfwMakeContextCurrent(window);
  gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);

  // Log glfw version.
  log_i("Initialized GLFW %", glfwGetVersionString());

  int maj = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
  int min = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
  int rev = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);

  // Log GL profile.
  log_i("OpenGL core profile %.%.%", maj, min, rev);

  // Make an OpenGL driver.
  auto driver = gfx::gl::Driver{};

  // Load a shader program.
#if 0
  auto shader_program = gfx::Program::from_files("shader/diffuse/vertex",
                                                 "shader/diffuse/fragment");
#endif

  // Load the scene data for an isometric view
  auto scene_data = gfx::make_isometric_scene();

  // auto scene = load_scene("scene/default.json");
  // prepare_scene(driver);

  // Prepare a mesh for rendering.
  auto mesh = driver.prepare_mesh(Mesh::from_file("obj/plane.obj"));
  auto tex =
        driver.prepare_texture(Texture::from_png_file("tex/cracked_soil.png"));

  int fps = 0;
  int time = glfwGetTime();

  // Set up some pre-rendering state.
  glClearColor(0.509, .694, .737, 1.0);
  glClearDepth(1);

  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

  // Use our shader.
#if 0
  shader_program.use();
#endif

#if 0
  auto tex_loc = shader_program.get_uniform_location("tex");
  shader_program.set_uniform_int(tex_loc, 0);
#endif
  tex->bind(0);

#if 0
  auto mvp_loc = shader_program.get_uniform_location("mvp");
#endif

  float deg = -5;
  while(!glfwWindowShouldClose(window))
  {
    ++fps;

    // Create our matrix.

    //glm::mat4 view = glm::lookAt(glm::vec3(0, 10, 0), glm::vec3(0, 0, 0),
                                 //glm::vec3(0, 0, 1));
    //glm::mat4 perspective = glm::frustum(-1, 1, -1, 1, -1, 1);
    //glm::mat4 perspective = glm::ortho(-1, 1, -1, 1, -1, 1);
    glm::mat4 view(1.0);
    view = glm::lookAt(glm::vec3(0, 0, 15), glm::vec3(0, 0, 0),
                       glm::vec3(0, 1, 0));
    glm::mat4 perspective(1.0);
    perspective = glm::perspective(45., 1., .01, 30.);

    auto model = glm::mat4(1.0);

    // rotate 90 degrees ccw
    //model = glm::translate(model, glm::vec3(0, cam_height, 0));
    model = glm::rotate(model, -3.14159f / 2.0f, glm::vec3(0, 1, 0));
    model = glm::rotate(model, deg, glm::vec3(0, 1, 0));
    //model = glm::translate(model, glm::vec3(0, 0, 0));
    //model = glm::translate(model, glm::vec3(0, 0, 7));
    model = glm::scale(model, glm::vec3(5));

    deg += .001;

    glm::mat4 mvp = perspective * view * model;

    // Set the matrix in the program.
    // TODO this seems bad, change this.
#if 0
    shader_program.set_uniform_mat4(mvp_loc, mvp);
#endif

    // Clear the screen and render.
    driver.clear();
    mesh->render();

    // Show it on screen.
    glfwSwapBuffers(window);
    glfwPollEvents();

    if(int(glfwGetTime()) != time)
    {
      time = glfwGetTime();
      log_d("fps: %", fps);
      fps = 0;
    }
  }

  glfwTerminate();
  return 0;
}

#if 0
int main()
{
  using namespace survive;

  auto driver = gfx::gl::Driver{"OpenGL 4.5"};
  auto scene_data = gfx::make_isometric_scene(factory, ...);

  auto scene_root = load_scene("scene/main.json");
  prepare_scene(factory, scene_root);

  while(window)
  {
    driver.clear();

    scene_root.render(scene_data);
    // Expanded view of ^
    {
      apply_model();
      material->use();
      mesh->render();

      for(child : children)
      {
        child.render(scene_data);
      }
    }

    gfx::swap_buffers();
  }
}
#endif
<commit_msg>The main function is severly messy but it loads a scene and works!<commit_after>/*
 * Copyright (C) 2014 Luke San Antonio
 * All rights reserved.
 */
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <vector>
#include <thread>

#include "common/log.h"

#include "gfx/gl/program.h"
#include "gfx/gl/driver.h"
#include "gfx/gl/diffuse_material.h"
#include "gfx/gl/program_cache.h"

#include "gfx/scene.h"
#include "scene_node.h"

#include "texture.h"
#include "mesh.h"

#include "glad/glad.h"
#include "glfw3.h"

#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#include "uv.h"

#define CATCH_CONFIG_RUNNER
#include "catch/catch.hpp"

struct Command_Options
{
  bool test = false;
};

Command_Options parse_command_line(int argc, char** argv)
{
  Command_Options opt;
  for(int i = 0; i < argc; ++i)
  {
    auto option = argv[i];
    if(strcmp(option, "--test") == 0)
    {
      opt.test = true;
    }
  }
  return opt;
}

int main(int argc, char** argv)
{
  using namespace survive;

  set_log_level(Log_Severity::Debug);

  uv_chdir("assets/");

  // Initialize logger.
  Scoped_Log_Init log_init_raii_lock{};

  // Parse command line arguments.
  auto options = parse_command_line(argc - 1, argv+1);

  // Should be run the testing whatchamacallit?
  if(options.test)
  {
    int result = Catch::Session().run(1, argv);
    if(result)
    {
      return EXIT_FAILURE;
    }
  }

  // Init glfw.
  if(!glfwInit())
    return EXIT_FAILURE;

  auto window = glfwCreateWindow(1000, 1000, "Hello World", NULL, NULL);
  if(!window)
  {
    glfwTerminate();
    return EXIT_FAILURE;
  }

  // Init context + load gl functions.
  glfwMakeContextCurrent(window);
  gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);

  // Log glfw version.
  log_i("Initialized GLFW %", glfwGetVersionString());

  int maj = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
  int min = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
  int rev = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);

  // Log GL profile.
  log_i("OpenGL core profile %.%.%", maj, min, rev);

  // Make an OpenGL driver.
  auto driver = gfx::gl::Driver{};

  // Load a shader program.
  //auto shader_program = gfx::gl::Program::from_files("shader/diffuse/vertex",
                                                 //"shader/diffuse/fragment");

  //auto material = std::make_unique<gfx::gl::Diffuse_Material>();
  //auto shader = gfx::gl::load_program("shader/diffuse/decl.json");
  //auto sampler_loc = shader->get_uniform_location("tex");
  //auto model_loc = shader->get_uniform_location("model");
  //auto proj_loc = shader->get_uniform_location("proj");
  //auto view_loc = shader->get_uniform_location("view");

  //auto tex =
        //driver.prepare_texture(Texture::from_png_file("tex/cracked_soil.png"));
  //material->diffuse_color(Color{0xff, 0x00, 0x00});
  //material->texture(std::move(tex));
  //tex->bind(0);
  //glUniform1i(sampler_loc, 0);

  // Load the scene data for an isometric view
  auto scene_data = gfx::make_isometric_scene();
  //scene_data.register_observer(*material);

  glm::mat4 view(1.0);
  view = glm::lookAt(glm::vec3(0, 0, 15), glm::vec3(0, 0, 0),
                     glm::vec3(0, 1, 0));
  //scene_data.view_matrix(view);
  glm::mat4 perspective(1.0);
  perspective = glm::perspective(45., 1., .01, 30.);
  //scene_data.projection_matrix(perspective);

  //material->set_view(view);
  //material->set_projection(perspective);

  auto scene = load_scene("scene/default.json", driver);
  scene_data.register_observer(*scene.obj.material);
  //prepare_scene(driver);

  // Prepare a mesh for rendering.
  //auto mesh = driver.prepare_mesh(Mesh::from_file("obj/plane.obj"));

  int fps = 0;
  int time = glfwGetTime();

  // Set up some pre-rendering state.
  glClearColor(0.509, .694, .737, 1.0);
  glClearDepth(1);

  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

  // Swap the back buffer to front buffer, first?
  glfwSwapBuffers(window);

  // Use our shader.

  float deg = -5;

  //shader->use();

  //material->use(model);
  //glUniformMatrix4fv(proj_loc, 1, GL_FALSE, &perspective[0][0]);
  //glUniformMatrix4fv(view_loc, 1, GL_FALSE, &view[0][0]);

  //glUseProgram(0);

  bool done = false;
  while(!glfwWindowShouldClose(window) && !done)
  {
    //done = true;
    ++fps;

    //shader->use();
    // Create our matrix.

    //glm::mat4 view = glm::lookAt(glm::vec3(0, 10, 0), glm::vec3(0, 0, 0),
                                 //glm::vec3(0, 0, 1));
    //glm::mat4 perspective = glm::frustum(-1, 1, -1, 1, -1, 1);
    //glm::mat4 perspective = glm::ortho(-1, 1, -1, 1, -1, 1);

    // rotate 90 degrees ccw
    auto model = glm::mat4(1.0);
    //model = glm::translate(model, glm::vec3(0, cam_height, 0));
    model = glm::rotate(model, -3.14159f / 2.0f, glm::vec3(0, 1, 0));
    model = glm::rotate(model, deg, glm::vec3(0, 1, 0));
    //model = glm::translate(model, glm::vec3(0, 0, 0));
    //model = glm::translate(model, glm::vec3(0, 0, 7));
    model = glm::scale(model, glm::vec3(5));
    //glUniformMatrix4fv(model_loc, 1, GL_FALSE, &model[0][0]);

    deg += .001;
    scene.model = model;

    // Set the matrix in the program.
    // TODO this seems bad, change this.

    // Clear the screen and render.
    driver.clear();
    scene.render();

    // Show it on screen.
    glfwSwapBuffers(window);
    glfwPollEvents();

    if(int(glfwGetTime()) != time)
    {
      time = glfwGetTime();
      log_d("fps: %", fps);
      fps = 0;
    }
  }

  glfwTerminate();
  return 0;
}

#if 0
int main()
{
  using namespace survive;

  auto driver = gfx::gl::Driver{"OpenGL 4.5"};
  auto scene_data = gfx::make_isometric_scene(factory, ...);

  auto scene_root = load_scene("scene/main.json");
  prepare_scene(factory, scene_root);

  while(window)
  {
    driver.clear();

    scene_root.render(scene_data);
    // Expanded view of ^
    {
      apply_model();
      material->use();
      mesh->render();

      for(child : children)
      {
        child.render(scene_data);
      }
    }

    gfx::swap_buffers();
  }
}
#endif
<|endoftext|>


<commit_before>#if defined(_MSC_VER)
#define _CRTDBG_MAP_ALLOC
#define _CRT_SECURE_NO_WARNINGS
#include <crtdbg.h>
#else
#include <fenv.h>
#endif

#include "CoolPropLib.h"
#include "CoolProp.h"
#include "HumidAirProp.h"
#include "DataStructures.h"
#include "Exceptions.h"
#include "float.h"

#include <string.h>

// In Microsoft Excel, they seem to check the FPU exception bits and error out because of it.
// By calling the _clearfp(), we can reset these bits, and not get the error
// See also http://stackoverflow.com/questions/11685441/floating-point-error-when-calling-dll-function-from-vba/27336496#27336496
// See also http://stackoverflow.com/questions/16849009/in-linux-do-there-exist-functions-similar-to-clearfp-and-statusfp for linux and OSX
void reset_fpu()
{
    #if defined(_MSC_VER)
        _clearfp(); // For MSVC, clear the floating point error flags
    #else
        feclearexcept(FE_ALL_EXCEPT);
    #endif
}
double convert_from_kSI_to_SI(long iInput, double value)
{
    if (get_debug_level() > 8){
        std::cout << format("%s:%d: convert_from_kSI_to_SI(i=%d,value=%g)\n",__FILE__,__LINE__,iInput,value).c_str();
    }

    switch (iInput)
    {
    case CoolProp::iP:
    case CoolProp::iCpmass:
    case CoolProp::iCp0mass:
    case CoolProp::iSmass:
    case CoolProp::iGmass:
    case CoolProp::iCvmass:
    case CoolProp::iHmass:
    case CoolProp::iUmass:
    case CoolProp::iconductivity:
        return value*1000.0;
    case CoolProp::iDmass:
    case CoolProp::ispeed_sound:
    case CoolProp::iQ:
    case CoolProp::iviscosity:
    case CoolProp::iT:
    case CoolProp::iPrandtl:
    case CoolProp::isurface_tension:
        return value;
    default:
        throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_kSI_to_SI",iInput).c_str());
        break;
    }
    return _HUGE;
}

double convert_from_SI_to_kSI(long iInput, double value)
{
    if (get_debug_level() > 8){
        std::cout << format("%s:%d: convert_from_SI_to_kSI(%d,%g)\n",__FILE__,__LINE__,iInput,value).c_str();
    }

    switch (iInput)
    {
    case CoolProp::iP:
    case CoolProp::iCpmass:
    case CoolProp::iCp0mass:
    case CoolProp::iSmass:
    case CoolProp::iGmass:
    case CoolProp::iCvmass:
    case CoolProp::iHmass:
    case CoolProp::iUmass:
    case CoolProp::iconductivity:
        return value/1000.0;
    case CoolProp::iDmass:
    case CoolProp::iQ:
    case CoolProp::ispeed_sound:
    case CoolProp::iviscosity:
    case CoolProp::iT:
    case CoolProp::isurface_tension:
        return value;
    default:
        throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_SI_to_kSI", iInput).c_str());
        break;
    }
    return _HUGE;
}

EXPORT_CODE long CONVENTION redirect_stdout(const char* file){
    freopen(file, "a+", stdout);
    reset_fpu();
    return 0;
}
EXPORT_CODE int CONVENTION set_reference_stateS(const char *Ref, const char *reference_state)
{
    std::string _Ref = Ref, _reference_state = reference_state;
    try{
        CoolProp::set_reference_stateS(_Ref, _reference_state);
        reset_fpu();
        return true;
    }
    catch(std::exception &){
        reset_fpu();
        return false;
    }
}
EXPORT_CODE int CONVENTION set_reference_stateD(const char *Ref, double T, double rho, double h0, double s0)
{
    try{
        CoolProp::set_reference_stateD(std::string(Ref), T, rho, h0, s0);
        reset_fpu();
        return true;
    }
    catch(std::exception &){
        reset_fpu();
        return false;
    }
}

// All the function interfaces that point to the single-input Props function
EXPORT_CODE double CONVENTION Props1(const char *FluidName, const char *Output){
    double val = PropsS(Output, "", 0, "", 0, FluidName);
    reset_fpu();
    return val;
}
EXPORT_CODE double CONVENTION PropsS(const char *Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char * Ref){
    double val = Props(Output,Name1[0],Prop1,Name2[0],Prop2,Ref);
    reset_fpu();
    return val;
}
EXPORT_CODE double CONVENTION Props(const char *Output, const char Name1, double Prop1, const char Name2, double Prop2, const char * Ref)
{
    try
    {
        // Get parameter indices
        std::string sName1 = std::string(1, Name1), sName2 = std::string(1, Name2);
        long iOutput = get_param_index(Output);
        long iName1 = CoolProp::get_parameter_index(sName1);
        long iName2 = CoolProp::get_parameter_index(sName2);

        // Convert inputs to SI
        Prop1 = convert_from_kSI_to_SI(iName1, Prop1);
        Prop2 = convert_from_kSI_to_SI(iName2, Prop2);

        // Call the SI function
        double val = PropsSI(Output, sName1.c_str(), Prop1, sName2.c_str(), Prop2, Ref);

        reset_fpu();

        // Convert back to unit system
        return convert_from_SI_to_kSI(iOutput, val);
    }
    catch(std::exception &e){CoolProp::set_error_string(e.what()); return _HUGE;}
    catch(...){CoolProp::set_error_string("Undefined error"); return _HUGE;}
}
EXPORT_CODE double CONVENTION saturation_ancillary(const char *fluid_name, const char *output, int Q, const char *input, double value)
{
    try
    {
        std::string _output = output, _input = input;
        double val = CoolProp::saturation_ancillary(fluid_name, _output, Q, _input, value);
        reset_fpu();
        return val;
    }
    catch(std::exception &e){CoolProp::set_error_string(e.what()); return _HUGE;}
    catch(...){CoolProp::set_error_string("Undefined error"); return _HUGE;}
}
EXPORT_CODE double CONVENTION Props1SI(const char *FluidName, const char *Output)
{
    std::string _Output = Output, _FluidName = FluidName;
    double val = CoolProp::Props1SI(_FluidName, _Output);
    reset_fpu();
    return val;
}
EXPORT_CODE double CONVENTION PropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * FluidName)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
    double val = CoolProp::PropsSI(_Output, _Name1, Prop1, _Name2, Prop2, _FluidName);
    reset_fpu();
    return val;
}
EXPORT_CODE long CONVENTION PhaseSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * FluidName, char *phase, int n)
{
    std::string _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
    std::string s = CoolProp::PhaseSI(_Name1, Prop1, _Name2, Prop2, _FluidName);
    if (s.size() < static_cast<unsigned int>(n)){
        strcpy(phase, s.c_str());
        reset_fpu();
        return 1;
    }
    else{
        reset_fpu();
        return 0;
    }
}
EXPORT_CODE double CONVENTION PropsSIZ(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * FluidName, const double *z, int n)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
    double val = CoolProp::PropsSI(_Output, _Name1, Prop1, _Name2, Prop2, _FluidName, std::vector<double>(z, z+n));
    reset_fpu();
    return val;
}
EXPORT_CODE void CONVENTION propssi_(const char *Output, const char *Name1, double *Prop1, const char *Name2, double *Prop2, const char * FluidName, double *output)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
    *output = CoolProp::PropsSI(_Output, _Name1, *Prop1, _Name2, *Prop2, _FluidName);
    reset_fpu();
}

EXPORT_CODE double CONVENTION K2F(double T){
    return T * 9 / 5 - 459.67;
}
EXPORT_CODE double CONVENTION F2K(double T_F){
    return (T_F + 459.67) * 5 / 9;
}
EXPORT_CODE int CONVENTION get_debug_level(){
    return CoolProp::get_debug_level();
}
EXPORT_CODE void CONVENTION set_debug_level(int level){
    CoolProp::set_debug_level(level);
}
EXPORT_CODE long CONVENTION get_param_index(const char * param){
    return CoolProp::get_parameter_index(param);
}
EXPORT_CODE long CONVENTION get_global_param_string(const char *param, char * Output, int n)
{
    std::string s;
    try{
        s = CoolProp::get_global_param_string(param);
    }
    catch(std::exception &){
        return 0;
    }
    if (s.size() < static_cast<unsigned int>(n)){
        strcpy(Output, s.c_str());
        return 1;
    }
    else{
        return 0;
    }
}
EXPORT_CODE long CONVENTION get_parameter_information_string(const char *param, char * Output, int n)
{
    int key = CoolProp::get_parameter_index(param);
    if (key >= 0){
        std::string s = CoolProp::get_parameter_information(key, Output);
        if (s.size() < static_cast<unsigned int>(n)){
            strcpy(Output, s.c_str());
            return 1;
        }
        else{
            return 0;
        }
    }
    else{
        strcpy(Output, format("parameter is invalid: %s", param).c_str());
        return 0;
    }
}
EXPORT_CODE long CONVENTION get_fluid_param_string(const char *fluid, const char *param, char * Output, int n)
{
    std::string s;
    try{
        s = CoolProp::get_fluid_param_string(std::string(fluid), std::string(param));
    }
    catch(std::exception &){
        return 0;
    }
    if (s.size() < static_cast<unsigned int>(n)){
        strcpy(Output, s.c_str());
        return 1;
    }
    else{
        return 0;
    }
}
EXPORT_CODE double CONVENTION HAPropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * Name3, double Prop3)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3;
    double val = HumidAir::HAPropsSI(Output, _Name1, Prop1, _Name2, Prop2, _Name3, Prop3);
    reset_fpu();
    return val;
}
EXPORT_CODE void CONVENTION hapropssi_(const char *Output, const char *Name1, double *Prop1, const char *Name2, double *Prop2, const char * Name3, double * Prop3, double *output)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3;
    *output = HumidAir::HAPropsSI(_Output, _Name1, *Prop1, _Name2, *Prop2, _Name3, *Prop3);
    reset_fpu();
}
EXPORT_CODE double CONVENTION HAProps(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * Name3, double Prop3)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3;
    double val = HumidAir::HAProps(Output, _Name1, Prop1, _Name2, Prop2, _Name3, Prop3);
    reset_fpu();
    return val;
}
EXPORT_CODE void CONVENTION haprops_(const char *Output, const char *Name1, double *Prop1, const char *Name2, double *Prop2, const char * Name3, double * Prop3, double *output)
{
    *output = HAProps(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
    reset_fpu();
}
<commit_msg>Disable the clearing of FPU exceptions on platforms that do not support it<commit_after>#if defined(_MSC_VER)
#define _CRTDBG_MAP_ALLOC
#define _CRT_SECURE_NO_WARNINGS
#include <crtdbg.h>
#else
#include <fenv.h>
#endif

#include "CoolPropLib.h"
#include "CoolProp.h"
#include "HumidAirProp.h"
#include "DataStructures.h"
#include "Exceptions.h"
#include "float.h"

#include <string.h>

// In Microsoft Excel, they seem to check the FPU exception bits and error out because of it.
// By calling the _clearfp(), we can reset these bits, and not get the error
// See also http://stackoverflow.com/questions/11685441/floating-point-error-when-calling-dll-function-from-vba/27336496#27336496
// See also http://stackoverflow.com/questions/16849009/in-linux-do-there-exist-functions-similar-to-clearfp-and-statusfp for linux and OSX
void reset_fpu()
{
    #if defined(_MSC_VER)
        _clearfp(); // For MSVC, clear the floating point error flags
    #elif defined(FE_ALL_EXCEPT)
        feclearexcept(FE_ALL_EXCEPT);
    #endif
}
double convert_from_kSI_to_SI(long iInput, double value)
{
    if (get_debug_level() > 8){
        std::cout << format("%s:%d: convert_from_kSI_to_SI(i=%d,value=%g)\n",__FILE__,__LINE__,iInput,value).c_str();
    }

    switch (iInput)
    {
    case CoolProp::iP:
    case CoolProp::iCpmass:
    case CoolProp::iCp0mass:
    case CoolProp::iSmass:
    case CoolProp::iGmass:
    case CoolProp::iCvmass:
    case CoolProp::iHmass:
    case CoolProp::iUmass:
    case CoolProp::iconductivity:
        return value*1000.0;
    case CoolProp::iDmass:
    case CoolProp::ispeed_sound:
    case CoolProp::iQ:
    case CoolProp::iviscosity:
    case CoolProp::iT:
    case CoolProp::iPrandtl:
    case CoolProp::isurface_tension:
        return value;
    default:
        throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_kSI_to_SI",iInput).c_str());
        break;
    }
    return _HUGE;
}

double convert_from_SI_to_kSI(long iInput, double value)
{
    if (get_debug_level() > 8){
        std::cout << format("%s:%d: convert_from_SI_to_kSI(%d,%g)\n",__FILE__,__LINE__,iInput,value).c_str();
    }

    switch (iInput)
    {
    case CoolProp::iP:
    case CoolProp::iCpmass:
    case CoolProp::iCp0mass:
    case CoolProp::iSmass:
    case CoolProp::iGmass:
    case CoolProp::iCvmass:
    case CoolProp::iHmass:
    case CoolProp::iUmass:
    case CoolProp::iconductivity:
        return value/1000.0;
    case CoolProp::iDmass:
    case CoolProp::iQ:
    case CoolProp::ispeed_sound:
    case CoolProp::iviscosity:
    case CoolProp::iT:
    case CoolProp::isurface_tension:
        return value;
    default:
        throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_SI_to_kSI", iInput).c_str());
        break;
    }
    return _HUGE;
}

EXPORT_CODE long CONVENTION redirect_stdout(const char* file){
    freopen(file, "a+", stdout);
    reset_fpu();
    return 0;
}
EXPORT_CODE int CONVENTION set_reference_stateS(const char *Ref, const char *reference_state)
{
    std::string _Ref = Ref, _reference_state = reference_state;
    try{
        CoolProp::set_reference_stateS(_Ref, _reference_state);
        reset_fpu();
        return true;
    }
    catch(std::exception &){
        reset_fpu();
        return false;
    }
}
EXPORT_CODE int CONVENTION set_reference_stateD(const char *Ref, double T, double rho, double h0, double s0)
{
    try{
        CoolProp::set_reference_stateD(std::string(Ref), T, rho, h0, s0);
        reset_fpu();
        return true;
    }
    catch(std::exception &){
        reset_fpu();
        return false;
    }
}

// All the function interfaces that point to the single-input Props function
EXPORT_CODE double CONVENTION Props1(const char *FluidName, const char *Output){
    double val = PropsS(Output, "", 0, "", 0, FluidName);
    reset_fpu();
    return val;
}
EXPORT_CODE double CONVENTION PropsS(const char *Output, const char* Name1, double Prop1, const char* Name2, double Prop2, const char * Ref){
    double val = Props(Output,Name1[0],Prop1,Name2[0],Prop2,Ref);
    reset_fpu();
    return val;
}
EXPORT_CODE double CONVENTION Props(const char *Output, const char Name1, double Prop1, const char Name2, double Prop2, const char * Ref)
{
    try
    {
        // Get parameter indices
        std::string sName1 = std::string(1, Name1), sName2 = std::string(1, Name2);
        long iOutput = get_param_index(Output);
        long iName1 = CoolProp::get_parameter_index(sName1);
        long iName2 = CoolProp::get_parameter_index(sName2);

        // Convert inputs to SI
        Prop1 = convert_from_kSI_to_SI(iName1, Prop1);
        Prop2 = convert_from_kSI_to_SI(iName2, Prop2);

        // Call the SI function
        double val = PropsSI(Output, sName1.c_str(), Prop1, sName2.c_str(), Prop2, Ref);

        reset_fpu();

        // Convert back to unit system
        return convert_from_SI_to_kSI(iOutput, val);
    }
    catch(std::exception &e){CoolProp::set_error_string(e.what()); return _HUGE;}
    catch(...){CoolProp::set_error_string("Undefined error"); return _HUGE;}
}
EXPORT_CODE double CONVENTION saturation_ancillary(const char *fluid_name, const char *output, int Q, const char *input, double value)
{
    try
    {
        std::string _output = output, _input = input;
        double val = CoolProp::saturation_ancillary(fluid_name, _output, Q, _input, value);
        reset_fpu();
        return val;
    }
    catch(std::exception &e){CoolProp::set_error_string(e.what()); return _HUGE;}
    catch(...){CoolProp::set_error_string("Undefined error"); return _HUGE;}
}
EXPORT_CODE double CONVENTION Props1SI(const char *FluidName, const char *Output)
{
    std::string _Output = Output, _FluidName = FluidName;
    double val = CoolProp::Props1SI(_FluidName, _Output);
    reset_fpu();
    return val;
}
EXPORT_CODE double CONVENTION PropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * FluidName)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
    double val = CoolProp::PropsSI(_Output, _Name1, Prop1, _Name2, Prop2, _FluidName);
    reset_fpu();
    return val;
}
EXPORT_CODE long CONVENTION PhaseSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * FluidName, char *phase, int n)
{
    std::string _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
    std::string s = CoolProp::PhaseSI(_Name1, Prop1, _Name2, Prop2, _FluidName);
    if (s.size() < static_cast<unsigned int>(n)){
        strcpy(phase, s.c_str());
        reset_fpu();
        return 1;
    }
    else{
        reset_fpu();
        return 0;
    }
}
EXPORT_CODE double CONVENTION PropsSIZ(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * FluidName, const double *z, int n)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
    double val = CoolProp::PropsSI(_Output, _Name1, Prop1, _Name2, Prop2, _FluidName, std::vector<double>(z, z+n));
    reset_fpu();
    return val;
}
EXPORT_CODE void CONVENTION propssi_(const char *Output, const char *Name1, double *Prop1, const char *Name2, double *Prop2, const char * FluidName, double *output)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _FluidName = FluidName;
    *output = CoolProp::PropsSI(_Output, _Name1, *Prop1, _Name2, *Prop2, _FluidName);
    reset_fpu();
}

EXPORT_CODE double CONVENTION K2F(double T){
    return T * 9 / 5 - 459.67;
}
EXPORT_CODE double CONVENTION F2K(double T_F){
    return (T_F + 459.67) * 5 / 9;
}
EXPORT_CODE int CONVENTION get_debug_level(){
    return CoolProp::get_debug_level();
}
EXPORT_CODE void CONVENTION set_debug_level(int level){
    CoolProp::set_debug_level(level);
}
EXPORT_CODE long CONVENTION get_param_index(const char * param){
    return CoolProp::get_parameter_index(param);
}
EXPORT_CODE long CONVENTION get_global_param_string(const char *param, char * Output, int n)
{
    std::string s;
    try{
        s = CoolProp::get_global_param_string(param);
    }
    catch(std::exception &){
        return 0;
    }
    if (s.size() < static_cast<unsigned int>(n)){
        strcpy(Output, s.c_str());
        return 1;
    }
    else{
        return 0;
    }
}
EXPORT_CODE long CONVENTION get_parameter_information_string(const char *param, char * Output, int n)
{
    int key = CoolProp::get_parameter_index(param);
    if (key >= 0){
        std::string s = CoolProp::get_parameter_information(key, Output);
        if (s.size() < static_cast<unsigned int>(n)){
            strcpy(Output, s.c_str());
            return 1;
        }
        else{
            return 0;
        }
    }
    else{
        strcpy(Output, format("parameter is invalid: %s", param).c_str());
        return 0;
    }
}
EXPORT_CODE long CONVENTION get_fluid_param_string(const char *fluid, const char *param, char * Output, int n)
{
    std::string s;
    try{
        s = CoolProp::get_fluid_param_string(std::string(fluid), std::string(param));
    }
    catch(std::exception &){
        return 0;
    }
    if (s.size() < static_cast<unsigned int>(n)){
        strcpy(Output, s.c_str());
        return 1;
    }
    else{
        return 0;
    }
}
EXPORT_CODE double CONVENTION HAPropsSI(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * Name3, double Prop3)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3;
    double val = HumidAir::HAPropsSI(Output, _Name1, Prop1, _Name2, Prop2, _Name3, Prop3);
    reset_fpu();
    return val;
}
EXPORT_CODE void CONVENTION hapropssi_(const char *Output, const char *Name1, double *Prop1, const char *Name2, double *Prop2, const char * Name3, double * Prop3, double *output)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3;
    *output = HumidAir::HAPropsSI(_Output, _Name1, *Prop1, _Name2, *Prop2, _Name3, *Prop3);
    reset_fpu();
}
EXPORT_CODE double CONVENTION HAProps(const char *Output, const char *Name1, double Prop1, const char *Name2, double Prop2, const char * Name3, double Prop3)
{
    std::string _Output = Output, _Name1 = Name1, _Name2 = Name2, _Name3 = Name3;
    double val = HumidAir::HAProps(Output, _Name1, Prop1, _Name2, Prop2, _Name3, Prop3);
    reset_fpu();
    return val;
}
EXPORT_CODE void CONVENTION haprops_(const char *Output, const char *Name1, double *Prop1, const char *Name2, double *Prop2, const char * Name3, double * Prop3, double *output)
{
    *output = HAProps(Output, Name1, *Prop1, Name2, *Prop2, Name3, *Prop3);
    reset_fpu();
}
<|endoftext|>


<commit_before>#include <chrono>
#include <thread>
#include <cstring>
#include <stdio.h>

#include "AudioSubsystem.h"
#include "AudioSubsystem_OpenAL.h"
#include "Decoders/iWaveDataProvider.h"
#include "Decoders/WAV/WAVDataProvider.h"
#include "Encoders/iWaveDataEncoder.h"
#include "Utils.h"
#include "Playlist.h"

#define ENABLE_TEST	0

const char* PORTAMP_VERSION = "1.1.2";

sConfig g_Config;
clPlaylist g_Playlist;

sConfig ReadConfigFromCommandLine( int argc, char* argv[] )
{
	sConfig Cfg;

	int i = 1;

	while ( i < argc )
	{
		if ( strstr( argv[i], "--loop" ) == argv[i] ) Cfg.m_Loop = true;
		else if ( strstr( argv[i], "--wav-modplug" ) == argv[i] ) Cfg.m_UseModPlugToDecodeWAV = true;
		else if ( strstr( argv[i], "--verbose" ) == argv[i] ) Cfg.m_Verbose = true;
		else if ( strstr (argv[i], "--output-file" ) == argv[i] )
		{
			if ( i+1 < argc )
			{
				Cfg.m_OutputFile = argv[++i];
			}
			else
			{
				printf( "Expected output file name for --output-file\n" );
				exit(0);
			}
		}
		else g_Playlist.EnqueueTrack( argv[i] );
		i++;
	}

	return Cfg;
}

void PrintBanner()
{
	printf( "PortAMP version %s (%s)\n", PORTAMP_VERSION, __DATE__ " " __TIME__ " via " __COMPILER_VER__ " for " BUILD_OS );
	printf( "Copyright (C) 2015-2016 Sergey Kosarevsky\n" );
	printf( "portamp@linderdaum.com\n" );
	printf( "https://github.com/corporateshark/PortAMP\n" );
	printf( "\n" );
	printf( "portamp <filename1> [<filename2> ...] [--loop] [--wav-modplug] [--verbose]\n" );
	printf( "\n" );
}

int main( int argc, char* argv[] )
{
#if !ENABLE_TEST
	if ( argc <= 1 )
	{
		PrintBanner();
		return 0;
	}
#endif

	g_Config = ReadConfigFromCommandLine( argc, argv );

#if ENABLE_TEST
	if ( g_Playlist.IsEmpty() ) g_Playlist.EnqueueTrack( "test.ogg" );
	g_Config.m_Verbose = true;
#endif

	auto AudioSubsystem = CreateAudioSubsystem_OpenAL();

	AudioSubsystem->Start();

	auto Source = AudioSubsystem->CreateAudioSource();
	// allow seamless looping if there is only one track
	if ( g_Playlist.GetNumTracks() == 1 ) Source->SetLooping( g_Config.m_Loop );

	bool RequestingExit = false;

	while ( !g_Playlist.IsEmpty() && !RequestingExit )
	{
		auto FileName = g_Playlist.GetAndPopNextTrack( g_Config.m_Loop );
		auto DataBlob = ReadFileAsBlob( FileName.c_str() );
		if (!DataBlob || !DataBlob->GetDataSize()) continue;

		auto Provider = CreateWaveDataProvider( FileName.c_str(), DataBlob );
		if (!Provider) continue;

		Source->BindDataProvider( Provider );
		Source->Play();

		while ( Source->IsPlaying() && !RequestingExit )
		{
			std::this_thread::sleep_for( std::chrono::milliseconds(10) );

			if ( IsKeyPressed() ) RequestingExit = true;
		};

		Source->Stop();
	}

	Source = nullptr;

	AudioSubsystem->Stop();

	return 0;
};
<commit_msg>Updated version to 1.1.3<commit_after>#include <chrono>
#include <thread>
#include <cstring>
#include <stdio.h>

#include "AudioSubsystem.h"
#include "AudioSubsystem_OpenAL.h"
#include "Decoders/iWaveDataProvider.h"
#include "Decoders/WAV/WAVDataProvider.h"
#include "Encoders/iWaveDataEncoder.h"
#include "Utils.h"
#include "Playlist.h"

#define ENABLE_TEST	0

const char* PORTAMP_VERSION = "1.1.3";

sConfig g_Config;
clPlaylist g_Playlist;

sConfig ReadConfigFromCommandLine( int argc, char* argv[] )
{
	sConfig Cfg;

	int i = 1;

	while ( i < argc )
	{
		if ( strstr( argv[i], "--loop" ) == argv[i] ) Cfg.m_Loop = true;
		else if ( strstr( argv[i], "--wav-modplug" ) == argv[i] ) Cfg.m_UseModPlugToDecodeWAV = true;
		else if ( strstr( argv[i], "--verbose" ) == argv[i] ) Cfg.m_Verbose = true;
		else if ( strstr (argv[i], "--output-file" ) == argv[i] )
		{
			if ( i+1 < argc )
			{
				Cfg.m_OutputFile = argv[++i];
			}
			else
			{
				printf( "Expected output file name for --output-file\n" );
				exit(0);
			}
		}
		else g_Playlist.EnqueueTrack( argv[i] );
		i++;
	}

	return Cfg;
}

void PrintBanner()
{
	printf( "PortAMP version %s (%s)\n", PORTAMP_VERSION, __DATE__ " " __TIME__ " via " __COMPILER_VER__ " for " BUILD_OS );
	printf( "Copyright (C) 2015-2016 Sergey Kosarevsky\n" );
	printf( "portamp@linderdaum.com\n" );
	printf( "https://github.com/corporateshark/PortAMP\n" );
	printf( "\n" );
	printf( "portamp <filename1> [<filename2> ...] [--loop] [--wav-modplug] [--verbose]\n" );
	printf( "\n" );
}

int main( int argc, char* argv[] )
{
#if !ENABLE_TEST
	if ( argc <= 1 )
	{
		PrintBanner();
		return 0;
	}
#endif

	g_Config = ReadConfigFromCommandLine( argc, argv );

#if ENABLE_TEST
	if ( g_Playlist.IsEmpty() ) g_Playlist.EnqueueTrack( "test.ogg" );
	g_Config.m_Verbose = true;
#endif

	auto AudioSubsystem = CreateAudioSubsystem_OpenAL();

	AudioSubsystem->Start();

	auto Source = AudioSubsystem->CreateAudioSource();
	// allow seamless looping if there is only one track
	if ( g_Playlist.GetNumTracks() == 1 ) Source->SetLooping( g_Config.m_Loop );

	bool RequestingExit = false;

	while ( !g_Playlist.IsEmpty() && !RequestingExit )
	{
		auto FileName = g_Playlist.GetAndPopNextTrack( g_Config.m_Loop );
		auto DataBlob = ReadFileAsBlob( FileName.c_str() );
		if (!DataBlob || !DataBlob->GetDataSize()) continue;

		auto Provider = CreateWaveDataProvider( FileName.c_str(), DataBlob );
		if (!Provider) continue;

		Source->BindDataProvider( Provider );
		Source->Play();

		while ( Source->IsPlaying() && !RequestingExit )
		{
			std::this_thread::sleep_for( std::chrono::milliseconds(10) );

			if ( IsKeyPressed() ) RequestingExit = true;
		};

		Source->Stop();
	}

	Source = nullptr;

	AudioSubsystem->Stop();

	return 0;
};
<|endoftext|>


<commit_before>/*	opendatacon
 *
 *	Copyright (c) 2014:
 *
 *		DCrip3fJguWgVCLrZFfA7sIGgvx1Ou3fHfCxnrz4svAi
 *		yxeOtDhDCXf1Z4ApgXvX5ahqQmzRfJ2DoX8S05SqHA==
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */
/*
 * main.cpp
 *
 *  Created on: 14/07/2014
 *      Author: Neil Stephens <dearknarl@gmail.com>
 */

/*TODO:
 * 	-fix logging:
 * 		-use log level properly
 * 		-cmd to change log level on the fly (part of config cmds: see below)
 * 	-add config change commands
 * 		-implement BuildOrRebuild properly for changed configs
 * 		-cmd to apply config item from command line
 * 		-cmd to load config from file
 * 		-save config to file
 * 	-add maintenance commands:
 * 		-enable/disable/restart ports/connectors/connections
 * 	-remove the need for DNP3Manager and two threadpools?
 * 		-DataConcentrator class can do it all
 * 	-implement plugin architecture - the following should be plugins:
 * 		-DataPort implementations
 * 		-Transform implementations
 * 	-add a network interface to the console
 *	-network logging
 *	-daemon mode
 *	-more dataports to implement:
 *		-EventGenPort (random events ala old test_slaves util)
 *		-C37.118
 *		-NMEA 2k / CANv2
 *		-NMEA 0183
 *		-XMLoHTML (inc. Gridlab-D)
 *		-JSONoHTML
 */

#include "DataConcentrator.h"

int main(int argc, char* argv[])
{
	try
	{
		//default config file
		std::string ConfFileName = "opendatacon.conf";
		//override if there's one provided
		if (argc>1)
			ConfFileName = argv[1];

		DataConcentrator TheDataConcentrator(ConfFileName);
		TheDataConcentrator.BuildOrRebuild();
		TheDataConcentrator.Run();

	}
	catch(std::exception& e)
	{
		std::cout<<"Caught exception: "<<e.what()<<std::endl;
		return 1;
	}

	return 0;
}

<commit_msg>updated TODO list<commit_after>/*	opendatacon
 *
 *	Copyright (c) 2014:
 *
 *		DCrip3fJguWgVCLrZFfA7sIGgvx1Ou3fHfCxnrz4svAi
 *		yxeOtDhDCXf1Z4ApgXvX5ahqQmzRfJ2DoX8S05SqHA==
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */
/*
 * main.cpp
 *
 *  Created on: 14/07/2014
 *      Author: Neil Stephens <dearknarl@gmail.com>
 */

/*TODO:
 * 	-fix logging:
 * 		-cmd to change log level on the fly (part of config cmds: see below)
 * 	-add config change commands
 * 		-implement BuildOrRebuild properly for changed configs
 * 		-cmd to apply config item from command line
 * 		-cmd to load config from file
 * 		-save config to file
 * 	-add maintenance commands:
 * 		-enable/disable/restart ports/connectors/connections
 * 	-remove the need for DNP3Manager and two threadpools?
 * 		-DataConcentrator class can do it all
 * 	-implement plugin architecture - the following should be plugins:
 * 		-DataPort implementations - DONE
 * 		-Transform implementations
 * 	-add a network interface to the console
 *	-network logging
 *	-daemon mode
 *	-more dataports to implement:
 *		-EventGenPort (random events ala old test_slaves util)
 *		-C37.118
 *		-NMEA 2k / CANv2
 *		-NMEA 0183
 *		-XMLoHTML (inc. Gridlab-D)
 *		-JSONoHTML
 */

#include "DataConcentrator.h"

int main(int argc, char* argv[])
{
	try
	{
		//default config file
		std::string ConfFileName = "opendatacon.conf";
		//override if there's one provided
		if (argc>1)
			ConfFileName = argv[1];

		DataConcentrator TheDataConcentrator(ConfFileName);
		TheDataConcentrator.BuildOrRebuild();
		TheDataConcentrator.Run();

	}
	catch(std::exception& e)
	{
		std::cout<<"Caught exception: "<<e.what()<<std::endl;
		return 1;
	}

	return 0;
}

<|endoftext|>


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

#include <allegro5/allegro.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>

#include <cstdio>
#include <memory>

#define DEBUG

void initialize();
void shutdown();

struct Assets {
public:
    Assets() :
        background(load_bitmap("res/imgs/Backgrounds/apurple.png"))
    { }

    Assets(const Assets& a) :
        background(a.background) { }

    ~Assets() {
        al_destroy_bitmap(background);
    }

    Assets& operator = (const Assets& a);

    ALLEGRO_BITMAP *background;

protected:

    ALLEGRO_BITMAP *load_bitmap(const char *file) {
        auto tmp = al_load_bitmap(file);
        assert(tmp && printf("Bitmap is not valid."));
        return tmp;
    }
};

typedef enum {
    Menu,
    Game,
    End,
} Stage;

int main(void) {
    initialize();

    Assets* assets = new Assets();
    Stage stage = Menu;

    ALLEGRO_DISPLAY *display = al_create_display(1920, 1080);
    ALLEGRO_EVENT_QUEUE *evqueue = al_create_event_queue();
    ALLEGRO_TIMER *fps_timer = al_create_timer(1.0 / 60.0);
    bool render = true, executing = true;

    al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, true);

    if (!display) {
        printf("Failed to create display!\n");
        exit(EXIT_FAILURE);
    }

    al_register_event_source(evqueue, al_get_keyboard_event_source());
    al_register_event_source(evqueue, al_get_mouse_event_source());
    al_register_event_source(evqueue, al_get_display_event_source(display));
    al_register_event_source(evqueue, al_get_timer_event_source(fps_timer));

    al_start_timer(fps_timer);

    while (executing) {
        ALLEGRO_EVENT event;
        al_wait_for_event(evqueue, &event);
        switch (event.type) {
            case ALLEGRO_EVENT_TIMER:
                render = true;
                break;
            case ALLEGRO_EVENT_DISPLAY_CLOSE:
                executing = false;
                break;
            case ALLEGRO_EVENT_KEY_DOWN:
                executing = event.keyboard.keycode != ALLEGRO_KEY_ESCAPE;
                break;
            default: break;
        }

        if (render && al_is_event_queue_empty(evqueue)) {
            render = false;
            al_clear_to_color(al_map_rgb(0, 0, 0));
            al_set_target_bitmap(al_get_backbuffer(display));
            for (float x = 0; x < 1080; x += al_get_bitmap_width(assets->background)) {
                for (float y = 0; y < 1920; y += al_get_bitmap_height(assets->background)) {
                    al_draw_bitmap(assets->background, x, y, 0);
                }
            }
            switch (stage) {
            default: break;
            case Menu:

                break;
            case Game:

                break;
            case End:

                break;
            }
            al_flip_display();
        }
        render = false;
    }

    al_unregister_event_source(evqueue, al_get_keyboard_event_source());
    al_unregister_event_source(evqueue, al_get_mouse_event_source());
    al_unregister_event_source(evqueue, al_get_display_event_source(display));
    al_unregister_event_source(evqueue, al_get_timer_event_source(fps_timer));

    al_destroy_display(display);
    al_destroy_event_queue(evqueue);
    al_destroy_timer(fps_timer);

    delete assets;
    shutdown();
    return EXIT_SUCCESS;
}

void initialize() {
    srand((unsigned int) time(NULL));

#ifdef DEBUG
    printf("Allegro v%i.%i.%i\n",
        al_get_allegro_version() >> 24,
        (al_get_allegro_version() >> 16) & 255,
        (al_get_allegro_version() >> 8) & 255);
#endif //DEBUG

    if (!al_init()) {
        printf("Failed to initialize allegro!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_install_audio()) {
        fprintf(stderr, "Failed to initialize audio!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_init_acodec_addon()) {
        fprintf(stderr, "Failed to initialize audio codecs!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_reserve_samples(1)) {
        fprintf(stderr, "Failed to reserve samples!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_install_mouse()) {
        fprintf(stderr, "Failed to initialize the mouse!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_install_keyboard()) {
        fprintf(stderr, "al_install_keyboard Failed!\n");
        exit(EXIT_FAILURE);
    }

    al_init_primitives_addon();
    al_init_font_addon();
    al_init_ttf_addon();
    al_init_image_addon();
}

void shutdown() {
    al_shutdown_image_addon();
    al_shutdown_ttf_addon();
    al_shutdown_font_addon();
    al_shutdown_primitives_addon();
    al_uninstall_keyboard();
    al_uninstall_mouse();
    al_uninstall_audio();
    al_uninstall_system();
}
<commit_msg>stuff<commit_after>//-----------------------------------------------------------------------------
// The MIT License (MIT)
//
// Copyright (c) 2016 Thomas Steinholz
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//-----------------------------------------------------------------------------

#include <allegro5/allegro.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>

#include <cstdio>
#include <memory>

#define DEBUG

void initialize();
void shutdown();

struct Assets {
public:
    Assets() :
        background(load_bitmap("res/imgs/Backgrounds/purple.png"))
    { }

    Assets(const Assets& a) :
        background(a.background) { }

    ~Assets() {
#ifdef DEBUG
        printf("Destroyed Assets\n");
#endif // DEBUG
        al_destroy_bitmap(background);
    }

    Assets& operator = (const Assets& a);

    ALLEGRO_BITMAP *background;

protected:

    ALLEGRO_BITMAP *load_bitmap(const char *file) {
        auto tmp = al_load_bitmap(file);
        assert(tmp && printf("Loaded %s\n", file));
        return tmp;
    }
};

typedef enum {
    Menu,
    Game,
    End,
} Stage;

int main(void) {
    initialize();

    Assets* assets = new Assets();
    Stage stage = Menu;

    ALLEGRO_DISPLAY *display = al_create_display(1920, 1080);
    ALLEGRO_EVENT_QUEUE *evqueue = al_create_event_queue();
    ALLEGRO_TIMER *fps_timer = al_create_timer(1.0 / 60.0);
    bool render = true, executing = true;

    al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, true);

    if (!display) {
        printf("Failed to create display!\n");
        exit(EXIT_FAILURE);
    }

    al_register_event_source(evqueue, al_get_keyboard_event_source());
    al_register_event_source(evqueue, al_get_mouse_event_source());
    al_register_event_source(evqueue, al_get_display_event_source(display));
    al_register_event_source(evqueue, al_get_timer_event_source(fps_timer));

    al_start_timer(fps_timer);

    while (executing) {
        ALLEGRO_EVENT event;
        al_wait_for_event(evqueue, &event);
        switch (event.type) {
            case ALLEGRO_EVENT_TIMER:
                render = true;
                break;
            case ALLEGRO_EVENT_DISPLAY_CLOSE:
                executing = false;
                break;
            case ALLEGRO_EVENT_KEY_DOWN:
                executing = event.keyboard.keycode != ALLEGRO_KEY_ESCAPE;
                break;
            default: break;
        }

        if (render && al_is_event_queue_empty(evqueue)) {
            render = false;
            al_clear_to_color(al_map_rgb(0, 0, 0));
            al_set_target_bitmap(al_get_backbuffer(display));
            for (float x = 0; x < 1080; x += al_get_bitmap_width(assets->background)) {
                for (float y = 0; y < 1920; y += al_get_bitmap_height(assets->background)) {
                    al_draw_bitmap(assets->background, x, y, 0);
                }
            }
            switch (stage) {
            default: break;
            case Menu:

                break;
            case Game:

                break;
            case End:

                break;
            }
            al_flip_display();
        }
        render = false;
    }

    al_unregister_event_source(evqueue, al_get_keyboard_event_source());
    al_unregister_event_source(evqueue, al_get_mouse_event_source());
    al_unregister_event_source(evqueue, al_get_display_event_source(display));
    al_unregister_event_source(evqueue, al_get_timer_event_source(fps_timer));

    al_destroy_display(display);
    al_destroy_event_queue(evqueue);
    al_destroy_timer(fps_timer);

    delete assets;
    shutdown();
    return EXIT_SUCCESS;
}

void initialize() {
    srand((unsigned int) time(NULL));

#ifdef DEBUG
    printf("Allegro v%i.%i.%i\n",
        al_get_allegro_version() >> 24,
        (al_get_allegro_version() >> 16) & 255,
        (al_get_allegro_version() >> 8) & 255);
#endif //DEBUG

    if (!al_init()) {
        printf("Failed to initialize allegro!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_install_audio()) {
        fprintf(stderr, "Failed to initialize audio!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_init_acodec_addon()) {
        fprintf(stderr, "Failed to initialize audio codecs!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_reserve_samples(1)) {
        fprintf(stderr, "Failed to reserve samples!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_install_mouse()) {
        fprintf(stderr, "Failed to initialize the mouse!\n");
        exit(EXIT_FAILURE);
    }
    if (!al_install_keyboard()) {
        fprintf(stderr, "al_install_keyboard Failed!\n");
        exit(EXIT_FAILURE);
    }

    al_init_primitives_addon();
    al_init_font_addon();
    al_init_ttf_addon();
    al_init_image_addon();
}

void shutdown() {
    al_shutdown_image_addon();
    al_shutdown_ttf_addon();
    al_shutdown_font_addon();
    al_shutdown_primitives_addon();
    al_uninstall_keyboard();
    al_uninstall_mouse();
    al_uninstall_audio();
    al_uninstall_system();
}
<|endoftext|>