<commit_before>/*  ************************************************************************************
 *
 *  ftParticleFlow
 *
 *  Created by Matthias Oostrik on 03/16.14.
 *  Copyright 2014 http://www.MatthiasOostrik.com All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the author nor the names of its contributors
 *       may be used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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 "ftParticleFlow.h"

namespace flowTools {

	ftParticleFlow::ftParticleFlow(){
		parameters.setName("particle flow");
		parameters.add(bIsActive.set("active", true));
		parameters.add(speed.set("speed", 20, 0, 100));
		parameters.add(cellSize.set("cell size", 1.25, 0.0, 2.0));
		parameters.add(birthChance.set("birth chance", 0.5, 0, 1));
		parameters.add(birthVelocityChance.set("birth velocity chance", 0.5, 0, 1));
		parameters.add(lifeSpan.set("lifespan", 5, 0, 10));
		parameters.add(lifeSpanSpread.set("lifespan spread", .25, 0, 1));
		parameters.add(mass.set("mass", 1.3, 0, 2));
		parameters.add(massSpread.set("mass spread", .2, 0, 1));
		parameters.add(size.set("size", 2, 0, 10));
		parameters.add(sizeSpread.set("size spread", .75, 0, 1));
		parameters.add(twinkleSpeed.set("twinkle speed", 11, 0, 20));
		parameters.add(gravity.set("gravity", ofVec2f(0, 9.80665), ofVec2f(-10,-10), ofVec2f(10,10)));
	}

	void ftParticleFlow::setup(int _simulationWidth, int _simulationHeight, int _numParticlesX, int _numParticlesY) {
		simulationWidth = _simulationWidth;
		simulationHeight = _simulationHeight;
		numParticlesX = _numParticlesX;
		numParticlesY = _numParticlesY;
		numParticles = (numParticlesX * numParticlesY);

		particleMesh.setMode(OF_PRIMITIVE_POINTS);
		for(int x = 0; x < _numParticlesX; x++){
			for(int y = 0; y < _numParticlesY; y++){
				particleMesh.addVertex(ofVec3f(x,y));
				particleMesh.addTexCoord(ofVec2f(x, y));
			}
		}

		int internalFormatVelocity = GL_RG32F;

		ofPushStyle();
		ofEnableBlendMode(OF_BLENDMODE_DISABLED);  // Why?

		particleAgeLifespanMassSizeSwapBuffer.allocate(numParticlesX, numParticlesY, GL_RGBA32F, GL_NEAREST);
		particleAgeLifespanMassSizeSwapBuffer.black();
		particlePositionSwapBuffer.allocate(numParticlesX, numParticlesY, internalFormatVelocity, GL_NEAREST);
		particlePositionSwapBuffer.black();
		initPositionShader.update(*particlePositionSwapBuffer.getBuffer());
		particlePositionSwapBuffer.swap();
		particleHomeBuffer.allocate(numParticlesX, numParticlesY, internalFormatVelocity);
		particleHomeBuffer.black();
		initPositionShader.update(particleHomeBuffer);

		fluidVelocitySwapBuffer.allocate(simulationWidth, simulationHeight, internalFormatVelocity);
		fluidVelocitySwapBuffer.black();
		flowVelocitySwapBuffer.allocate(simulationWidth, simulationHeight, internalFormatVelocity);
		flowVelocitySwapBuffer.black();
		densitySwapBuffer.allocate(simulationWidth, simulationHeight, GL_RGBA32F);
		densitySwapBuffer.black();
		obstacleBuffer.allocate(simulationWidth, simulationHeight, GL_RGB); // GL_RED??
		obstacleBuffer.black();

		ofPopStyle();

	}

	void ftParticleFlow::update(float _deltaTime) {
		float time = ofGetElapsedTimef();
		if (_deltaTime != 0)
			deltaTime = _deltaTime;
		else
			deltaTime = time - lastTime;
		lastTime = time;
		timeStep = deltaTime * speed.get();

		if (bIsActive.get()) {

			ofPushStyle();
			ofEnableBlendMode(OF_BLENDMODE_DISABLED);

			ALMSParticleShader.update(*particleAgeLifespanMassSizeSwapBuffer.getBuffer(),
									   particleAgeLifespanMassSizeSwapBuffer.getBackTexture(),
									   particlePositionSwapBuffer.getBackTexture(),
									   flowVelocitySwapBuffer.getBackTexture(),
									   densitySwapBuffer.getBackTexture(),
									   obstacleBuffer.getTexture(),
									   deltaTime,
									   birthChance.get(),
									   birthVelocityChance.get(),
									   lifeSpan.get(), lifeSpanSpread.get(),
									   mass.get(), massSpread.get(),
									   size.get(), sizeSpread.get());
			particleAgeLifespanMassSizeSwapBuffer.swap();

			moveParticleShader.update(*particlePositionSwapBuffer.getBuffer(),
									  particlePositionSwapBuffer.getBackTexture(),
									  particleAgeLifespanMassSizeSwapBuffer.getBackTexture(),
									  fluidVelocitySwapBuffer.getBackTexture(),
									  particleHomeBuffer.getTexture(),
									  timeStep,
									  cellSize.get(),
									  gravity);
			particlePositionSwapBuffer.swap();

			ofPopStyle();

			flowVelocitySwapBuffer.black();
			fluidVelocitySwapBuffer.black();
			densitySwapBuffer.black();
			obstacleBuffer.black();
		}
	}

	void ftParticleFlow::draw(int _x, int _y, int _width, int _height) {
		ofPushView();
		ofTranslate(_x, _y);
		ofScale(_width / numParticlesX, _height / numParticlesY);
		drawParticleShader.update(particleMesh, numParticles, particlePositionSwapBuffer.getBackTexture(), particleAgeLifespanMassSizeSwapBuffer.getBackTexture(), twinkleSpeed.get());

		ofPopView();
	}

	void ftParticleFlow::addFlowVelocity(ofTexture & _tex, float _strength) {
		ofPushStyle();
		ofEnableBlendMode(OF_BLENDMODE_DISABLED);
		addShader.update(*flowVelocitySwapBuffer.getBuffer(),
						 flowVelocitySwapBuffer.getBackTexture(),
						 _tex,
						 _strength);
		flowVelocitySwapBuffer.swap();
		ofPopStyle();
	}

	void ftParticleFlow::addFluidVelocity (ofTexture& _tex, float _strength) {
		ofPushStyle();
		ofEnableBlendMode(OF_BLENDMODE_DISABLED);
		addShader.update(*fluidVelocitySwapBuffer.getBuffer(),
						 fluidVelocitySwapBuffer.getBackTexture(),
						 _tex,
						 _strength);
		fluidVelocitySwapBuffer.swap();
		ofPopStyle();
	}

	void ftParticleFlow::setObstacle (ofTexture& _tex) {
		ofPushStyle();
		ofEnableBlendMode(OF_BLENDMODE_DISABLED);
		obstacleBuffer.black();
		obstacleBuffer.begin();
		_tex.draw(0,0,simulationWidth,simulationHeight);
		obstacleBuffer.end();
		ofPopStyle();
	}
}<commit_msg>sensible swap<commit_after>/*  ************************************************************************************
 *
 *  ftParticleFlow
 *
 *  Created by Matthias Oostrik on 03/16.14.
 *  Copyright 2014 http://www.MatthiasOostrik.com All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the author nor the names of its contributors
 *       may be used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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 "ftParticleFlow.h"

namespace flowTools {

	ftParticleFlow::ftParticleFlow(){
		parameters.setName("particle flow");
		parameters.add(bIsActive.set("active", true));
		parameters.add(speed.set("speed", 20, 0, 100));
		parameters.add(cellSize.set("cell size", 1.25, 0.0, 2.0));
		parameters.add(birthChance.set("birth chance", 0.5, 0, 1));
		parameters.add(birthVelocityChance.set("birth velocity chance", 0.5, 0, 1));
		parameters.add(lifeSpan.set("lifespan", 5, 0, 10));
		parameters.add(lifeSpanSpread.set("lifespan spread", .25, 0, 1));
		parameters.add(mass.set("mass", 1.3, 0, 2));
		parameters.add(massSpread.set("mass spread", .2, 0, 1));
		parameters.add(size.set("size", 2, 0, 10));
		parameters.add(sizeSpread.set("size spread", .75, 0, 1));
		parameters.add(twinkleSpeed.set("twinkle speed", 11, 0, 20));
		parameters.add(gravity.set("gravity", ofVec2f(0, 9.80665), ofVec2f(-10,-10), ofVec2f(10,10)));
	}

	void ftParticleFlow::setup(int _simulationWidth, int _simulationHeight, int _numParticlesX, int _numParticlesY) {
		simulationWidth = _simulationWidth;
		simulationHeight = _simulationHeight;
		numParticlesX = _numParticlesX;
		numParticlesY = _numParticlesY;
		numParticles = (numParticlesX * numParticlesY);

		particleMesh.setMode(OF_PRIMITIVE_POINTS);
		for(int x = 0; x < _numParticlesX; x++){
			for(int y = 0; y < _numParticlesY; y++){
				particleMesh.addVertex(ofVec3f(x,y));
				particleMesh.addTexCoord(ofVec2f(x, y));
			}
		}

		int internalFormatVelocity = GL_RG32F;

		ofPushStyle();
		ofEnableBlendMode(OF_BLENDMODE_DISABLED);  // Why?

		particleAgeLifespanMassSizeSwapBuffer.allocate(numParticlesX, numParticlesY, GL_RGBA32F, GL_NEAREST);
		particleAgeLifespanMassSizeSwapBuffer.black();
		particlePositionSwapBuffer.allocate(numParticlesX, numParticlesY, internalFormatVelocity, GL_NEAREST);
		particlePositionSwapBuffer.black();
		initPositionShader.update(*particlePositionSwapBuffer.getBuffer());
		particlePositionSwapBuffer.swap();
		particleHomeBuffer.allocate(numParticlesX, numParticlesY, internalFormatVelocity);
		particleHomeBuffer.black();
		initPositionShader.update(particleHomeBuffer);

		fluidVelocitySwapBuffer.allocate(simulationWidth, simulationHeight, internalFormatVelocity);
		fluidVelocitySwapBuffer.black();
		flowVelocitySwapBuffer.allocate(simulationWidth, simulationHeight, internalFormatVelocity);
		flowVelocitySwapBuffer.black();
		densitySwapBuffer.allocate(simulationWidth, simulationHeight, GL_RGBA32F);
		densitySwapBuffer.black();
		obstacleBuffer.allocate(simulationWidth, simulationHeight, GL_RGB); // GL_RED??
		obstacleBuffer.black();

		ofPopStyle();

	}

	void ftParticleFlow::update(float _deltaTime) {
		float time = ofGetElapsedTimef();
		if (_deltaTime != 0)
			deltaTime = _deltaTime;
		else
			deltaTime = time - lastTime;
		lastTime = time;
		timeStep = deltaTime * speed.get();

		if (bIsActive.get()) {

			ofPushStyle();
			ofEnableBlendMode(OF_BLENDMODE_DISABLED);

			particleAgeLifespanMassSizeSwapBuffer.swap();
			ALMSParticleShader.update(*particleAgeLifespanMassSizeSwapBuffer.getBuffer(),
									   particleAgeLifespanMassSizeSwapBuffer.getBackTexture(),
									   particlePositionSwapBuffer.getTexture(),
									   flowVelocitySwapBuffer.getTexture(),
									   densitySwapBuffer.getTexture(),
									   obstacleBuffer.getTexture(),
									   deltaTime,
									   birthChance.get(),
									   birthVelocityChance.get(),
									   lifeSpan.get(), lifeSpanSpread.get(),
									   mass.get(), massSpread.get(),
									   size.get(), sizeSpread.get());

			particlePositionSwapBuffer.swap();
			moveParticleShader.update(*particlePositionSwapBuffer.getBuffer(),
									  particlePositionSwapBuffer.getBackTexture(),
									  particleAgeLifespanMassSizeSwapBuffer.getTexture(),
									  fluidVelocitySwapBuffer.getTexture(),
									  particleHomeBuffer.getTexture(),
									  timeStep,
									  cellSize.get(),
									  gravity);

			ofPopStyle();

			flowVelocitySwapBuffer.black();
			fluidVelocitySwapBuffer.black();
			densitySwapBuffer.black();
			obstacleBuffer.black();
		}
	}

	void ftParticleFlow::draw(int _x, int _y, int _width, int _height) {
		ofPushView();
		ofTranslate(_x, _y);
		ofScale(_width / numParticlesX, _height / numParticlesY);
		drawParticleShader.update(particleMesh, numParticles, particlePositionSwapBuffer.getTexture(), particleAgeLifespanMassSizeSwapBuffer.getTexture(), twinkleSpeed.get());

		ofPopView();
	}

	void ftParticleFlow::addFlowVelocity(ofTexture & _tex, float _strength) {
		ofPushStyle();
		ofEnableBlendMode(OF_BLENDMODE_DISABLED);
		flowVelocitySwapBuffer.swap();
		addShader.update(*flowVelocitySwapBuffer.getBuffer(),
						 flowVelocitySwapBuffer.getBackTexture(),
						 _tex,
						 _strength);
		ofPopStyle();
	}

	void ftParticleFlow::addFluidVelocity (ofTexture& _tex, float _strength) {
		ofPushStyle();
		ofEnableBlendMode(OF_BLENDMODE_DISABLED);
		fluidVelocitySwapBuffer.swap();
		addShader.update(*fluidVelocitySwapBuffer.getBuffer(),
						 fluidVelocitySwapBuffer.getBackTexture(),
						 _tex,
						 _strength);
		ofPopStyle();
	}

	void ftParticleFlow::setObstacle (ofTexture& _tex) {
		ofPushStyle();
		ofEnableBlendMode(OF_BLENDMODE_DISABLED);
		obstacleBuffer.black();
		obstacleBuffer.begin();
		_tex.draw(0,0,simulationWidth,simulationHeight);
		obstacleBuffer.end();
		ofPopStyle();
	}
}<|endoftext|>


<commit_before>#include <algorithm>
#include <cassert>
#include <cmath>

#include "hlstrafe.hpp"
#include "util.hpp"

namespace HLStrafe
{
	double MaxAccelTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed)
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= 0.0)
			return M_PI;

		double wishspeed_capped = onground ? wishspeed : 30;
		double tmp = wishspeed_capped - accelspeed;
		if (tmp <= 0.0)
			return M_PI / 2;

		double speed = Length<float, 2>(player.Velocity);
		if (tmp < speed)
			return std::acos(tmp / speed);

		return 0.0;
	}

	double MaxAccelIntoYawTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, double vel_yaw, double yaw)
	{
		assert(postype != PositionType::WATER);

		if (!IsZero<float, 2>(player.Velocity))
			vel_yaw = std::atan2(player.Velocity[1], player.Velocity[0]);

		double theta = MaxAccelTheta(player, vars, postype, wishspeed);
		if (theta == 0.0 || theta == M_PI)
			return NormalizeRad(yaw - vel_yaw + theta);
		return std::copysign(theta, NormalizeRad(yaw - vel_yaw));
	}

	double MaxAngleTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed)
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double speed = Length<float, 2>(player.Velocity);
		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= 0.0) {
			double wishspeed_capped = onground ? wishspeed : 30;
			accelspeed *= -1;
			if (accelspeed >= speed) {
				if (wishspeed_capped >= speed)
					return 0.0;
				else
					return std::acos(wishspeed_capped / speed); // The actual angle needs to be _less_ than this.
			} else {
				if (wishspeed_capped >= speed)
					return std::acos(accelspeed / speed);
				else
					return std::acos(std::min(accelspeed, wishspeed_capped) / speed); // The actual angle needs to be _less_ than this if wishspeed_capped <= accelspeed.
			}
		} else {
			if (accelspeed >= speed)
				return M_PI;
			else
				return std::acos(-1 * accelspeed / speed);
		}
	}

	void VectorFME(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, const double a[2])
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double wishspeed_capped = onground ? wishspeed : 30;
		double tmp = wishspeed_capped - DotProduct<float, double, 2>(player.Velocity, a);
		if (tmp <= 0.0)
			return;

		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= tmp)
			tmp = accelspeed;

		player.Velocity[0] += a[0] * tmp;
		player.Velocity[1] += a[1] * tmp;
	}

	inline double ButtonsPhi(HLTAS::Button button)
	{
		switch (button) {
		case HLTAS::Button::      FORWARD: return 0;
		case HLTAS::Button:: FORWARD_LEFT: return -M_PI / 4;
		case HLTAS::Button::         LEFT: return -M_PI / 2;
		case HLTAS::Button::    BACK_LEFT: return -3 * M_PI / 2;
		case HLTAS::Button::         BACK: return M_PI;
		case HLTAS::Button::   BACK_RIGHT: return 3 * M_PI / 2;
		case HLTAS::Button::        RIGHT: return M_PI / 2;
		case HLTAS::Button::FORWARD_RIGHT: return M_PI / 4;
		default: return 0;
		}
	}

	static void SideStrafeGeneral(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed,
		HLTAS::Button buttons, double vel_yaw, double theta, bool right, bool safeguard_yaw, float velocities[2][2], double yaws[2])
	{
		assert(postype != PositionType::WATER);

		double phi = ButtonsPhi(buttons);
		phi = right ? phi : -phi;
		theta = right ? theta : -theta;

		if (!IsZero<float, 2>(player.Velocity))
			vel_yaw = std::atan2(player.Velocity[1], player.Velocity[0]);

		double yaw = vel_yaw + phi - theta;
		yaws[0] = AngleModRad(yaw);
		// Very rare case of yaw == anglemod(yaw).
		if (yaws[0] == yaw) {
			// Multiply by 1.5 because the fp precision might make the yaw a value not enough to reach the next anglemod.
			// Or divide by 2 because it might throw us a value too far back.
			yaws[1] = AngleModRad(yaw + std::copysign(M_U_RAD * 1.5, yaw));

			// We need to handle this when we may have yaw equal to the speed change boundary.
			if (safeguard_yaw)
				yaws[0] = AngleModRad(yaw - std::copysign(M_U_RAD / 2, yaw));
		} else
			yaws[1] = AngleModRad(yaw + std::copysign(M_U_RAD, yaw));

		double avec[2] = { std::cos(yaws[0] - phi), std::sin(yaws[0] - phi) };
		PlayerData pl = player;
		VectorFME(pl, vars, postype, wishspeed, avec);
		VecCopy<float, 2>(pl.Velocity, velocities[0]);

		avec[0] = std::cos(yaws[1] - phi);
		avec[1] = std::sin(yaws[1] - phi);
		VecCopy<float, 2>(player.Velocity, pl.Velocity);
		VectorFME(pl, vars, postype, wishspeed, avec);
		VecCopy<float, 2>(pl.Velocity, velocities[1]);
	}

	double SideStrafeMaxAccel(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, HLTAS::Button buttons,
		double vel_yaw, bool right)
	{
		assert(postype != PositionType::WATER);

		double theta = MaxAccelTheta(player, vars, postype, wishspeed);
		float velocities[2][2];
		double yaws[2];
		SideStrafeGeneral(player, vars, postype, wishspeed, buttons, vel_yaw, theta, right, false, velocities, yaws);

		double speedsqrs[2] = {
			DotProduct<float, float, 2>(velocities[0], velocities[0]),
			DotProduct<float, float, 2>(velocities[1], velocities[1])
		};

		if (speedsqrs[0] > speedsqrs[1]) {
			VecCopy<float, 2>(velocities[0], player.Velocity);
			return yaws[0];
		} else {
			VecCopy<float, 2>(velocities[1], player.Velocity);
			return yaws[1];
		}
	}

	double BestStrafeMaxAccel(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, HLTAS::Button buttons,
		double vel_yaw)
	{
		assert(postype != PositionType::WATER);

		float temp_vel[2], orig_vel[2];
		double yaws[2];
		VecCopy<float, 2>(player.Velocity, orig_vel);
		yaws[0] = SideStrafeMaxAccel(player, vars, postype, wishspeed, buttons, vel_yaw, false);
		VecCopy<float, 2>(player.Velocity, temp_vel);
		VecCopy<float, 2>(orig_vel, player.Velocity);
		yaws[1] = SideStrafeMaxAccel(player, vars, postype, wishspeed, buttons, vel_yaw, true);

		double speedsqrs[2] = {
			DotProduct<float, float, 2>(temp_vel, temp_vel),
			DotProduct<float, float, 2>(player.Velocity, player.Velocity)
		};

		if (speedsqrs[0] > speedsqrs[1]) {
			VecCopy<float, 2>(temp_vel, player.Velocity);
			return yaws[0];
		} else
			return yaws[1];
	}
}
<commit_msg>Angle sign consistency.<commit_after>#include <algorithm>
#include <cassert>
#include <cmath>

#include "hlstrafe.hpp"
#include "util.hpp"

namespace HLStrafe
{
	double MaxAccelTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed)
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= 0.0)
			return M_PI;

		double wishspeed_capped = onground ? wishspeed : 30;
		double tmp = wishspeed_capped - accelspeed;
		if (tmp <= 0.0)
			return M_PI / 2;

		double speed = Length<float, 2>(player.Velocity);
		if (tmp < speed)
			return std::acos(tmp / speed);

		return 0.0;
	}

	double MaxAccelIntoYawTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, double vel_yaw, double yaw)
	{
		assert(postype != PositionType::WATER);

		if (!IsZero<float, 2>(player.Velocity))
			vel_yaw = std::atan2(player.Velocity[1], player.Velocity[0]);

		double theta = MaxAccelTheta(player, vars, postype, wishspeed);
		if (theta == 0.0 || theta == M_PI)
			return NormalizeRad(yaw - vel_yaw + theta);
		return std::copysign(theta, NormalizeRad(yaw - vel_yaw));
	}

	double MaxAngleTheta(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed)
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double speed = Length<float, 2>(player.Velocity);
		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= 0.0) {
			double wishspeed_capped = onground ? wishspeed : 30;
			accelspeed *= -1;
			if (accelspeed >= speed) {
				if (wishspeed_capped >= speed)
					return 0.0;
				else
					return std::acos(wishspeed_capped / speed); // The actual angle needs to be _less_ than this.
			} else {
				if (wishspeed_capped >= speed)
					return std::acos(accelspeed / speed);
				else
					return std::acos(std::min(accelspeed, wishspeed_capped) / speed); // The actual angle needs to be _less_ than this if wishspeed_capped <= accelspeed.
			}
		} else {
			if (accelspeed >= speed)
				return M_PI;
			else
				return std::acos(-1 * accelspeed / speed);
		}
	}

	void VectorFME(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, const double a[2])
	{
		assert(postype != PositionType::WATER);

		bool onground = (postype == PositionType::GROUND);
		double wishspeed_capped = onground ? wishspeed : 30;
		double tmp = wishspeed_capped - DotProduct<float, double, 2>(player.Velocity, a);
		if (tmp <= 0.0)
			return;

		double accel = onground ? vars.Accelerate : vars.Airaccelerate;
		double accelspeed = accel * wishspeed * vars.EntFriction * vars.Frametime;
		if (accelspeed <= tmp)
			tmp = accelspeed;

		player.Velocity[0] += a[0] * tmp;
		player.Velocity[1] += a[1] * tmp;
	}

	inline double ButtonsPhi(HLTAS::Button button)
	{
		switch (button) {
		case HLTAS::Button::      FORWARD: return 0;
		case HLTAS::Button:: FORWARD_LEFT: return M_PI / 4;
		case HLTAS::Button::         LEFT: return M_PI / 2;
		case HLTAS::Button::    BACK_LEFT: return 3 * M_PI / 2;
		case HLTAS::Button::         BACK: return -M_PI;
		case HLTAS::Button::   BACK_RIGHT: return -3 * M_PI / 2;
		case HLTAS::Button::        RIGHT: return -M_PI / 2;
		case HLTAS::Button::FORWARD_RIGHT: return -M_PI / 4;
		default: return 0;
		}
	}

	static void SideStrafeGeneral(const PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed,
		HLTAS::Button buttons, double vel_yaw, double theta, bool right, bool safeguard_yaw, float velocities[2][2], double yaws[2])
	{
		assert(postype != PositionType::WATER);

		double phi = ButtonsPhi(buttons);
		phi = right ? -phi : phi;
		theta = right ? -theta : theta;

		if (!IsZero<float, 2>(player.Velocity))
			vel_yaw = std::atan2(player.Velocity[1], player.Velocity[0]);

		double yaw = vel_yaw + phi + theta;
		yaws[0] = AngleModRad(yaw);
		// Very rare case of yaw == anglemod(yaw).
		if (yaws[0] == yaw) {
			// Multiply by 1.5 because the fp precision might make the yaw a value not enough to reach the next anglemod.
			// Or divide by 2 because it might throw us a value too far back.
			yaws[1] = AngleModRad(yaw + std::copysign(M_U_RAD * 1.5, yaw));

			// We need to handle this when we may have yaw equal to the speed change boundary.
			if (safeguard_yaw)
				yaws[0] = AngleModRad(yaw - std::copysign(M_U_RAD / 2, yaw));
		} else
			yaws[1] = AngleModRad(yaw + std::copysign(M_U_RAD, yaw));

		double avec[2] = { std::cos(yaws[0] - phi), std::sin(yaws[0] - phi) };
		PlayerData pl = player;
		VectorFME(pl, vars, postype, wishspeed, avec);
		VecCopy<float, 2>(pl.Velocity, velocities[0]);

		avec[0] = std::cos(yaws[1] - phi);
		avec[1] = std::sin(yaws[1] - phi);
		VecCopy<float, 2>(player.Velocity, pl.Velocity);
		VectorFME(pl, vars, postype, wishspeed, avec);
		VecCopy<float, 2>(pl.Velocity, velocities[1]);
	}

	double SideStrafeMaxAccel(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, HLTAS::Button buttons,
		double vel_yaw, bool right)
	{
		assert(postype != PositionType::WATER);

		double theta = MaxAccelTheta(player, vars, postype, wishspeed);
		float velocities[2][2];
		double yaws[2];
		SideStrafeGeneral(player, vars, postype, wishspeed, buttons, vel_yaw, theta, right, false, velocities, yaws);

		double speedsqrs[2] = {
			DotProduct<float, float, 2>(velocities[0], velocities[0]),
			DotProduct<float, float, 2>(velocities[1], velocities[1])
		};

		if (speedsqrs[0] > speedsqrs[1]) {
			VecCopy<float, 2>(velocities[0], player.Velocity);
			return yaws[0];
		} else {
			VecCopy<float, 2>(velocities[1], player.Velocity);
			return yaws[1];
		}
	}

	double BestStrafeMaxAccel(PlayerData& player, const MovementVars& vars, PositionType postype, double wishspeed, HLTAS::Button buttons,
		double vel_yaw)
	{
		assert(postype != PositionType::WATER);

		float temp_vel[2], orig_vel[2];
		double yaws[2];
		VecCopy<float, 2>(player.Velocity, orig_vel);
		yaws[0] = SideStrafeMaxAccel(player, vars, postype, wishspeed, buttons, vel_yaw, false);
		VecCopy<float, 2>(player.Velocity, temp_vel);
		VecCopy<float, 2>(orig_vel, player.Velocity);
		yaws[1] = SideStrafeMaxAccel(player, vars, postype, wishspeed, buttons, vel_yaw, true);

		double speedsqrs[2] = {
			DotProduct<float, float, 2>(temp_vel, temp_vel),
			DotProduct<float, float, 2>(player.Velocity, player.Velocity)
		};

		if (speedsqrs[0] > speedsqrs[1]) {
			VecCopy<float, 2>(temp_vel, player.Velocity);
			return yaws[0];
		} else
			return yaws[1];
	}
}
<|endoftext|>


<commit_before>#include <QuickTime/QuickTime.h>
#include "MacMedia.h"

static SndCallBackUPP gCarbonSndCallBackUPP = nil;
static int queued_chunks = 0;

static pascal void callbackProc (SndChannelPtr theChannel, SndCommand * theCallBackCmd)
{
 //   dprintf("!");
  queued_chunks--;
}

MacMedia::MacMedia() {
  gCarbonSndCallBackUPP = NewSndCallBackUPP (callbackProc);
}

MacMedia::~MacMedia() {}

double MacMedia::stopwatch(bool start) { return 0; }

void   MacMedia::sleep(float   secs ) {}

// Audio

#define CHUNK_SIZE  (1024 * 4)
#define BUFFER_SIZE (CHUNK_SIZE * 8)

bool MacMedia::openAudio() {
  buffer = new SInt16 [BUFFER_SIZE];
  rpos = wpos = buffer;

  // Return false if SoundManager is not at least version 3.3
  //NumVersionVariant version;
  //version.parts = SndSoundManagerVersion();

  //if (version.whole < 0x03300000)
  //  return false;

  // callback = NewSndCallBackProc ( callbackProc );
  channel = new SndChannel;
  channel->userInfo = 0;
  channel->qLength  = 128;
  error = SndNewChannel (&channel, sampledSynth, initStereo, callback);

  if (error != noErr)
    return false;

  header.numChannels   = 2;
  header.sampleRate    = rate22050hz;
  header.encode        = extSH;
  header.sampleSize    = 16;
  header.numFrames     = CHUNK_SIZE;

  num_samples = CHUNK_SIZE * 2;

  return true;
}

void    MacMedia::closeAudio() {
  if (channel)
    SndDisposeChannel (channel, true);

  if (buffer)
    free(buffer);
}

bool MacMedia::isAudioBrainDead() const {
  return false;
}

bool MacMedia::startAudioThread(void (*proc)(void*), void* data) {
  audio_proc = proc;

  audio_proc(NULL);

  return true;
}

void    MacMedia::stopAudioThread() {}

bool MacMedia::hasAudioThread() const {
  return false;
}

bool MacMedia::isAudioTooEmpty () const {
  return queued_chunks <= 20;
}

void MacMedia::writeAudio(void) {
  OSErr iErr = noErr;
  SndCommand                        playCmd;
  SndCommand                        callBack;

  header.samplePtr = (char*)buffer;

  playCmd.cmd = bufferCmd;
  playCmd.param1 = 0;          // unused
  playCmd.param2 = (long)&header;

  callBack.cmd = callBackCmd;
  callBack.param1 = 0;          // which buffer to fill, 0 buffer, 1, 0, ...

  channel->callBack = gCarbonSndCallBackUPP;

  iErr = SndDoCommand (channel, &playCmd, true);
  if (noErr != iErr)
    return;

  queued_chunks++;

  iErr = SndDoCommand(channel, &callBack, true);
  if (noErr != iErr)
    return;
}

void    MacMedia::writeAudioFrames(const float *samples, int numFrames)
{
  int numSamples = 2 * numFrames;
  while (numSamples > BUFFER_SIZE)
  {
    for (int j = 0; j < BUFFER_SIZE; j++)
      if (samples[j] < -32767.0f) buffer[j] = -32767;
      else if (samples[j] > 32767.0f) buffer[j] = 32767;
      else buffer[j] = short(samples[j]);
    writeAudio();
    samples += BUFFER_SIZE;
    numSamples -= BUFFER_SIZE;
  }

  if (numSamples > 0) {
    for (int j = 0; j < numSamples; j++)
      if (samples[j] < -32767.0f)
	buffer[j] = -32767;
      else if (samples[j] > 32767.0f)
	buffer[j] = 32767;
      else
	buffer[j] = short(samples[j]);
    writeAudio();
  }
}

void MacMedia::writeSoundCommand(const void *data, int length) {
  char *temp = new char[length];
  memcpy(temp, data, length);
  command_queue.push(temp);
}

bool MacMedia::readSoundCommand  (void *data, int length) {
  if (!command_queue.empty()) {
    char *temp = command_queue.front();
    memcpy (data, temp, length);
    command_queue.pop();
    free(temp);
    return true;
  }
  else
    return false;
}

int     MacMedia::getAudioOutputRate() const {
  return 22050;
}

int     MacMedia::getAudioBufferSize() const {
  return BUFFER_SIZE;
}

int     MacMedia::getAudioBufferChunkSize() const {
  return CHUNK_SIZE;
}

void    MacMedia::audioSleep(bool checkLowWater, double maxTime) {

}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>mac finds some rusted code.  don't free new'd memory.  delete it.<commit_after>#include <QuickTime/QuickTime.h>
#include "MacMedia.h"

static SndCallBackUPP gCarbonSndCallBackUPP = nil;
static int queued_chunks = 0;

static pascal void callbackProc (SndChannelPtr theChannel, SndCommand * theCallBackCmd)
{
 //   dprintf("!");
  queued_chunks--;
}

MacMedia::MacMedia() {
  gCarbonSndCallBackUPP = NewSndCallBackUPP (callbackProc);
}

MacMedia::~MacMedia() {}

double MacMedia::stopwatch(bool start) { return 0; }

void   MacMedia::sleep(float   secs ) {}

// Audio

#define CHUNK_SIZE  (1024 * 4)
#define BUFFER_SIZE (CHUNK_SIZE * 8)

bool MacMedia::openAudio() {
  buffer = new SInt16 [BUFFER_SIZE];
  rpos = wpos = buffer;

  // Return false if SoundManager is not at least version 3.3
  //NumVersionVariant version;
  //version.parts = SndSoundManagerVersion();

  //if (version.whole < 0x03300000)
  //  return false;

  // callback = NewSndCallBackProc ( callbackProc );
  channel = new SndChannel;
  channel->userInfo = 0;
  channel->qLength  = 128;
  error = SndNewChannel (&channel, sampledSynth, initStereo, callback);

  if (error != noErr)
    return false;

  header.numChannels   = 2;
  header.sampleRate    = rate22050hz;
  header.encode        = extSH;
  header.sampleSize    = 16;
  header.numFrames     = CHUNK_SIZE;

  num_samples = CHUNK_SIZE * 2;

  return true;
}

void    MacMedia::closeAudio() {
  if (channel)
    SndDisposeChannel (channel, true);

  if (buffer)
    delete buffer;
  buffer = (SInt16*)NULL;
}

bool MacMedia::isAudioBrainDead() const {
  return false;
}

bool MacMedia::startAudioThread(void (*proc)(void*), void* data) {
  audio_proc = proc;

  audio_proc(NULL);

  return true;
}

void    MacMedia::stopAudioThread() {}

bool MacMedia::hasAudioThread() const {
  return false;
}

bool MacMedia::isAudioTooEmpty () const {
  return queued_chunks <= 20;
}

void MacMedia::writeAudio(void) {
  OSErr iErr = noErr;
  SndCommand                        playCmd;
  SndCommand                        callBack;

  header.samplePtr = (char*)buffer;

  playCmd.cmd = bufferCmd;
  playCmd.param1 = 0;          // unused
  playCmd.param2 = (long)&header;

  callBack.cmd = callBackCmd;
  callBack.param1 = 0;          // which buffer to fill, 0 buffer, 1, 0, ...

  channel->callBack = gCarbonSndCallBackUPP;

  iErr = SndDoCommand (channel, &playCmd, true);
  if (noErr != iErr)
    return;

  queued_chunks++;

  iErr = SndDoCommand(channel, &callBack, true);
  if (noErr != iErr)
    return;
}

void    MacMedia::writeAudioFrames(const float *samples, int numFrames)
{
  int numSamples = 2 * numFrames;
  while (numSamples > BUFFER_SIZE)
  {
    for (int j = 0; j < BUFFER_SIZE; j++)
      if (samples[j] < -32767.0f) buffer[j] = -32767;
      else if (samples[j] > 32767.0f) buffer[j] = 32767;
      else buffer[j] = short(samples[j]);
    writeAudio();
    samples += BUFFER_SIZE;
    numSamples -= BUFFER_SIZE;
  }

  if (numSamples > 0) {
    for (int j = 0; j < numSamples; j++)
      if (samples[j] < -32767.0f)
	buffer[j] = -32767;
      else if (samples[j] > 32767.0f)
	buffer[j] = 32767;
      else
	buffer[j] = short(samples[j]);
    writeAudio();
  }
}

void MacMedia::writeSoundCommand(const void *data, int length) {
  char *temp = new char[length];
  memcpy(temp, data, length);
  command_queue.push(temp);
}

bool MacMedia::readSoundCommand  (void *data, int length) {
  if (!command_queue.empty()) {
    char *temp = command_queue.front();
    memcpy (data, temp, length);
    command_queue.pop();
    delete temp;
    temp = (char*)NULL;
    return true;
  }
  else
    return false;
}

int     MacMedia::getAudioOutputRate() const {
  return 22050;
}

int     MacMedia::getAudioBufferSize() const {
  return BUFFER_SIZE;
}

int     MacMedia::getAudioBufferChunkSize() const {
  return CHUNK_SIZE;
}

void    MacMedia::audioSleep(bool checkLowWater, double maxTime) {

}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>#include "cdp_lua_functions.h"

#include <vector>
#include <string>

#include "lua.hpp"

#include "AltarThread.h"

using namespace std;

//Same as cdp() but doesn't block
//unimplemented, sorry bozo
static int cdpPar( lua_State * L )
	{
	return 0;
	}

//Lua function used for calling arbitrary cdp modules
static int lua_cdp( lua_State * L )
	{
	string fullCommand;

	//Lambda function for getting and checking strings from the lua stack
	auto getLuaString = [ &L ]( int index, const char * error )
		{
		const char * s = lua_tostring( L, index );
		if( s == nullptr ) luaL_error( L, error );
		return string( s );
		};

	//Get the module name and cdp directory, form the complete exe string and copy to fullCommand
	{
	string exe = getLuaString( 1, "Module name sent to cdp is not a valid string" );
	lua_getglobal( L, "cdpDir" );
	fullCommand = getLuaString( -1, "cdpDir given in lua script is not a valid string" ) + exe + string( ".exe" );
	lua_pop( L, 1 );
	}

	//Get remaining arguments from the lua stack
	{
	int argCount = lua_gettop( L ) - 1;
	for( int i = 0; i < argCount; ++i )
		{
		//+2 accounting for lua indices starting at one and the first stack entry being the module name
		fullCommand += " " + getLuaString( i + 2, "Unknown argument passed to cdp is not a valid string" );
		}
	}

	//Get the directory to put files in.
	//We could generate files in the OS temp dir but if something breaks we need access
	lua_getglobal( L, "workingDir" );
	string workingDir = getLuaString( -1, "workingDir given in lua script is not a valid string" );
	lua_pop( L, 1 );

	vector<string> outFiles;
	if( ! static_cast<AltarThread *>( Thread::getCurrentThread() )->cdp( fullCommand, workingDir, outFiles ) )

		luaL_error( L, "Exiting lua: error from CDP" );

	for( int i = 0; i < outFiles.size(); ++i )
		{
		lua_pushstring( L, outFiles[i].c_str() );
		}

	return outFiles.size();
	}

//Normalize infile to given level
static int lua_cdp_normalize( lua_State * L )
	{
	//Normalize is in the modify module
	lua_pushstring( L, "modify" );
	lua_insert( L, 1 );
	//loudness 3 = normalize
	lua_pushstring( L, "loudness 3" );
	lua_insert( L, 2 );
	//Push in a token for output file
	lua_pushstring( L, "$" );

	//Stack: "modify" | "loudness 3" | infile | volume? | "$"

	//If no volume was sent there are now 4 elements on the stack, set the volume to .9
	if( lua_gettop( L ) == 4 ) lua_pushstring( L, "-l0.9" );
	else
		{ //volume was sent, change it from number to string
		double volume = lua_tonumber( L, 4 );
		string volumeString = "-l" + to_string( volume );
		lua_pushstring( L, volumeString.c_str() );
		lua_insert( L, -2 );
		}

	return lua_cdp( L );
	}

void registerCdpLuaFunctions( lua_State * L )
	{
	lua_register( L, "cdp", lua_cdp );
	lua_register( L, "cdp_normalize", lua_cdp_normalize );
	}<commit_msg>Delete cdp_lua_functions.cpp<commit_after><|endoftext|>


<commit_before>/*
Type support for generic simulation cell class.

Copyright 2014 Ilja Honkonen
All rights reserved.

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

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

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

* Neither the name of copyright holders nor the names of their contributors
  may be used to endorse or promote products derived from this software
  without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.
*/

#ifndef GENSIMCELL_TYPE_SUPPORT_HPP
#define GENSIMCELL_TYPE_SUPPORT_HPP

#include "type_traits"

namespace gensimcell {

/*!
Indicates whether has been given a generic simulation cell class.

Derives from std::true_type if given a generic simulation cell class
as template parameter, otherwise derives from std::false_type.
*/
template <class... T> struct is_gensimcell : std::false_type {};

//! std::true_type version of is_gensimcell.
template <
	template<template<class> class Transfer_Policy, class... Variables> class Cell,
	template<class> class Transfer_Policy,
	class... Variables
> struct is_gensimcell<Cell<Transfer_Policy, Variables...>> : std::true_type {};

} // namespace gensimcell

#endif // ifndef GENSIMCELL_TYPE_SUPPORT_HPP
<commit_msg>Adjust code formatting in type_support.hpp.<commit_after>/*
Type support for generic simulation cell class.

Copyright 2014 Ilja Honkonen
All rights reserved.

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

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

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

* Neither the name of copyright holders nor the names of their contributors
  may be used to endorse or promote products derived from this software
  without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.
*/

#ifndef GENSIMCELL_TYPE_SUPPORT_HPP
#define GENSIMCELL_TYPE_SUPPORT_HPP

#include "type_traits"

namespace gensimcell {

/*!
Indicates whether has been given a generic simulation cell class.

Derives from std::true_type if given a generic simulation cell class
as template parameter, otherwise derives from std::false_type.
*/
template <class... T> struct is_gensimcell : std::false_type {};

//! std::true_type version of is_gensimcell.
template <
	template<
		template<class> class Transfer_Policy,
		class... Variables
	> class Cell,
	template<class> class Transfer_Policy,
	class... Variables
> struct is_gensimcell<Cell<Transfer_Policy, Variables...>> : std::true_type {};

} // namespace gensimcell

#endif // ifndef GENSIMCELL_TYPE_SUPPORT_HPP
<|endoftext|>


<commit_before>#include "Iop_SubSystem.h"
#include "../MemoryStateFile.h"
#include "../Ps2Const.h"
#include "../Log.h"
#include "placeholder_def.h"

using namespace Iop;
using namespace PS2;

#define LOG_NAME ("iop_subsystem")

#define STATE_CPU		("iop_cpu")
#define STATE_RAM		("iop_ram")
#define STATE_SCRATCH	("iop_scratch")

CSubSystem::CSubSystem(bool ps2Mode)
: m_cpu(MEMORYMAP_ENDIAN_LSBF)
, m_executor(m_cpu, (IOP_RAM_SIZE * 4))
, m_ram(new uint8[IOP_RAM_SIZE])
, m_scratchPad(new uint8[IOP_SCRATCH_SIZE])
, m_spuRam(new uint8[SPU_RAM_SIZE])
, m_dmac(m_ram, m_intc)
, m_counters(ps2Mode ? IOP_CLOCK_OVER_FREQ : IOP_CLOCK_BASE_FREQ, m_intc)
, m_spuCore0(m_spuRam, SPU_RAM_SIZE, 0)
, m_spuCore1(m_spuRam, SPU_RAM_SIZE, 1)
, m_spu(m_spuCore0)
, m_spu2(m_spuCore0, m_spuCore1)
#ifdef _IOP_EMULATE_MODULES
, m_sio2(m_intc)
#endif
, m_cpuArch(MIPS_REGSIZE_32)
, m_copScu(MIPS_REGSIZE_32)
, m_dmaUpdateTicks(0)
{
	//Read memory map
	m_cpu.m_pMemoryMap->InsertReadMap((0 * IOP_RAM_SIZE), (0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,														0x01);
	m_cpu.m_pMemoryMap->InsertReadMap((1 * IOP_RAM_SIZE), (1 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,														0x02);
	m_cpu.m_pMemoryMap->InsertReadMap((2 * IOP_RAM_SIZE), (2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,														0x03);
	m_cpu.m_pMemoryMap->InsertReadMap((3 * IOP_RAM_SIZE), (3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,														0x04);
	m_cpu.m_pMemoryMap->InsertReadMap(0x1F800000,					0x1F8003FF,						m_scratchPad,												0x05);
	m_cpu.m_pMemoryMap->InsertReadMap(HW_REG_BEGIN,					HW_REG_END,						std::bind(&CSubSystem::ReadIoRegister, this, std::placeholders::_1),		0x06);

	//Write memory map
	m_cpu.m_pMemoryMap->InsertWriteMap((0 * IOP_RAM_SIZE),		(0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,																			0x01);
	m_cpu.m_pMemoryMap->InsertWriteMap((1 * IOP_RAM_SIZE),		(1 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,																			0x02);
	m_cpu.m_pMemoryMap->InsertWriteMap((2 * IOP_RAM_SIZE),		(2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,																			0x03);
	m_cpu.m_pMemoryMap->InsertWriteMap((3 * IOP_RAM_SIZE),		(3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,																			0x04);
	m_cpu.m_pMemoryMap->InsertWriteMap(0x1F800000,		0x1F8003FF,									m_scratchPad,																	0x05);
	m_cpu.m_pMemoryMap->InsertWriteMap(HW_REG_BEGIN,	HW_REG_END,									std::bind(&CSubSystem::WriteIoRegister, this, std::placeholders::_1, std::placeholders::_2),		0x06);

	//Instruction memory map
	m_cpu.m_pMemoryMap->InsertInstructionMap((0 * IOP_RAM_SIZE), (0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,						0x01);
	m_cpu.m_pMemoryMap->InsertInstructionMap((1 * IOP_RAM_SIZE), (1 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,						0x02);
	m_cpu.m_pMemoryMap->InsertInstructionMap((2 * IOP_RAM_SIZE), (2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,						0x03);
	m_cpu.m_pMemoryMap->InsertInstructionMap((3 * IOP_RAM_SIZE), (3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,						0x04);

	m_cpu.m_pArch = &m_cpuArch;
	m_cpu.m_pCOP[0] = &m_copScu;
	m_cpu.m_pAddrTranslator = &CMIPS::TranslateAddress64;

	m_dmac.SetReceiveFunction(4, bind(&CSpuBase::ReceiveDma, &m_spuCore0, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3));
	m_dmac.SetReceiveFunction(8, bind(&CSpuBase::ReceiveDma, &m_spuCore1, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3));
}

CSubSystem::~CSubSystem()
{
	m_bios.reset();
	delete [] m_ram;
	delete [] m_scratchPad;
	delete [] m_spuRam;
}

void CSubSystem::SetBios(const BiosBasePtr& bios)
{
	m_bios = bios;
}

void CSubSystem::NotifyVBlankStart()
{
	m_bios->NotifyVBlankStart();
	m_intc.AssertLine(Iop::CIntc::LINE_VBLANK);
}

void CSubSystem::NotifyVBlankEnd()
{
	m_bios->NotifyVBlankEnd();
	m_intc.AssertLine(Iop::CIntc::LINE_EVBLANK);
}

void CSubSystem::SaveState(Framework::CZipArchiveWriter& archive)
{
	archive.InsertFile(new CMemoryStateFile(STATE_CPU,		&m_cpu.m_State, sizeof(MIPSSTATE)));
	archive.InsertFile(new CMemoryStateFile(STATE_RAM,		m_ram,			IOP_RAM_SIZE));
	archive.InsertFile(new CMemoryStateFile(STATE_SCRATCH,	m_scratchPad,	IOP_SCRATCH_SIZE));
	m_intc.SaveState(archive);
	m_spuCore0.SaveState(archive);
	m_spuCore1.SaveState(archive);
	m_bios->SaveState(archive);
}

void CSubSystem::LoadState(Framework::CZipArchiveReader& archive)
{
	archive.BeginReadFile(STATE_CPU			)->Read(&m_cpu.m_State,	sizeof(MIPSSTATE));
	archive.BeginReadFile(STATE_RAM			)->Read(m_ram,			IOP_RAM_SIZE);
	archive.BeginReadFile(STATE_SCRATCH		)->Read(m_scratchPad,	IOP_SCRATCH_SIZE);
	m_intc.LoadState(archive);
	m_spuCore0.LoadState(archive);
	m_spuCore1.LoadState(archive);
	m_bios->LoadState(archive);
}

void CSubSystem::Reset()
{
	memset(m_ram, 0, IOP_RAM_SIZE);
	memset(m_scratchPad, 0, IOP_SCRATCH_SIZE);
	memset(m_spuRam, 0, SPU_RAM_SIZE);
	m_executor.Reset();
	m_cpu.Reset();
	m_cpu.m_pAnalysis->Clear();
	m_spuCore0.Reset();
	m_spuCore1.Reset();
	m_spu.Reset();
	m_spu2.Reset();
#ifdef _IOP_EMULATE_MODULES
	m_sio2.Reset();
#endif
	m_counters.Reset();
	m_dmac.Reset();
	m_intc.Reset();
	m_bios.reset();

	m_cpu.m_Comments.RemoveTags();
	m_cpu.m_Functions.RemoveTags();

	m_dmaUpdateTicks = 0;
}

uint32 CSubSystem::ReadIoRegister(uint32 address)
{
	if(address == 0x1F801814)
	{
		return 0x14802000;
	}
	else if(address >= CSpu::SPU_BEGIN && address <= CSpu::SPU_END)
	{
		return m_spu.ReadRegister(address);
	}
	else if(address >= CDmac::DMAC_ZONE1_START && address <= CDmac::DMAC_ZONE1_END)
	{
		return m_dmac.ReadRegister(address);
	}
	else if(address >= CDmac::DMAC_ZONE2_START && address <= CDmac::DMAC_ZONE2_END)
	{
		return m_dmac.ReadRegister(address);
	}
	else if(address >= CIntc::ADDR_BEGIN && address <= CIntc::ADDR_END)
	{
		return m_intc.ReadRegister(address);
	}
	else if(
		(address >= CRootCounters::ADDR_BEGIN1 && address <= CRootCounters::ADDR_END1) ||
		(address >= CRootCounters::ADDR_BEGIN2 && address <= CRootCounters::ADDR_END2)
		)
	{
		return m_counters.ReadRegister(address);
	}
#ifdef _IOP_EMULATE_MODULES
	else if(address >= CSio2::ADDR_BEGIN && address <= CSio2::ADDR_END)
	{
		return m_sio2.ReadRegister(address);
	}
#endif
	else if(address >= CSpu2::REGS_BEGIN && address <= CSpu2::REGS_END)
	{
		return m_spu2.ReadRegister(address);
	}
	else if(address >= 0x1F808400 && address <= 0x1F808500)
	{
		//iLink (aka Firewire) stuff
		return 0x08;
	}
	else
	{
		CLog::GetInstance().Print(LOG_NAME, "Reading an unknown hardware register (0x%0.8X).\r\n", address);
	}
	return 0;
}

uint32 CSubSystem::WriteIoRegister(uint32 address, uint32 value)
{
	if(address >= CDmac::DMAC_ZONE1_START && address <= CDmac::DMAC_ZONE1_END)
	{
		m_dmac.WriteRegister(address, value);
	}
	else if(address >= CSpu::SPU_BEGIN && address <= CSpu::SPU_END)
	{
		m_spu.WriteRegister(address, static_cast<uint16>(value));
	}
	else if(address >= CDmac::DMAC_ZONE2_START && address <= CDmac::DMAC_ZONE2_END)
	{
		m_dmac.WriteRegister(address, value);
	}
	else if(address >= CIntc::ADDR_BEGIN && address <= CIntc::ADDR_END)
	{
		m_intc.WriteRegister(address, value);
	}
	else if(
		(address >= CRootCounters::ADDR_BEGIN1 && address <= CRootCounters::ADDR_END1) ||
		(address >= CRootCounters::ADDR_BEGIN2 && address <= CRootCounters::ADDR_END2)
		)
	{
		m_counters.WriteRegister(address, value);
	}
#ifdef _IOP_EMULATE_MODULES
	else if(address >= CSio2::ADDR_BEGIN && address <= CSio2::ADDR_END)
	{
		m_sio2.WriteRegister(address, value);
	}
#endif
	else if(address >= CSpu2::REGS_BEGIN && address <= CSpu2::REGS_END)
	{
		return m_spu2.WriteRegister(address, value);
	}
	else
	{
		CLog::GetInstance().Print(LOG_NAME, "Writing to an unknown hardware register (0x%0.8X, 0x%0.8X).\r\n", address, value);
	}
	return 0;
}

bool CSubSystem::IsCpuIdle()
{
	if(m_bios->IsIdle())
	{
		return true;
	}
	else
	{
		uint32 physicalPc = m_cpu.m_pAddrTranslator(&m_cpu, m_cpu.m_State.nPC);
		CBasicBlock* nextBlock = m_executor.FindBlockAt(physicalPc);
		if(nextBlock && nextBlock->GetSelfLoopCount() > 5000)
		{
			//Go a little bit faster if we're "stuck"
			return true;
		}
	}
	return false;
}

void CSubSystem::CountTicks(int ticks)
{
	m_counters.Update(ticks);
	m_bios->CountTicks(ticks);
	m_dmaUpdateTicks += ticks;
	if(m_dmaUpdateTicks >= 100)
	{
		m_dmac.ResumeDma(4);
		m_dmac.ResumeDma(8);
		m_dmaUpdateTicks -= 100;
	}
}

int CSubSystem::ExecuteCpu(int quota)
{
	int executed = 0;
	if(!m_cpu.m_State.nHasException)
	{
		if(m_intc.HasPendingInterrupt())
		{
			m_bios->HandleInterrupt();
		}
	}
	if(!m_cpu.m_State.nHasException)
	{
		executed = (quota - m_executor.Execute(quota));
	}
	if(m_cpu.m_State.nHasException)
	{
		m_bios->HandleException();
	}
	return executed;
}
<commit_msg>Increased the DMA update delay in Iop::CSubSystem to prevent interrupt spam. (was preventing Xenosaga 2 from booting)<commit_after>#include "Iop_SubSystem.h"
#include "../MemoryStateFile.h"
#include "../Ps2Const.h"
#include "../Log.h"
#include "placeholder_def.h"

using namespace Iop;
using namespace PS2;

#define LOG_NAME ("iop_subsystem")

#define STATE_CPU		("iop_cpu")
#define STATE_RAM		("iop_ram")
#define STATE_SCRATCH	("iop_scratch")

CSubSystem::CSubSystem(bool ps2Mode)
: m_cpu(MEMORYMAP_ENDIAN_LSBF)
, m_executor(m_cpu, (IOP_RAM_SIZE * 4))
, m_ram(new uint8[IOP_RAM_SIZE])
, m_scratchPad(new uint8[IOP_SCRATCH_SIZE])
, m_spuRam(new uint8[SPU_RAM_SIZE])
, m_dmac(m_ram, m_intc)
, m_counters(ps2Mode ? IOP_CLOCK_OVER_FREQ : IOP_CLOCK_BASE_FREQ, m_intc)
, m_spuCore0(m_spuRam, SPU_RAM_SIZE, 0)
, m_spuCore1(m_spuRam, SPU_RAM_SIZE, 1)
, m_spu(m_spuCore0)
, m_spu2(m_spuCore0, m_spuCore1)
#ifdef _IOP_EMULATE_MODULES
, m_sio2(m_intc)
#endif
, m_cpuArch(MIPS_REGSIZE_32)
, m_copScu(MIPS_REGSIZE_32)
, m_dmaUpdateTicks(0)
{
	//Read memory map
	m_cpu.m_pMemoryMap->InsertReadMap((0 * IOP_RAM_SIZE), (0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,														0x01);
	m_cpu.m_pMemoryMap->InsertReadMap((1 * IOP_RAM_SIZE), (1 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,														0x02);
	m_cpu.m_pMemoryMap->InsertReadMap((2 * IOP_RAM_SIZE), (2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,														0x03);
	m_cpu.m_pMemoryMap->InsertReadMap((3 * IOP_RAM_SIZE), (3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,														0x04);
	m_cpu.m_pMemoryMap->InsertReadMap(0x1F800000,					0x1F8003FF,						m_scratchPad,												0x05);
	m_cpu.m_pMemoryMap->InsertReadMap(HW_REG_BEGIN,					HW_REG_END,						std::bind(&CSubSystem::ReadIoRegister, this, std::placeholders::_1),		0x06);

	//Write memory map
	m_cpu.m_pMemoryMap->InsertWriteMap((0 * IOP_RAM_SIZE),		(0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,																			0x01);
	m_cpu.m_pMemoryMap->InsertWriteMap((1 * IOP_RAM_SIZE),		(1 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,																			0x02);
	m_cpu.m_pMemoryMap->InsertWriteMap((2 * IOP_RAM_SIZE),		(2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,																			0x03);
	m_cpu.m_pMemoryMap->InsertWriteMap((3 * IOP_RAM_SIZE),		(3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,																			0x04);
	m_cpu.m_pMemoryMap->InsertWriteMap(0x1F800000,		0x1F8003FF,									m_scratchPad,																	0x05);
	m_cpu.m_pMemoryMap->InsertWriteMap(HW_REG_BEGIN,	HW_REG_END,									std::bind(&CSubSystem::WriteIoRegister, this, std::placeholders::_1, std::placeholders::_2),		0x06);

	//Instruction memory map
	m_cpu.m_pMemoryMap->InsertInstructionMap((0 * IOP_RAM_SIZE), (0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,						0x01);
	m_cpu.m_pMemoryMap->InsertInstructionMap((1 * IOP_RAM_SIZE), (1 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,						0x02);
	m_cpu.m_pMemoryMap->InsertInstructionMap((2 * IOP_RAM_SIZE), (2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,						0x03);
	m_cpu.m_pMemoryMap->InsertInstructionMap((3 * IOP_RAM_SIZE), (3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1,	m_ram,						0x04);

	m_cpu.m_pArch = &m_cpuArch;
	m_cpu.m_pCOP[0] = &m_copScu;
	m_cpu.m_pAddrTranslator = &CMIPS::TranslateAddress64;

	m_dmac.SetReceiveFunction(4, bind(&CSpuBase::ReceiveDma, &m_spuCore0, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3));
	m_dmac.SetReceiveFunction(8, bind(&CSpuBase::ReceiveDma, &m_spuCore1, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3));
}

CSubSystem::~CSubSystem()
{
	m_bios.reset();
	delete [] m_ram;
	delete [] m_scratchPad;
	delete [] m_spuRam;
}

void CSubSystem::SetBios(const BiosBasePtr& bios)
{
	m_bios = bios;
}

void CSubSystem::NotifyVBlankStart()
{
	m_bios->NotifyVBlankStart();
	m_intc.AssertLine(Iop::CIntc::LINE_VBLANK);
}

void CSubSystem::NotifyVBlankEnd()
{
	m_bios->NotifyVBlankEnd();
	m_intc.AssertLine(Iop::CIntc::LINE_EVBLANK);
}

void CSubSystem::SaveState(Framework::CZipArchiveWriter& archive)
{
	archive.InsertFile(new CMemoryStateFile(STATE_CPU,		&m_cpu.m_State, sizeof(MIPSSTATE)));
	archive.InsertFile(new CMemoryStateFile(STATE_RAM,		m_ram,			IOP_RAM_SIZE));
	archive.InsertFile(new CMemoryStateFile(STATE_SCRATCH,	m_scratchPad,	IOP_SCRATCH_SIZE));
	m_intc.SaveState(archive);
	m_spuCore0.SaveState(archive);
	m_spuCore1.SaveState(archive);
	m_bios->SaveState(archive);
}

void CSubSystem::LoadState(Framework::CZipArchiveReader& archive)
{
	archive.BeginReadFile(STATE_CPU			)->Read(&m_cpu.m_State,	sizeof(MIPSSTATE));
	archive.BeginReadFile(STATE_RAM			)->Read(m_ram,			IOP_RAM_SIZE);
	archive.BeginReadFile(STATE_SCRATCH		)->Read(m_scratchPad,	IOP_SCRATCH_SIZE);
	m_intc.LoadState(archive);
	m_spuCore0.LoadState(archive);
	m_spuCore1.LoadState(archive);
	m_bios->LoadState(archive);
}

void CSubSystem::Reset()
{
	memset(m_ram, 0, IOP_RAM_SIZE);
	memset(m_scratchPad, 0, IOP_SCRATCH_SIZE);
	memset(m_spuRam, 0, SPU_RAM_SIZE);
	m_executor.Reset();
	m_cpu.Reset();
	m_cpu.m_pAnalysis->Clear();
	m_spuCore0.Reset();
	m_spuCore1.Reset();
	m_spu.Reset();
	m_spu2.Reset();
#ifdef _IOP_EMULATE_MODULES
	m_sio2.Reset();
#endif
	m_counters.Reset();
	m_dmac.Reset();
	m_intc.Reset();
	m_bios.reset();

	m_cpu.m_Comments.RemoveTags();
	m_cpu.m_Functions.RemoveTags();

	m_dmaUpdateTicks = 0;
}

uint32 CSubSystem::ReadIoRegister(uint32 address)
{
	if(address == 0x1F801814)
	{
		return 0x14802000;
	}
	else if(address >= CSpu::SPU_BEGIN && address <= CSpu::SPU_END)
	{
		return m_spu.ReadRegister(address);
	}
	else if(address >= CDmac::DMAC_ZONE1_START && address <= CDmac::DMAC_ZONE1_END)
	{
		return m_dmac.ReadRegister(address);
	}
	else if(address >= CDmac::DMAC_ZONE2_START && address <= CDmac::DMAC_ZONE2_END)
	{
		return m_dmac.ReadRegister(address);
	}
	else if(address >= CIntc::ADDR_BEGIN && address <= CIntc::ADDR_END)
	{
		return m_intc.ReadRegister(address);
	}
	else if(
		(address >= CRootCounters::ADDR_BEGIN1 && address <= CRootCounters::ADDR_END1) ||
		(address >= CRootCounters::ADDR_BEGIN2 && address <= CRootCounters::ADDR_END2)
		)
	{
		return m_counters.ReadRegister(address);
	}
#ifdef _IOP_EMULATE_MODULES
	else if(address >= CSio2::ADDR_BEGIN && address <= CSio2::ADDR_END)
	{
		return m_sio2.ReadRegister(address);
	}
#endif
	else if(address >= CSpu2::REGS_BEGIN && address <= CSpu2::REGS_END)
	{
		return m_spu2.ReadRegister(address);
	}
	else if(address >= 0x1F808400 && address <= 0x1F808500)
	{
		//iLink (aka Firewire) stuff
		return 0x08;
	}
	else
	{
		CLog::GetInstance().Print(LOG_NAME, "Reading an unknown hardware register (0x%0.8X).\r\n", address);
	}
	return 0;
}

uint32 CSubSystem::WriteIoRegister(uint32 address, uint32 value)
{
	if(address >= CDmac::DMAC_ZONE1_START && address <= CDmac::DMAC_ZONE1_END)
	{
		m_dmac.WriteRegister(address, value);
	}
	else if(address >= CSpu::SPU_BEGIN && address <= CSpu::SPU_END)
	{
		m_spu.WriteRegister(address, static_cast<uint16>(value));
	}
	else if(address >= CDmac::DMAC_ZONE2_START && address <= CDmac::DMAC_ZONE2_END)
	{
		m_dmac.WriteRegister(address, value);
	}
	else if(address >= CIntc::ADDR_BEGIN && address <= CIntc::ADDR_END)
	{
		m_intc.WriteRegister(address, value);
	}
	else if(
		(address >= CRootCounters::ADDR_BEGIN1 && address <= CRootCounters::ADDR_END1) ||
		(address >= CRootCounters::ADDR_BEGIN2 && address <= CRootCounters::ADDR_END2)
		)
	{
		m_counters.WriteRegister(address, value);
	}
#ifdef _IOP_EMULATE_MODULES
	else if(address >= CSio2::ADDR_BEGIN && address <= CSio2::ADDR_END)
	{
		m_sio2.WriteRegister(address, value);
	}
#endif
	else if(address >= CSpu2::REGS_BEGIN && address <= CSpu2::REGS_END)
	{
		return m_spu2.WriteRegister(address, value);
	}
	else
	{
		CLog::GetInstance().Print(LOG_NAME, "Writing to an unknown hardware register (0x%0.8X, 0x%0.8X).\r\n", address, value);
	}
	return 0;
}

bool CSubSystem::IsCpuIdle()
{
	if(m_bios->IsIdle())
	{
		return true;
	}
	else
	{
		uint32 physicalPc = m_cpu.m_pAddrTranslator(&m_cpu, m_cpu.m_State.nPC);
		CBasicBlock* nextBlock = m_executor.FindBlockAt(physicalPc);
		if(nextBlock && nextBlock->GetSelfLoopCount() > 5000)
		{
			//Go a little bit faster if we're "stuck"
			return true;
		}
	}
	return false;
}

void CSubSystem::CountTicks(int ticks)
{
	static int g_dmaUpdateDelay = 10000;
	m_counters.Update(ticks);
	m_bios->CountTicks(ticks);
	m_dmaUpdateTicks += ticks;
	if(m_dmaUpdateTicks >= g_dmaUpdateDelay)
	{
		m_dmac.ResumeDma(4);
		m_dmac.ResumeDma(8);
		m_dmaUpdateTicks -= g_dmaUpdateDelay;
	}
}

int CSubSystem::ExecuteCpu(int quota)
{
	int executed = 0;
	if(!m_cpu.m_State.nHasException)
	{
		if(m_intc.HasPendingInterrupt())
		{
			m_bios->HandleInterrupt();
		}
	}
	if(!m_cpu.m_State.nHasException)
	{
		executed = (quota - m_executor.Execute(quota));
	}
	if(m_cpu.m_State.nHasException)
	{
		m_bios->HandleException();
	}
	return executed;
}
<|endoftext|>


<commit_before>/*************************************************************************
> File Name: GameAgent.cpp
> Project Name: Hearthstone++
> Author: Young-Joong Kim
> Purpose: Hearthstone Game Agent
> Created Time: 2017/09/26
> Copyright (c) 2017, Young-Joong Kim
*************************************************************************/
#include <Agents/GameAgent.h>
#include <Tasks/BasicTask.h>
#include <Tasks/MetaData.h>

#include <random>

namespace Hearthstonepp
{
std::thread GameAgent::StartAgent()
{
    auto flow = [this]() {
        BeginPhase();
        while (true)
        {
            bool isGameEnd = MainPhase();
            if (isGameEnd)
            {
                break;
            }
        }

        FinalPhase();
    };

    return std::thread(std::move(flow));
}

void GameAgent::GetTaskMeta(TaskMeta& meta)
{
    m_taskAgent.Read(meta);
}

void GameAgent::WriteSyncBuffer(TaskMeta&& data, bool sideChannel)
{
    m_taskAgent.Notify(std::move(data), sideChannel);
}

void GameAgent::BeginPhase()
{
    std::random_device rd;
    std::default_random_engine gen(rd());

    // get random number, zero or one.
    std::uniform_int_distribution<int> bin(0, 1);
    // swap user with 50% probability
    if (bin(gen) == 1)
    {
        m_taskAgent.Add(BasicTask::SwapUserTask());
    }

    auto untilMulliganSuccess = [](const TaskMeta& serialized) {
        return serialized.status == MetaData::MULLIGAN_SUCCESS;
    };

    // BeginPhase Task List
    m_taskAgent.Add(BasicTask::UserSettingTask());
    m_taskAgent.Add(BasicTask::DoBothUser(BasicTask::ShuffleTask()));
    m_taskAgent.Add(BasicTask::DoBothUser(BasicTask::DrawTask(NUM_BEGIN_DRAW)));
    m_taskAgent.Add(BasicTask::BriefTask());
    m_taskAgent.Add(BasicTask::DoUntil(BasicTask::MulliganTask(m_taskAgent),
                                       untilMulliganSuccess));
    m_taskAgent.Add(BasicTask::SwapUserTask());
    m_taskAgent.Add(BasicTask::BriefTask());
    m_taskAgent.Add(BasicTask::DoUntil(BasicTask::MulliganTask(m_taskAgent),
                                       untilMulliganSuccess));
    m_taskAgent.Add(BasicTask::SwapUserTask());

    TaskMeta meta;
    m_taskAgent.Run(meta, m_current, m_opponent);
    m_taskAgent.Clear();

    // TODO: Coin for later user
    m_opponent.hand.push_back(new Card());
}

bool GameAgent::MainPhase()
{
    // Ready for main phase
    MainReady();
    // MainMenu return isGameEnd flag
    return MainMenu();
}

void GameAgent::FinalPhase()
{
    TaskMeta meta;
    m_taskAgent.Run(BasicTask::GameEndTask(), meta, m_current, m_opponent);
}

void GameAgent::MainReady()
{
    // MainReady : Draw, ModifyMana, Clear vector `attacked`
    m_taskAgent.Add(BasicTask::DrawTask(1));
    m_taskAgent.Add(BasicTask::ModifyManaTask(BasicTask::NUM_ADD,
                                              BasicTask::MANA_TOTAL, 1));
    m_taskAgent.Add(BasicTask::ModifyManaByRef(
        BasicTask::NUM_SYNC, BasicTask::MANA_EXIST, m_current.totalMana));

    TaskMeta meta;
    m_taskAgent.Run(meta, m_current, m_opponent);
    m_taskAgent.Clear();

    m_current.attacked.clear();
}

bool GameAgent::MainMenu()
{
    // Check before starting main phase
    if (IsGameEnd())
    {
        return true;
    }

    TaskMeta meta;
    m_taskAgent.Run(BasicTask::BriefTask(), meta, m_current, m_opponent);
    m_taskAgent.Run(BasicTask::SelectMenuTask(m_taskAgent), meta, m_current, m_opponent);

    // Interface pass menu by status of TaskMeta
    TaskMeta::status_t menu = meta.status;

    if (menu == GAME_MAIN_MENU_SIZE - 1)
    {
        // Main End phase
        m_taskAgent.Run(BasicTask::SwapUserTask(), meta, m_current, m_opponent);
    }
    else
    {
        if (menu >= 0 && menu < GAME_MAIN_MENU_SIZE - 1)
        {
            // call action method
            m_mainMenuFuncs[menu](*this);
        }
        // Recursion
        return MainMenu();
    }

    return false;
}

void GameAgent::MainUseCard()
{
    // Read what kinds of card user wants to use
    TaskMeta meta;
    m_taskAgent.Run(BasicTask::SelectCardTask(m_taskAgent), meta, m_current, m_opponent);

    if (meta.status == MetaData::SELECT_CARD_MINION)
    {
        using Require = FlatData::RequireSummonMinionTaskMeta;
        const auto& buffer = meta.GetConstBuffer();
        auto minion = flatbuffers::GetRoot<Require>(buffer.get());

        m_taskAgent.Run(BasicTask::SummonMinionTask(minion->cardIndex(),
                                                    minion->position()),
                        meta, m_current, m_opponent);
    }
    else
    {
        // TODO : If else selected card is not minion
    }
}

void GameAgent::MainCombat()
{
    TaskMeta meta;
    m_taskAgent.Run(BasicTask::SelectTargetTask(m_taskAgent), meta, m_current,
                    m_opponent);

    using Require = FlatData::RequireTargetingTaskMeta;
    const auto& buffer = meta.GetConstBuffer();
    auto targeting = flatbuffers::GetRoot<Require>(buffer.get());

    m_taskAgent.Run(BasicTask::CombatTask(targeting->src(), targeting->dst()),
                    meta, m_current, m_opponent);
}

bool GameAgent::IsGameEnd()
{
    int healthCurrent = m_current.hero->GetHealth();
    int healthOpponent = m_opponent.hero->GetHealth();

    if (healthCurrent < 1 || healthOpponent < 1)
    {
        return true;
    }
    else
    {
        return false;
    }
}
}  // namespace Hearthstonepp<commit_msg>[ci skip] Update GameAgent - Fix type conversion warning<commit_after>/*************************************************************************
> File Name: GameAgent.cpp
> Project Name: Hearthstone++
> Author: Young-Joong Kim
> Purpose: Hearthstone Game Agent
> Created Time: 2017/09/26
> Copyright (c) 2017, Young-Joong Kim
*************************************************************************/
#include <Agents/GameAgent.h>
#include <Tasks/BasicTask.h>
#include <Tasks/MetaData.h>

#include <random>

namespace Hearthstonepp
{
std::thread GameAgent::StartAgent()
{
    auto flow = [this]() {
        BeginPhase();
        while (true)
        {
            bool isGameEnd = MainPhase();
            if (isGameEnd)
            {
                break;
            }
        }

        FinalPhase();
    };

    return std::thread(std::move(flow));
}

void GameAgent::GetTaskMeta(TaskMeta& meta)
{
    m_taskAgent.Read(meta);
}

void GameAgent::WriteSyncBuffer(TaskMeta&& data, bool sideChannel)
{
    m_taskAgent.Notify(std::move(data), sideChannel);
}

void GameAgent::BeginPhase()
{
    std::random_device rd;
    std::default_random_engine gen(rd());

    // get random number, zero or one.
    std::uniform_int_distribution<int> bin(0, 1);
    // swap user with 50% probability
    if (bin(gen) == 1)
    {
        m_taskAgent.Add(BasicTask::SwapUserTask());
    }

    auto untilMulliganSuccess = [](const TaskMeta& serialized) {
        return serialized.status == MetaData::MULLIGAN_SUCCESS;
    };

    // BeginPhase Task List
    m_taskAgent.Add(BasicTask::UserSettingTask());
    m_taskAgent.Add(BasicTask::DoBothUser(BasicTask::ShuffleTask()));
    m_taskAgent.Add(BasicTask::DoBothUser(BasicTask::DrawTask(NUM_BEGIN_DRAW)));
    m_taskAgent.Add(BasicTask::BriefTask());
    m_taskAgent.Add(BasicTask::DoUntil(BasicTask::MulliganTask(m_taskAgent),
                                       untilMulliganSuccess));
    m_taskAgent.Add(BasicTask::SwapUserTask());
    m_taskAgent.Add(BasicTask::BriefTask());
    m_taskAgent.Add(BasicTask::DoUntil(BasicTask::MulliganTask(m_taskAgent),
                                       untilMulliganSuccess));
    m_taskAgent.Add(BasicTask::SwapUserTask());

    TaskMeta meta;
    m_taskAgent.Run(meta, m_current, m_opponent);
    m_taskAgent.Clear();

    // TODO: Coin for later user
    m_opponent.hand.push_back(new Card());
}

bool GameAgent::MainPhase()
{
    // Ready for main phase
    MainReady();
    // MainMenu return isGameEnd flag
    return MainMenu();
}

void GameAgent::FinalPhase()
{
    TaskMeta meta;
    m_taskAgent.Run(BasicTask::GameEndTask(), meta, m_current, m_opponent);
}

void GameAgent::MainReady()
{
    // MainReady : Draw, ModifyMana, Clear vector `attacked`
    m_taskAgent.Add(BasicTask::DrawTask(1));
    m_taskAgent.Add(BasicTask::ModifyManaTask(BasicTask::NUM_ADD,
                                              BasicTask::MANA_TOTAL, 1));
    m_taskAgent.Add(BasicTask::ModifyManaByRef(
        BasicTask::NUM_SYNC, BasicTask::MANA_EXIST, m_current.totalMana));

    TaskMeta meta;
    m_taskAgent.Run(meta, m_current, m_opponent);
    m_taskAgent.Clear();

    m_current.attacked.clear();
}

bool GameAgent::MainMenu()
{
    // Check before starting main phase
    if (IsGameEnd())
    {
        return true;
    }

    TaskMeta meta;
    m_taskAgent.Run(BasicTask::BriefTask(), meta, m_current, m_opponent);
    m_taskAgent.Run(BasicTask::SelectMenuTask(m_taskAgent), meta, m_current, m_opponent);

    // Interface pass menu by status of TaskMeta
    TaskMeta::status_t menu = meta.status;

    if (menu == GAME_MAIN_MENU_SIZE - 1)
    {
        // Main End phase
        m_taskAgent.Run(BasicTask::SwapUserTask(), meta, m_current, m_opponent);
    }
    else
    {
        if (menu >= 0 && menu < GAME_MAIN_MENU_SIZE - 1)
        {
            // call action method
            m_mainMenuFuncs[menu](*this);
        }
        // Recursion
        return MainMenu();
    }

    return false;
}

void GameAgent::MainUseCard()
{
    // Read what kinds of card user wants to use
    TaskMeta meta;
    m_taskAgent.Run(BasicTask::SelectCardTask(m_taskAgent), meta, m_current, m_opponent);

    if (meta.status == MetaData::SELECT_CARD_MINION)
    {
        using Require = FlatData::RequireSummonMinionTaskMeta;
        const auto& buffer = meta.GetConstBuffer();
        auto minion = flatbuffers::GetRoot<Require>(buffer.get());

        m_taskAgent.Run(BasicTask::SummonMinionTask(minion->cardIndex(),
                                                    minion->position()),
                        meta, m_current, m_opponent);
    }
    else
    {
        // TODO : If else selected card is not minion
    }
}

void GameAgent::MainCombat()
{
    TaskMeta meta;
    m_taskAgent.Run(BasicTask::SelectTargetTask(m_taskAgent), meta, m_current,
                    m_opponent);

    using Require = FlatData::RequireTargetingTaskMeta;
    const auto& buffer = meta.GetConstBuffer();
    auto targeting = flatbuffers::GetRoot<Require>(buffer.get());

    m_taskAgent.Run(BasicTask::CombatTask(targeting->src(), targeting->dst()),
                    meta, m_current, m_opponent);
}

bool GameAgent::IsGameEnd()
{
    int healthCurrent = static_cast<int>(m_current.hero->GetHealth());
    int healthOpponent = static_cast<int>(m_opponent.hero->GetHealth());

    if (healthCurrent < 1 || healthOpponent < 1)
    {
        return true;
    }
    else
    {
        return false;
    }
}
}  // namespace Hearthstonepp<|endoftext|>


<commit_before>/*
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2007 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */
/**
 * $Id: projectM.hpp,v 1.1.1.1 2005/12/23 18:05:11 psperl Exp $
 *
 * Encapsulation of ProjectM engine
 *
 * $Log$
 */

#ifndef _PROJECTM_H
#define _PROJECTM_H

#ifdef WIN32
#include "win32-dirent.h"
#else
#include <dirent.h>
#endif /** WIN32 */
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <sys/types.h>

#ifdef MACOS
#include <MacWindows.h>
#include <gl.h>
#include <glu.h>
#else
#ifdef WIN32
#include <windows.h>
#endif /** WIN32 */

#endif /** MACOS */
#ifdef WIN322
#define inline
#endif /** WIN32 */
#ifndef WIN32
#include <sys/time.h>
#else
#endif /** !WIN32 */

#include "dlldefs.h"
#include "event.h"
#include "fatal.h"
#include "PresetFrameIO.hpp"

#include <memory>

class BeatDetect;
class Func;
class Renderer;
class Preset;
class PresetIterator;
class PresetChooser;
class PresetLoader;
class MoodBar;
//class PresetInputs;
//class PresetOutputs;

#include <memory>
#ifdef WIN32
#pragma warning (disable:4244)
#pragma warning (disable:4305)
#endif /** WIN32 */

#ifdef MACOS2
#define inline
#endif

/** KEEP THIS UP TO DATE! */
#define PROJECTM_VERSION "1.00.00"
#define PROJECTM_TITLE "projectM 1.00.00"

/** Thread state */
typedef enum { GO, STOP } PMThreadState;

/** Interface types */
typedef enum {
    MENU_INTERFACE,
    SHELL_INTERFACE,
    EDITOR_INTERFACE,
    DEFAULT_INTERFACE,
    BROWSER_INTERFACE
  } interface_t;

class projectM
{
public:

  BeatDetect * beatDetect;

  /* PER_FRAME CONSTANTS END */

  /** Functions */

  DLLEXPORT projectM(std::string config_file);
  DLLEXPORT projectM(int gx, int gy, int fps, int texsize, int width, int height,std::string preset_url,std::string title_fonturl, std::string title_menuurl);

  DLLEXPORT void projectM_resetGL( int width, int height );
  DLLEXPORT void projectM_setTitle( std::string title );
  DLLEXPORT void renderFrame();
  DLLEXPORT unsigned initRenderToTexture();
  DLLEXPORT void key_handler( projectMEvent event,
		    projectMKeycode keycode, projectMModifier modifier );

  ~projectM();

private:
 Renderer *renderer;
  std::string presetURL;

  std::string title_fontURL;
  std::string menu_fontURL;

  int smoothFrame;

#ifndef WIN32
  /* The first ticks value of the application */
  struct timeval startTime;
#else
  long startTime;
#endif /** !WIN32 */

  int wvw;      //windowed dimensions
  int wvh;

  int avgtime;  //# frames per preset

  /** Timing information */
  int mspf;
  int timed;
  int timestart;
  int nohard;
  int count;
  float fpsstart;

  void readConfig(std::string config_file);
  void projectM_init(int gx, int gy, int fps, int texsize, int width, int height);
  void projectM_reset();

  void projectM_initengine();
  void projectM_resetengine();
  /// Initializes preset loading / management libraries
  int initPresetTools();

  /// Deinitialize all preset related tools. Usually done before projectM cleanup
  void destroyPresetTools();
  void default_key_handler( projectMEvent event, projectMKeycode keycode );
  // The current position of the directory iterator
  PresetIterator * m_presetPos;

  // Required by the preset chooser. Manages a loaded preset directory
  PresetLoader * m_presetLoader;

  // Provides accessor functions to choose presets
  PresetChooser * m_presetChooser;

  // Currently loaded preset
  std::auto_ptr<Preset> m_activePreset;

  // Destination preset when smooth preset switching
  std::auto_ptr<Preset> m_activePreset2;

  /// Experimental mood bar instance. May or may not make it into 1.0 release
  MoodBar * moodBar;

  /// All readonly variables which are passed as inputs to presets
  PresetInputs presetInputs;

  /// A preset outputs container used and modified by the "current" preset
  PresetOutputs presetOutputs;

  /// A preset outputs container used for smooth preset switching
  PresetOutputs presetOutputs2;
};
#endif
<commit_msg>more header cleanup<commit_after>/*
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2007 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */
/**
 * $Id: projectM.hpp,v 1.1.1.1 2005/12/23 18:05:11 psperl Exp $
 *
 * Encapsulation of ProjectM engine
 *
 * $Log$
 */

#ifndef _PROJECTM_H
#define _PROJECTM_H

#ifdef WIN32
#include "win32-dirent.h"
#else
#include <dirent.h>
#endif /** WIN32 */
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <sys/types.h>

#ifdef MACOS
#include <MacWindows.h>
#include <gl.h>
#include <glu.h>
#else
#ifdef WIN32
#include <windows.h>
#endif /** WIN32 */

#endif /** MACOS */
#ifdef WIN322
#define inline
#endif /** WIN32 */
#ifndef WIN32
#include <sys/time.h>
#else
#endif /** !WIN32 */

#include "dlldefs.h"
#include "event.h"
#include "fatal.h"
#include "PresetFrameIO.hpp"

#include <memory>

class BeatDetect;
class Func;
class Renderer;
class Preset;
class PresetIterator;
class PresetChooser;
class PresetLoader;
class MoodBar;
//class PresetInputs;
//class PresetOutputs;

#include <memory>
#ifdef WIN32
#pragma warning (disable:4244)
#pragma warning (disable:4305)
#endif /** WIN32 */

#ifdef MACOS2
#define inline
#endif

/** KEEP THIS UP TO DATE! */
#define PROJECTM_VERSION "1.00.00"
#define PROJECTM_TITLE "projectM 1.00.00"

/** Interface types */
typedef enum {
    MENU_INTERFACE,
    SHELL_INTERFACE,
    EDITOR_INTERFACE,
    DEFAULT_INTERFACE,
    BROWSER_INTERFACE
  } interface_t;

class projectM
{
public:

  BeatDetect * beatDetect;

  DLLEXPORT projectM(std::string config_file);
  DLLEXPORT projectM(int gx, int gy, int fps, int texsize, int width, int height,std::string preset_url,std::string title_fonturl, std::string title_menuurl);

  DLLEXPORT void projectM_resetGL( int width, int height );
  DLLEXPORT void projectM_setTitle( std::string title );
  DLLEXPORT void renderFrame();
  DLLEXPORT unsigned initRenderToTexture();
  DLLEXPORT void key_handler( projectMEvent event,
		    projectMKeycode keycode, projectMModifier modifier );

  ~projectM();

private:
  Renderer *renderer;
  std::string presetURL;

  std::string title_fontURL;
  std::string menu_fontURL;

  int smoothFrame;

#ifndef WIN32
  /* The first ticks value of the application */
  struct timeval startTime;
#else
  long startTime;
#endif /** !WIN32 */

  int wvw;      //windowed dimensions
  int wvh;

  int avgtime;  //# frames per preset

  /** Timing information */
  int mspf;
  int timed;
  int timestart;
  int nohard;
  int count;
  float fpsstart;

  void readConfig(std::string config_file);
  void projectM_init(int gx, int gy, int fps, int texsize, int width, int height);
  void projectM_reset();

  void projectM_initengine();
  void projectM_resetengine();
  /// Initializes preset loading / management libraries
  int initPresetTools();

  /// Deinitialize all preset related tools. Usually done before projectM cleanup
  void destroyPresetTools();
  void default_key_handler( projectMEvent event, projectMKeycode keycode );
  // The current position of the directory iterator
  PresetIterator * m_presetPos;

  // Required by the preset chooser. Manages a loaded preset directory
  PresetLoader * m_presetLoader;

  // Provides accessor functions to choose presets
  PresetChooser * m_presetChooser;

  // Currently loaded preset
  std::auto_ptr<Preset> m_activePreset;

  // Destination preset when smooth preset switching
  std::auto_ptr<Preset> m_activePreset2;

  /// Experimental mood bar instance. May or may not make it into 1.0 release
  MoodBar * moodBar;

  /// All readonly variables which are passed as inputs to presets
  PresetInputs presetInputs;

  /// A preset outputs container used and modified by the "current" preset
  PresetOutputs presetOutputs;

  /// A preset outputs container used for smooth preset switching
  PresetOutputs presetOutputs2;
};
#endif
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/*
 * Copyright 2019 IBM International Business Machines Corp.
 *
 * 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.
 */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file target_types.H
 * @brief definitions for fapi2 target types
 */

#ifndef __FAPI2_TARGET_TYPES__
#define __FAPI2_TARGET_TYPES__
#include <stdint.h>

/// FAPI namespace
namespace fapi2
{
///
/// @enum fapi::TargetType
/// @brief Types, kinds, of targets
/// @note TYPE_NONE is used to represent empty/NULL targets in lists
/// or tables. TYPE_ALL is used to pass targets to methods which
/// can act generally on any type of target
///

/// Target Kind
enum TargetType : uint64_t
{
    TARGET_TYPE_NONE          = 0x0000000000000000, ///< No type
    TARGET_TYPE_SYSTEM        = 0x0000000000000001, ///< System type
    TARGET_TYPE_DIMM          = 0x0000000000000002, ///< DIMM type
    TARGET_TYPE_PROC_CHIP     = 0x0000000000000004, ///< Processor type
    TARGET_TYPE_MEMBUF_CHIP   = 0x0000000000000008, ///< Membuf type
    TARGET_TYPE_EX            = 0x0000000000000010, ///< EX - 2x Core, L2, L3 - can be deconfigured
    TARGET_TYPE_MBA           = 0x0000000000000020, ///< MBA type
    TARGET_TYPE_MCS           = 0x0000000000000040, ///< MCS type
    TARGET_TYPE_XBUS          = 0x0000000000000080, ///< XBUS type
    TARGET_TYPE_ABUS          = 0x0000000000000100, ///< ABUS type
    TARGET_TYPE_L4            = 0x0000000000000200, ///< L4 type
    TARGET_TYPE_CORE          = 0x0000000000000400, ///< Core
    TARGET_TYPE_EQ            = 0x0000000000000800, ///< EQ - 4x core, 2x L2, 2x L3 - can be deconfigured
    TARGET_TYPE_MCA           = 0x0000000000001000, ///< MCA type
    TARGET_TYPE_MCBIST        = 0x0000000000002000, ///< MCBIST type
    TARGET_TYPE_MI            = 0x0000000000004000, ///< MI Memory Interface (Cumulus)
    TARGET_TYPE_CAPP          = 0x0000000000008000, ///< CAPP target
    TARGET_TYPE_DMI           = 0x0000000000010000, ///< DMI type
    TARGET_TYPE_OBUS          = 0x0000000000020000, ///< OBUS type
    TARGET_TYPE_OBUS_BRICK    = 0x0000000000040000, ///< OBUS BRICK type
    TARGET_TYPE_SBE           = 0x0000000000080000, ///< SBE type
    TARGET_TYPE_PPE           = 0x0000000000100000, ///< PPE type
    TARGET_TYPE_PERV          = 0x0000000000200000, ///< Pervasive type
    TARGET_TYPE_PEC           = 0x0000000000400000, ///< PEC type
    TARGET_TYPE_PHB           = 0x0000000000800000, ///< PHB type
    TARGET_TYPE_MC            = 0x0000000001000000, ///< MC type
    TARGET_TYPE_OMI           = 0x0000000002000000, ///< OMI type
    TARGET_TYPE_OMIC          = 0x0000000004000000, ///< OMIC type
    TARGET_TYPE_MCC           = 0x0000000008000000, ///< MCC type
    TARGET_TYPE_OCMB_CHIP     = 0x0000000010000000, ///< OCMB type
    TARGET_TYPE_MEM_PORT      = 0x0000000020000000, ///< MEM_PORT type
    TARGET_TYPE_NMMU          = 0x0000000040000000, ///< NEST MMU type
#ifdef FAPI_2_Z
    TARGET_TYPE_SC_CHIP       = 0x0000000080000000, ///< Z SC type
#else
    TARGET_TYPE_RESERVED      = 0x0000000080000000, ///< Reserved for Cronus (Z)
#endif
    TARGET_TYPE_PAU           = 0x0000000100000000, ///< PAU type
    TARGET_TYPE_IOHS          = 0x0000000200000000, ///< IOHS type
    TARGET_TYPE_FC            = 0x0000000400000000, ///< Fused Core type
    TARGET_TYPE_PMIC          = 0x0000000800000000, ///< PMIC type
    TARGET_TYPE_PAUC          = 0x0000001000000000, ///< PAUC type
    TARGET_TYPE_MULTICAST     = 0x8000000000000000, ///< MULTICAST type
    TARGET_TYPE_ALL           = 0x7FFFFFFFFFFFFFFF, ///< Any/All types
    TARGET_TYPE_ALL_MC        = 0xFFFFFFFFFFFFFFFF, ///< Any/All types + Multicast

    // Compound target types
    TARGET_TYPE_CHIPS         = TARGET_TYPE_PROC_CHIP |
#ifdef FAPI_2_Z
                                TARGET_TYPE_SC_CHIP |
#endif
                                TARGET_TYPE_MEMBUF_CHIP |
                                TARGET_TYPE_OCMB_CHIP,

    TARGET_TYPE_CHIPLETS      = TARGET_TYPE_EX            |
                                TARGET_TYPE_MBA           |
                                TARGET_TYPE_MCS           |
                                TARGET_TYPE_XBUS          |
                                TARGET_TYPE_ABUS          |
                                TARGET_TYPE_L4            |
                                TARGET_TYPE_CORE          |
                                TARGET_TYPE_EQ            |
                                TARGET_TYPE_MCA           |
                                TARGET_TYPE_MCBIST        |
                                TARGET_TYPE_MI            |
                                TARGET_TYPE_DMI           |
                                TARGET_TYPE_OBUS          |
                                TARGET_TYPE_OBUS_BRICK    |
                                TARGET_TYPE_SBE           |
                                TARGET_TYPE_PPE           |
                                TARGET_TYPE_PERV          |
                                TARGET_TYPE_PEC           |
                                TARGET_TYPE_PHB           |
                                TARGET_TYPE_MC            |
                                TARGET_TYPE_OMI           |
                                TARGET_TYPE_OMIC          |
                                TARGET_TYPE_MCC           |
                                TARGET_TYPE_MEM_PORT      |
                                TARGET_TYPE_NMMU          |
                                TARGET_TYPE_PAU           |
                                TARGET_TYPE_IOHS          |
                                TARGET_TYPE_FC            |
                                TARGET_TYPE_PAUC,

    TARGET_TYPE_MULTICASTABLE = TARGET_TYPE_CORE   |
                                TARGET_TYPE_EQ     |
                                TARGET_TYPE_MCBIST |
                                TARGET_TYPE_OBUS   |
                                TARGET_TYPE_PERV   |
                                TARGET_TYPE_PEC,

    // Mappings to target types found in the error xml files
    TARGET_TYPE_EX_CHIPLET    = TARGET_TYPE_EX,
    TARGET_TYPE_MBA_CHIPLET   = TARGET_TYPE_MBA,
    TARGET_TYPE_MCS_CHIPLET   = TARGET_TYPE_MCS,
    TARGET_TYPE_XBUS_ENDPOINT = TARGET_TYPE_XBUS,
    TARGET_TYPE_ABUS_ENDPOINT = TARGET_TYPE_ABUS,
#ifdef FAPI_2_Z
    // Z mappings
    TARGET_TYPE_EP_CHIP       = TARGET_TYPE_PROC_CHIP,
    TARGET_TYPE_XBUS0         = TARGET_TYPE_XBUS,
    TARGET_TYPE_XBUS1         = TARGET_TYPE_OBUS,
    TARGET_TYPE_NEST          = TARGET_TYPE_CAPP,
    TARGET_TYPE_PCIE          = TARGET_TYPE_PEC,
    TARGET_TYPE_GXA           = TARGET_TYPE_PHB,
#endif
};

///
/// Target filter 64-bit
/// Declare the enumeration size so that target.H will compile without chip specific filter.
/// When users want to use an enumeration value then they can include the chip specific
/// target_filters.H, which would have the enumerator list of values.
///
enum TargetFilter : uint64_t;

// attributeOverride tool requires x86.nfp compile
#ifndef CONTEXT_x86_nfp
/// @cond
constexpr TargetType operator|(TargetType x, TargetType y)
{
    return static_cast<TargetType>(static_cast<uint64_t>(x) |
                                   static_cast<uint64_t>(y));
}
#endif

template<uint64_t V>
class bitCount
{
    public:
        // Don't use enums, too hard to compare
        static const uint8_t count = bitCount < (V >> 1) >::count + (V & 1);
};

template<>
class bitCount<0>
{
    public:
        static const uint8_t count = 0;
};
/// @endcond

}

#endif
<commit_msg>update fapi2 multicastable type<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/*
 * Copyright 2019 IBM International Business Machines Corp.
 *
 * 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.
 */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file target_types.H
 * @brief definitions for fapi2 target types
 */

#ifndef __FAPI2_TARGET_TYPES__
#define __FAPI2_TARGET_TYPES__
#include <stdint.h>

/// FAPI namespace
namespace fapi2
{
///
/// @enum fapi::TargetType
/// @brief Types, kinds, of targets
/// @note TYPE_NONE is used to represent empty/NULL targets in lists
/// or tables. TYPE_ALL is used to pass targets to methods which
/// can act generally on any type of target
///

/// Target Kind
enum TargetType : uint64_t
{
    TARGET_TYPE_NONE          = 0x0000000000000000, ///< No type
    TARGET_TYPE_SYSTEM        = 0x0000000000000001, ///< System type
    TARGET_TYPE_DIMM          = 0x0000000000000002, ///< DIMM type
    TARGET_TYPE_PROC_CHIP     = 0x0000000000000004, ///< Processor type
    TARGET_TYPE_MEMBUF_CHIP   = 0x0000000000000008, ///< Membuf type
    TARGET_TYPE_EX            = 0x0000000000000010, ///< EX - 2x Core, L2, L3 - can be deconfigured
    TARGET_TYPE_MBA           = 0x0000000000000020, ///< MBA type
    TARGET_TYPE_MCS           = 0x0000000000000040, ///< MCS type
    TARGET_TYPE_XBUS          = 0x0000000000000080, ///< XBUS type
    TARGET_TYPE_ABUS          = 0x0000000000000100, ///< ABUS type
    TARGET_TYPE_L4            = 0x0000000000000200, ///< L4 type
    TARGET_TYPE_CORE          = 0x0000000000000400, ///< Core
    TARGET_TYPE_EQ            = 0x0000000000000800, ///< EQ - 4x core, 2x L2, 2x L3 - can be deconfigured
    TARGET_TYPE_MCA           = 0x0000000000001000, ///< MCA type
    TARGET_TYPE_MCBIST        = 0x0000000000002000, ///< MCBIST type
    TARGET_TYPE_MI            = 0x0000000000004000, ///< MI Memory Interface (Cumulus)
    TARGET_TYPE_CAPP          = 0x0000000000008000, ///< CAPP target
    TARGET_TYPE_DMI           = 0x0000000000010000, ///< DMI type
    TARGET_TYPE_OBUS          = 0x0000000000020000, ///< OBUS type
    TARGET_TYPE_OBUS_BRICK    = 0x0000000000040000, ///< OBUS BRICK type
    TARGET_TYPE_SBE           = 0x0000000000080000, ///< SBE type
    TARGET_TYPE_PPE           = 0x0000000000100000, ///< PPE type
    TARGET_TYPE_PERV          = 0x0000000000200000, ///< Pervasive type
    TARGET_TYPE_PEC           = 0x0000000000400000, ///< PEC type
    TARGET_TYPE_PHB           = 0x0000000000800000, ///< PHB type
    TARGET_TYPE_MC            = 0x0000000001000000, ///< MC type
    TARGET_TYPE_OMI           = 0x0000000002000000, ///< OMI type
    TARGET_TYPE_OMIC          = 0x0000000004000000, ///< OMIC type
    TARGET_TYPE_MCC           = 0x0000000008000000, ///< MCC type
    TARGET_TYPE_OCMB_CHIP     = 0x0000000010000000, ///< OCMB type
    TARGET_TYPE_MEM_PORT      = 0x0000000020000000, ///< MEM_PORT type
    TARGET_TYPE_NMMU          = 0x0000000040000000, ///< NEST MMU type
#ifdef FAPI_2_Z
    TARGET_TYPE_SC_CHIP       = 0x0000000080000000, ///< Z SC type
#else
    TARGET_TYPE_RESERVED      = 0x0000000080000000, ///< Reserved for Cronus (Z)
#endif
    TARGET_TYPE_PAU           = 0x0000000100000000, ///< PAU type
    TARGET_TYPE_IOHS          = 0x0000000200000000, ///< IOHS type
    TARGET_TYPE_FC            = 0x0000000400000000, ///< Fused Core type
    TARGET_TYPE_PMIC          = 0x0000000800000000, ///< PMIC type
    TARGET_TYPE_PAUC          = 0x0000001000000000, ///< PAUC type
    TARGET_TYPE_MULTICAST     = 0x8000000000000000, ///< MULTICAST type
    TARGET_TYPE_ALL           = 0x7FFFFFFFFFFFFFFF, ///< Any/All types
    TARGET_TYPE_ALL_MC        = 0xFFFFFFFFFFFFFFFF, ///< Any/All types + Multicast

    // Compound target types
    TARGET_TYPE_CHIPS         = TARGET_TYPE_PROC_CHIP |
#ifdef FAPI_2_Z
                                TARGET_TYPE_SC_CHIP |
#endif
                                TARGET_TYPE_MEMBUF_CHIP |
                                TARGET_TYPE_OCMB_CHIP,

    TARGET_TYPE_CHIPLETS      = TARGET_TYPE_EX            |
                                TARGET_TYPE_MBA           |
                                TARGET_TYPE_MCS           |
                                TARGET_TYPE_XBUS          |
                                TARGET_TYPE_ABUS          |
                                TARGET_TYPE_L4            |
                                TARGET_TYPE_CORE          |
                                TARGET_TYPE_EQ            |
                                TARGET_TYPE_MCA           |
                                TARGET_TYPE_MCBIST        |
                                TARGET_TYPE_MI            |
                                TARGET_TYPE_DMI           |
                                TARGET_TYPE_OBUS          |
                                TARGET_TYPE_OBUS_BRICK    |
                                TARGET_TYPE_SBE           |
                                TARGET_TYPE_PPE           |
                                TARGET_TYPE_PERV          |
                                TARGET_TYPE_PEC           |
                                TARGET_TYPE_PHB           |
                                TARGET_TYPE_MC            |
                                TARGET_TYPE_OMI           |
                                TARGET_TYPE_OMIC          |
                                TARGET_TYPE_MCC           |
                                TARGET_TYPE_MEM_PORT      |
                                TARGET_TYPE_NMMU          |
                                TARGET_TYPE_PAU           |
                                TARGET_TYPE_IOHS          |
                                TARGET_TYPE_FC            |
                                TARGET_TYPE_PAUC,

    TARGET_TYPE_MULTICASTABLE = TARGET_TYPE_CORE   |
                                TARGET_TYPE_EQ     |
                                TARGET_TYPE_IOHS   |
                                TARGET_TYPE_MC     |
                                TARGET_TYPE_PAUC   |
                                TARGET_TYPE_PEC    |
                                TARGET_TYPE_PERV,

    // Mappings to target types found in the error xml files
    TARGET_TYPE_EX_CHIPLET    = TARGET_TYPE_EX,
    TARGET_TYPE_MBA_CHIPLET   = TARGET_TYPE_MBA,
    TARGET_TYPE_MCS_CHIPLET   = TARGET_TYPE_MCS,
    TARGET_TYPE_XBUS_ENDPOINT = TARGET_TYPE_XBUS,
    TARGET_TYPE_ABUS_ENDPOINT = TARGET_TYPE_ABUS,
#ifdef FAPI_2_Z
    // Z mappings
    TARGET_TYPE_EP_CHIP       = TARGET_TYPE_PROC_CHIP,
    TARGET_TYPE_XBUS0         = TARGET_TYPE_XBUS,
    TARGET_TYPE_XBUS1         = TARGET_TYPE_OBUS,
    TARGET_TYPE_NEST          = TARGET_TYPE_CAPP,
    TARGET_TYPE_PCIE          = TARGET_TYPE_PEC,
    TARGET_TYPE_GXA           = TARGET_TYPE_PHB,
#endif
};

///
/// Target filter 64-bit
/// Declare the enumeration size so that target.H will compile without chip specific filter.
/// When users want to use an enumeration value then they can include the chip specific
/// target_filters.H, which would have the enumerator list of values.
///
enum TargetFilter : uint64_t;

// attributeOverride tool requires x86.nfp compile
#ifndef CONTEXT_x86_nfp
/// @cond
constexpr TargetType operator|(TargetType x, TargetType y)
{
    return static_cast<TargetType>(static_cast<uint64_t>(x) |
                                   static_cast<uint64_t>(y));
}
#endif

template<uint64_t V>
class bitCount
{
    public:
        // Don't use enums, too hard to compare
        static const uint8_t count = bitCount < (V >> 1) >::count + (V & 1);
};

template<>
class bitCount<0>
{
    public:
        static const uint8_t count = 0;
};
/// @endcond

}

#endif
<|endoftext|>