<commit_before>#pragma once
#include "context.hpp"
namespace yagbe
{

namespace operands
{
	struct A {};
	struct F {};

	struct AF {};

	struct B {};
	struct C {};

	struct C_pointer {};

	struct BC {};
	struct BC_pointer {};

	struct D {};
	struct E {};

	struct DE {};
	struct DE_pointer {};

	struct H {};
	struct L {};

	struct HL {};
	struct HL_pointer {};

	struct d8 {};
	struct d16 {};

	struct HLI {};
	struct HLD {};

	struct SP {};

	template<typename Register>
	struct unwrap_register
	{

	};

	template<>
	struct unwrap_register
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.a; }
	};

	template<>
	struct unwrap_register<operands::F>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.f; }
	};

	template<>
	struct unwrap_register<operands::B>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.b; }
	};

	template<>
	struct unwrap_register<operands::C>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.c; }
	};

	template<>
	struct unwrap_register<operands::D>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.d; }
	};

	template<>
	struct unwrap_register<operands::E>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.e; }
	};

	template<>
	struct unwrap_register<operands::H>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.h; }
	};

	template<>
	struct unwrap_register<operands::L>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.l; }
	};

	template<>
	struct unwrap_register<operands::AF>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.af; }
	};

	template<>
	struct unwrap_register<operands::BC>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.bc; }
	};

	template<>
	struct unwrap_register<operands::DE>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.de; }
	};

	template<>
	struct unwrap_register<operands::HL>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.hl; }
	};

	template<>
	struct unwrap_register<operands::SP>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.sp; }
	};

	template<>
	struct unwrap_register<operands::BC_pointer>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.memory.at(c.registers.bc); }
	};

	template<>
	struct unwrap_register<operands::DE_pointer>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.memory.at(c.registers.de); }
	};

	template<>
	struct unwrap_register<operands::HL_pointer>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.memory.at(c.registers.hl); }
	};

	template<>
	struct unwrap_register<operands::HLI>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.memory.at(c.registers.hl++); }
	};

	template<>
	struct unwrap_register<operands::HLD>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.memory.at(c.registers.hl--); }
	};

	template<>
	struct unwrap_register<operands::C_pointer>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.memory.at(0xFF00 + c.registers.c); }
	};

	template<>
	struct unwrap_register<operands::d8>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto get(context &c) { return c.read_byte(); }
	};

	template<>
	struct unwrap_register<operands::d16>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto get(context &c) { return c.read_word(); }
	};

	//operands

	template<uint8_t s, uint8_t c>
	struct default_operand
	{
		constexpr static int size() { return s; }
		constexpr static int cycles() { return c; }
	};

	template<uint8_t s, uint8_t c, typename Arg>
	struct default_unary_operand
	{
		constexpr static int size() { return s; }
		constexpr static int cycles() { return c + unwrap_register<Arg>::complexity; }
	};

	template<uint8_t s, uint8_t c, typename Arg1, typename Arg2>
	struct default_binary_operand
	{
		static_assert(unwrap_register<Arg1>::size_of == unwrap_register<Arg2>::size_of, "Mismatching sizes");

		constexpr static int size() { return s; }
		constexpr static int cycles() { return c + unwrap_register<Arg1>::complexity + unwrap_register<Arg2>::complexity; }
	};

	//NOP
	struct NOP : default_operand<1, 4>
	{
		static void execute(context &c)
		{

		}
	};

	//HALT
	struct HALT : default_operand<1, 4>
	{
		static void execute(context &c)
		{
			throw std::exception("NYI");
		}
	};

	//this allows to type LD::execute, or LD::execute, etc
	template<typename Arg1, typename Arg2>
	struct LD : default_binary_operand<1, 4, Arg1, Arg2>
	{
		static void execute(context &c)
		{
			unwrap_register<Arg1>::get(c) = unwrap_register<Arg2>::get(c);
		}
	};

	//PUSH
	template<typename Arg>
	struct PUSH : default_operand<1, 16>
	{
		static_assert(unwrap_register<Arg>::size_of == 2, "Assuming word");

		static void execute(context &c)
		{
			union
			{
				uint8_t bytes[2];
				uint16_t word;
			};

			word = unwrap_register<Arg>::get(c);

			//TODO endianess
			c.memory.at(c.registers.sp--) = bytes[0];
			c.memory.at(c.registers.sp--) = bytes[1];
		}
	};

	//POP
	template<typename Arg>
	struct POP : default_operand<1, 16>
	{
		static_assert(unwrap_register<Arg>::size_of == 2, "Assuming word");

		static void execute(context &c)
		{
			union
			{
				uint8_t bytes[2];
				uint16_t word;
			};

			//TODO endianess
			bytes[1] = c.memory.at(c.registers.sp++);
			bytes[0] = c.memory.at(c.registers.sp++);

			unwrap_register<Arg>::get(c) = word
		}
	};

	//ARITHMETIC

	//INC
	template<typename Arg>
	struct INC : default_unary_operand<1, 4, Arg>
	{
		static void execute(context &c)
		{
			bool byte = unwrap_register<Arg>::size_of == 1;
			auto value = unwrap_register<Arg>::get(c);

			if (byte)
			{
				c.flags.h = ((value & 0x0f) == 0x0f);
			}

			value++;
			unwrap_register<Arg>::get(c) = value;

			if (byte)
			{
				c.flags.z = (value == 0);
				c.flags.n = 0;
			}
		}
	};

	//DEC
	template<typename Arg>
	struct DEC : default_unary_operand<1, 4, Arg>
	{
		static void execute(context &c)
		{
			bool byte = unwrap_register<Arg>::size_of == 1;
			auto value = unwrap_register<Arg>::get(c);

			if (byte)
			{
				c.flags.h = !(value & 0x0f); //TODO is this correct?
			}

			value--;
			unwrap_register<Arg>::get(c) = value;

			if (byte)
			{
				c.flags.z = (value == 0);
				c.flags.n = 1;
			}
		}
	};

}
}<commit_msg>added stop instruction<commit_after>#pragma once
#include "context.hpp"
namespace yagbe
{

namespace operands
{
	struct A {};
	struct F {};

	struct AF {};

	struct B {};
	struct C {};

	struct C_pointer {};

	struct BC {};
	struct BC_pointer {};

	struct D {};
	struct E {};

	struct DE {};
	struct DE_pointer {};

	struct H {};
	struct L {};

	struct HL {};
	struct HL_pointer {};

	struct d8 {};
	struct d16 {};

	struct HLI {};
	struct HLD {};

	struct SP {};

	template<typename Register>
	struct unwrap_register
	{

	};

	template<>
	struct unwrap_register
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.a; }
	};

	template<>
	struct unwrap_register<operands::F>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.f; }
	};

	template<>
	struct unwrap_register<operands::B>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.b; }
	};

	template<>
	struct unwrap_register<operands::C>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.c; }
	};

	template<>
	struct unwrap_register<operands::D>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.d; }
	};

	template<>
	struct unwrap_register<operands::E>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.e; }
	};

	template<>
	struct unwrap_register<operands::H>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.h; }
	};

	template<>
	struct unwrap_register<operands::L>
	{
		constexpr static int complexity = 0;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.registers.l; }
	};

	template<>
	struct unwrap_register<operands::AF>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.af; }
	};

	template<>
	struct unwrap_register<operands::BC>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.bc; }
	};

	template<>
	struct unwrap_register<operands::DE>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.de; }
	};

	template<>
	struct unwrap_register<operands::HL>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.hl; }
	};

	template<>
	struct unwrap_register<operands::SP>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.registers.sp; }
	};

	template<>
	struct unwrap_register<operands::BC_pointer>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.memory.at(c.registers.bc); }
	};

	template<>
	struct unwrap_register<operands::DE_pointer>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.memory.at(c.registers.de); }
	};

	template<>
	struct unwrap_register<operands::HL_pointer>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.memory.at(c.registers.hl); }
	};

	template<>
	struct unwrap_register<operands::HLI>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.memory.at(c.registers.hl++); }
	};

	template<>
	struct unwrap_register<operands::HLD>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto& get(context &c) { return c.memory.at(c.registers.hl--); }
	};

	template<>
	struct unwrap_register<operands::C_pointer>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto& get(context &c) { return c.memory.at(0xFF00 + c.registers.c); }
	};

	template<>
	struct unwrap_register<operands::d8>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 1;

		static auto get(context &c) { return c.read_byte(); }
	};

	template<>
	struct unwrap_register<operands::d16>
	{
		constexpr static int complexity = 4;
		constexpr static int size_of = 2;

		static auto get(context &c) { return c.read_word(); }
	};

	//operands

	template<uint8_t s, uint8_t c>
	struct default_operand
	{
		constexpr static int size() { return s; }
		constexpr static int cycles() { return c; }
	};

	template<uint8_t s, uint8_t c, typename Arg>
	struct default_unary_operand
	{
		constexpr static int size() { return s; }
		constexpr static int cycles() { return c + unwrap_register<Arg>::complexity; }
	};

	template<uint8_t s, uint8_t c, typename Arg1, typename Arg2>
	struct default_binary_operand
	{
		static_assert(unwrap_register<Arg1>::size_of == unwrap_register<Arg2>::size_of, "Mismatching sizes");

		constexpr static int size() { return s; }
		constexpr static int cycles() { return c + unwrap_register<Arg1>::complexity + unwrap_register<Arg2>::complexity; }
	};

	//NOP
	struct NOP : default_operand<1, 4>
	{
		static void execute(context &c)
		{

		}
	};

	//HALT
	struct HALT : default_operand<1, 4>
	{
		static void execute(context &c)
		{
			throw std::exception("NYI");
		}
	};

	//STOP
	struct STOP : default_operand<2, 4>
	{
		static void execute(context &c)
		{
			c.read_byte();
			throw std::exception("NYI");
		}
	};

	//this allows to type LD::execute, or LD::execute, etc
	template<typename Arg1, typename Arg2>
	struct LD : default_binary_operand<1, 4, Arg1, Arg2>
	{
		static void execute(context &c)
		{
			unwrap_register<Arg1>::get(c) = unwrap_register<Arg2>::get(c);
		}
	};

	//PUSH
	template<typename Arg>
	struct PUSH : default_operand<1, 16>
	{
		static_assert(unwrap_register<Arg>::size_of == 2, "Assuming word");

		static void execute(context &c)
		{
			union
			{
				uint8_t bytes[2];
				uint16_t word;
			};

			word = unwrap_register<Arg>::get(c);

			//TODO endianess
			c.memory.at(c.registers.sp--) = bytes[0];
			c.memory.at(c.registers.sp--) = bytes[1];
		}
	};

	//POP
	template<typename Arg>
	struct POP : default_operand<1, 16>
	{
		static_assert(unwrap_register<Arg>::size_of == 2, "Assuming word");

		static void execute(context &c)
		{
			union
			{
				uint8_t bytes[2];
				uint16_t word;
			};

			//TODO endianess
			bytes[1] = c.memory.at(c.registers.sp++);
			bytes[0] = c.memory.at(c.registers.sp++);

			unwrap_register<Arg>::get(c) = word
		}
	};

	//ARITHMETIC

	//INC
	template<typename Arg>
	struct INC : default_unary_operand<1, 4, Arg>
	{
		static void execute(context &c)
		{
			bool byte = unwrap_register<Arg>::size_of == 1;
			auto value = unwrap_register<Arg>::get(c);

			if (byte)
			{
				c.flags.h = ((value & 0x0f) == 0x0f);
			}

			value++;
			unwrap_register<Arg>::get(c) = value;

			if (byte)
			{
				c.flags.z = (value == 0);
				c.flags.n = 0;
			}
		}
	};

	//DEC
	template<typename Arg>
	struct DEC : default_unary_operand<1, 4, Arg>
	{
		static void execute(context &c)
		{
			bool byte = unwrap_register<Arg>::size_of == 1;
			auto value = unwrap_register<Arg>::get(c);

			if (byte)
			{
				c.flags.h = !(value & 0x0f); //TODO is this correct?
			}

			value--;
			unwrap_register<Arg>::get(c) = value;

			if (byte)
			{
				c.flags.z = (value == 0);
				c.flags.n = 1;
			}
		}
	};

}
}<|endoftext|>


<commit_before>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <nan.h>

using v8::FunctionTemplate;

NAN_METHOD(Get) {
	if (info.Length() != 3) {
		Nan::ThrowError("getpriority requires 3 args");
		return;
	}
	if (!info[0]->IsNumber()) {
		Nan::ThrowError("getpriority requires a number for its first (`which`) arg");
		return;
	}
	if (!info[1]->IsNumber()) {
		Nan::ThrowError("getpriority requires a number for its second (`who`) arg");
		return;
	}
	if (!info[2]->IsFunction()) {
		Nan::ThrowError("getpriority requires a callback as its third arg");
		return;
	}

	int which = info[0]->Int32Value();
	int who = info[1]->Int32Value();
	v8::Local<v8::Function> cb = info[2].As<v8::Function>();

	// since getpriority can legitimately return -1, we need to
	// clear errno and check it upon return.
	errno = 0;
	int priority = getpriority(which, who);
	if (priority == -1 && errno) {
		v8::Local<v8::Value> jsErr = Nan::New(errno);
		Nan::MakeCallback(Nan::GetCurrentContext()->Global(), cb, 1, &jsErr);
		return;
	}

	v8::Local<v8::Value> results[2];
	results[0] = Nan::Undefined();
	results[1] = Nan::New(priority);

	Nan::MakeCallback(Nan::GetCurrentContext()->Global(), cb, 2, results);
}

NAN_METHOD(Set) {
	if (info.Length() != 4) {
		Nan::ThrowError("setpriority requires 4 args");
		return;
	}
	if (!info[0]->IsNumber()) {
		Nan::ThrowError("setpriority requires a number for its first (`which`) arg");
		return;
	}
	if (!info[1]->IsNumber()) {
		Nan::ThrowError("setpriority requires a number for its second (`who`) arg");
		return;
	}
	if (!info[2]->IsNumber()) {
		Nan::ThrowError("setpriority requires a number for its third (`prio`) arg");
		return;
	}
	if (!info[3]->IsFunction()) {
		Nan::ThrowError("setpriority requires a callback as its fourth arg");
		return;
	}

	int which = info[0]->Int32Value();
	int who = info[1]->Int32Value();
	int prio = info[2]->Int32Value();
	v8::Local<v8::Function> cb = info[3].As<v8::Function>();

	int priority = setpriority(which, who, prio);
	if (priority != 0) {
		// FIXME: provide more detail
		v8::Local<v8::Value> jsErr = Nan::New("setpriority failed").ToLocalChecked();
		Nan::MakeCallback(Nan::GetCurrentContext()->Global(), cb, 1, &jsErr);
		return;
	}

	v8::Local<v8::Value> result = Nan::Undefined();

	Nan::MakeCallback(Nan::GetCurrentContext()->Global(), cb, 1, &result);
}

NAN_MODULE_INIT(Init) {
	Nan::Set(target, Nan::New("get").ToLocalChecked(),
		 Nan::GetFunction(Nan::New<FunctionTemplate>(Get)).ToLocalChecked());
	Nan::Set(target, Nan::New("set").ToLocalChecked(),
		 Nan::GetFunction(Nan::New<FunctionTemplate>(Set)).ToLocalChecked());

	// constants
	Nan::Set(target, Nan::New("Process").ToLocalChecked(),
		 v8::Integer::New(v8::Isolate::GetCurrent(), (int)PRIO_PROCESS));
	Nan::Set(target, Nan::New("Pgrp").ToLocalChecked(),
		 v8::Integer::New(v8::Isolate::GetCurrent(), (int)PRIO_PGRP));
	Nan::Set(target, Nan::New("User").ToLocalChecked(),
		 v8::Integer::New(v8::Isolate::GetCurrent(), (int)PRIO_USER));
}

NODE_MODULE(priority, Init)
<commit_msg>use Nan::New instead of v8::Integer::New for v0.10 compat<commit_after>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <nan.h>

using v8::FunctionTemplate;

NAN_METHOD(Get) {
	if (info.Length() != 3) {
		Nan::ThrowError("getpriority requires 3 args");
		return;
	}
	if (!info[0]->IsNumber()) {
		Nan::ThrowError("getpriority requires a number for its first (`which`) arg");
		return;
	}
	if (!info[1]->IsNumber()) {
		Nan::ThrowError("getpriority requires a number for its second (`who`) arg");
		return;
	}
	if (!info[2]->IsFunction()) {
		Nan::ThrowError("getpriority requires a callback as its third arg");
		return;
	}

	int which = info[0]->Int32Value();
	int who = info[1]->Int32Value();
	v8::Local<v8::Function> cb = info[2].As<v8::Function>();

	// since getpriority can legitimately return -1, we need to
	// clear errno and check it upon return.
	errno = 0;
	int priority = getpriority(which, who);
	if (priority == -1 && errno) {
		v8::Local<v8::Value> jsErr = Nan::New(errno);
		Nan::MakeCallback(Nan::GetCurrentContext()->Global(), cb, 1, &jsErr);
		return;
	}

	v8::Local<v8::Value> results[2];
	results[0] = Nan::Undefined();
	results[1] = Nan::New(priority);

	Nan::MakeCallback(Nan::GetCurrentContext()->Global(), cb, 2, results);
}

NAN_METHOD(Set) {
	if (info.Length() != 4) {
		Nan::ThrowError("setpriority requires 4 args");
		return;
	}
	if (!info[0]->IsNumber()) {
		Nan::ThrowError("setpriority requires a number for its first (`which`) arg");
		return;
	}
	if (!info[1]->IsNumber()) {
		Nan::ThrowError("setpriority requires a number for its second (`who`) arg");
		return;
	}
	if (!info[2]->IsNumber()) {
		Nan::ThrowError("setpriority requires a number for its third (`prio`) arg");
		return;
	}
	if (!info[3]->IsFunction()) {
		Nan::ThrowError("setpriority requires a callback as its fourth arg");
		return;
	}

	int which = info[0]->Int32Value();
	int who = info[1]->Int32Value();
	int prio = info[2]->Int32Value();
	v8::Local<v8::Function> cb = info[3].As<v8::Function>();

	int priority = setpriority(which, who, prio);
	if (priority != 0) {
		// FIXME: provide more detail
		v8::Local<v8::Value> jsErr = Nan::New("setpriority failed").ToLocalChecked();
		Nan::MakeCallback(Nan::GetCurrentContext()->Global(), cb, 1, &jsErr);
		return;
	}

	v8::Local<v8::Value> result = Nan::Undefined();

	Nan::MakeCallback(Nan::GetCurrentContext()->Global(), cb, 1, &result);
}

NAN_MODULE_INIT(Init) {
	Nan::Set(target, Nan::New("get").ToLocalChecked(),
		 Nan::GetFunction(Nan::New<FunctionTemplate>(Get)).ToLocalChecked());
	Nan::Set(target, Nan::New("set").ToLocalChecked(),
		 Nan::GetFunction(Nan::New<FunctionTemplate>(Set)).ToLocalChecked());

	// constants
	Nan::Set(target, Nan::New("Process").ToLocalChecked(), Nan::New((int)PRIO_PROCESS));
	Nan::Set(target, Nan::New("Pgrp").ToLocalChecked(), Nan::New((int)PRIO_PGRP));
	Nan::Set(target, Nan::New("User").ToLocalChecked(), Nan::New((int)PRIO_USER));
}

NODE_MODULE(priority, Init)
<|endoftext|>


<commit_before>//
//  main.cpp
//  Unit Tests
//
//  Created by Evan McCartney-Melstad on 12/31/14.
//  Copyright (c) 2014 Evan McCartney-Melstad. All rights reserved.
//

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "../cPWP/generateSimulatedData.h"
#include "../cPWP/bamsToBin.h"
#include "../cPWP/calcPWP.h"
#include "catch.hpp"
#include <string>

/*
TEST_CASE( "Simulated reads are generated", "[generateReads]" ) {
    // Make sure that the read simulation finishes
    REQUIRE( generateReadsAndMap(1, 0.01, "0.0", "300", "50", "1000000", "100", "1234", "scaffold_0.fasta") == 0);
}
 */

TEST_CASE( "Generate reference genome for simulation tests", "[generateReference]") {
    REQUIRE( createReferenceGenome(10000000, 0.42668722, "simulatedReferenceGenome.fasta") == 0 );
}

TEST_CASE ( "Mutate a reference genome", "[mutateRefGenome]") {
    REQUIRE( createMutatedGenome("simulatedReferenceGenome.fasta", "simulatedReferenceGenomeMutated.fasta", 0.01) == 0);
}

TEST_CASE( "Generate sequence reads", "[perfectReads]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome.fasta", 1, 100, 300, "normalRef") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

TEST_CASE( " Mapping first set of reads", "[mapReads]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "normalRef_R1.fastq", "normalRef_R2.fastq", "normal.bam", "25") == 0);
}

TEST_CASE( "Generate sequence reads 2", "[perfectReads2]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutated.fasta", 1, 100, 300, "mutatedRef") == 0);
}

TEST_CASE( " Mapping second set of reads", "[mapReads2]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "mutatedRef_R1.fastq", "mutatedRef_R2.fastq", "mutated.bam", "25") == 0);
}

TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "25", "angsdOutLog.txt") == 0);
}

/*

TEST_CASE( "Generate mutated reference genomes and simulate reads", "[genomeAndReadSim]") {
    REQUIRE( generateReadsAndMap(3, 0.01, "300", "25", "10000", "100", "1234", "simulatedReferenceGenome.fasta", "25") == 0);
}

TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "25", "angsdOutLog.txt") == 0);
}

 */

TEST_CASE( "Convert ANGSD read counts to unsigned chars for major and minor counts", "[convertCountsToBinary]") {
    REQUIRE( convertANGSDcountsToBinary("angsdOut", "angsdOut.readCounts.binary", 2, 5000) == 0); // 3 individuals, not 2, because generateReadsAndMap actually generates n+1 individuals, since one individual is identical to the reference genome. And 5000 as a max because we don't want to exclude any loci for this test
}

TEST_CASE( "Calculate PWP from the binary representations of the ANGSD readcounts", "[calcPWP]") {
    REQUIRE( calcPWPfromBinaryFile ("angsdOut.readCounts.binary", 0, 272, "testingOut.pwp", 30) == 0);
}

<commit_msg>Minor changes<commit_after>//
//  main.cpp
//  Unit Tests
//
//  Created by Evan McCartney-Melstad on 12/31/14.
//  Copyright (c) 2014 Evan McCartney-Melstad. All rights reserved.
//

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "../cPWP/generateSimulatedData.h"
#include "../cPWP/bamsToBin.h"
#include "../cPWP/calcPWP.h"
#include "catch.hpp"
#include <string>

/*
TEST_CASE( "Simulated reads are generated", "[generateReads]" ) {
    // Make sure that the read simulation finishes
    REQUIRE( generateReadsAndMap(1, 0.01, "0.0", "300", "50", "1000000", "100", "1234", "scaffold_0.fasta") == 0);
}
 */

TEST_CASE( "Generate reference genome for simulation tests", "[generateReference]") {
    REQUIRE( createReferenceGenome(1000000, 0.42668722, "simulatedReferenceGenome.fasta") == 0 );
}

TEST_CASE ( "Mutate a reference genome", "[mutateRefGenome]") {
    REQUIRE( createMutatedGenome("simulatedReferenceGenome.fasta", "simulatedReferenceGenomeMutated.fasta", 0.01) == 0);
}

TEST_CASE( "Generate sequence reads", "[perfectReads]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome.fasta", 1, 100, 300, "normalRef") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

TEST_CASE( " Mapping first set of reads", "[mapReads]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "normalRef_R1.fastq", "normalRef_R2.fastq", "normal.bam", "25") == 0);
}

TEST_CASE( "Generate sequence reads 2", "[perfectReads2]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutated.fasta", 1, 100, 300, "mutatedRef") == 0);
}

TEST_CASE( " Mapping second set of reads", "[mapReads2]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "mutatedRef_R1.fastq", "mutatedRef_R2.fastq", "mutated.bam", "25") == 0);
}

TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "25", "angsdOutLog.txt") == 0);
}

/*

TEST_CASE( "Generate mutated reference genomes and simulate reads", "[genomeAndReadSim]") {
    REQUIRE( generateReadsAndMap(3, 0.01, "300", "25", "10000", "100", "1234", "simulatedReferenceGenome.fasta", "25") == 0);
}

TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "25", "angsdOutLog.txt") == 0);
}

 */

TEST_CASE( "Convert ANGSD read counts to unsigned chars for major and minor counts", "[convertCountsToBinary]") {
    REQUIRE( convertANGSDcountsToBinary("angsdOut", "angsdOut.readCounts.binary", 2, 5000) == 0); // 3 individuals, not 2, because generateReadsAndMap actually generates n+1 individuals, since one individual is identical to the reference genome. And 5000 as a max because we don't want to exclude any loci for this test
}

TEST_CASE( "Calculate PWP from the binary representations of the ANGSD readcounts", "[calcPWP]") {
    REQUIRE( calcPWPfromBinaryFile ("angsdOut.readCounts.binary", 0, 272, "testingOut.pwp", 30) == 0);
}

<|endoftext|>


<commit_before>#ifndef ITER_PRODUCT_HPP_
#define ITER_PRODUCT_HPP_

#include "iterbase.hpp"

#include <iterator>
#include <tuple>
#include <utility>
#include <array>

namespace iter {
    template <typename... RestContainers>
    class Productor;

    template <typename... Containers>
    Productor<Containers...> product(Containers&&...);

    // specialization for at least 1 template argument
    template <typename Container, typename... RestContainers>
    class Productor <Container, RestContainers...> {
        static_assert(!std::is_rvalue_reference<Container>::value,
                "Itertools cannot be templated with rvalue references");

        friend Productor product<Container, RestContainers...>(
                Container&&, RestContainers&&...);

        template <typename... RC>
        friend class Productor;

        using ProdIterDeref = std::tuple<
            iterator_deref<Container>, iterator_deref<RestContainers>...>;

        private:
            Container container;
            Productor<RestContainers...> rest_products;
            Productor(Container&& container, RestContainers&&... rest)
                : container(std::forward<Container>(container)),
                rest_products{std::forward<RestContainers>(rest)...}
            { }

        public:
            class Iterator
                : public std::iterator<std::input_iterator_tag, ProdIterDeref>
            {
                private:
                    using RestIter =
                        typename Productor<RestContainers...>::Iterator;

                    iterator_type<Container> iter;
                    iterator_type<Container> begin;

                    RestIter rest_iter;
                    RestIter rest_end;
                public:
                    constexpr static const bool is_base_iter = false;
                    Iterator(const iterator_type<Container>& it,
                            RestIter&& rest,
                            RestIter&& in_rest_end)
                        : iter{it},
                        begin{it},
                        rest_iter{rest},
                        rest_end{in_rest_end}
                    { }

                    void reset() {
                        this->iter = this->begin;
                    }

                    Iterator& operator++() {
                        ++this->rest_iter;
                        if (!(this->rest_iter != this->rest_end)) {
                            this->rest_iter.reset();
                            ++this->iter;
                        }
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->iter != other.iter &&
                            (RestIter::is_base_iter
                                || this->rest_iter != other.rest_iter);
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }

                    ProdIterDeref operator*() {
                        return std::tuple_cat(
                                std::tuple<iterator_deref<Container>>{
                                    *this->iter},
                                *this->rest_iter);
                    }
            };

            Iterator begin() {
                return {std::begin(this->container),
                    std::begin(this->rest_products),
                    std::end(this->rest_products)};
            }

            Iterator end() {
                return {std::end(this->container),
                    std::end(this->rest_products),
                    std::end(this->rest_products)};
            }
    };

    template <>
    class Productor<> {
        public:
            class Iterator
                : public std::iterator<std::input_iterator_tag, std::tuple<>>
            {
                public:
                    constexpr static const bool is_base_iter = true;

                    void reset() { }

                    Iterator& operator++() {
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    // see note in zip about base case operator!=
                    bool operator!=(const Iterator&) const {
                        return false;
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }

                    std::tuple<> operator*() const {
                        return {};
                    }
            };

            Iterator begin() {
                return {};
            }

            Iterator end() {
                return {};
            }
    };

    template <typename... Containers>
    Productor<Containers...> product(Containers&&... containers) {
        return {std::forward<Containers>(containers)...};
    }

    constexpr std::array<std::tuple<>, 1> product() {
        return {{}};
    }
}

#endif
<commit_msg>eliminates shadow warnings from product<commit_after>#ifndef ITER_PRODUCT_HPP_
#define ITER_PRODUCT_HPP_

#include "iterbase.hpp"

#include <iterator>
#include <tuple>
#include <utility>
#include <array>

namespace iter {
    template <typename... RestContainers>
    class Productor;

    template <typename... Containers>
    Productor<Containers...> product(Containers&&...);

    // specialization for at least 1 template argument
    template <typename Container, typename... RestContainers>
    class Productor <Container, RestContainers...> {
        static_assert(!std::is_rvalue_reference<Container>::value,
                "Itertools cannot be templated with rvalue references");

        friend Productor product<Container, RestContainers...>(
                Container&&, RestContainers&&...);

        template <typename... RC>
        friend class Productor;

        using ProdIterDeref = std::tuple<
            iterator_deref<Container>, iterator_deref<RestContainers>...>;

        private:
            Container container;
            Productor<RestContainers...> rest_products;
            Productor(Container&& in_container, RestContainers&&... rest)
                : container(std::forward<Container>(in_container)),
                rest_products{std::forward<RestContainers>(rest)...}
            { }

        public:
            class Iterator
                : public std::iterator<std::input_iterator_tag, ProdIterDeref>
            {
                private:
                    using RestIter =
                        typename Productor<RestContainers...>::Iterator;

                    iterator_type<Container> iter;
                    iterator_type<Container> begin;

                    RestIter rest_iter;
                    RestIter rest_end;
                public:
                    constexpr static const bool is_base_iter = false;
                    Iterator(const iterator_type<Container>& it,
                            RestIter&& rest,
                            RestIter&& in_rest_end)
                        : iter{it},
                        begin{it},
                        rest_iter{rest},
                        rest_end{in_rest_end}
                    { }

                    void reset() {
                        this->iter = this->begin;
                    }

                    Iterator& operator++() {
                        ++this->rest_iter;
                        if (!(this->rest_iter != this->rest_end)) {
                            this->rest_iter.reset();
                            ++this->iter;
                        }
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->iter != other.iter &&
                            (RestIter::is_base_iter
                                || this->rest_iter != other.rest_iter);
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }

                    ProdIterDeref operator*() {
                        return std::tuple_cat(
                                std::tuple<iterator_deref<Container>>{
                                    *this->iter},
                                *this->rest_iter);
                    }
            };

            Iterator begin() {
                return {std::begin(this->container),
                    std::begin(this->rest_products),
                    std::end(this->rest_products)};
            }

            Iterator end() {
                return {std::end(this->container),
                    std::end(this->rest_products),
                    std::end(this->rest_products)};
            }
    };

    template <>
    class Productor<> {
        public:
            class Iterator
                : public std::iterator<std::input_iterator_tag, std::tuple<>>
            {
                public:
                    constexpr static const bool is_base_iter = true;

                    void reset() { }

                    Iterator& operator++() {
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    // see note in zip about base case operator!=
                    bool operator!=(const Iterator&) const {
                        return false;
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }

                    std::tuple<> operator*() const {
                        return {};
                    }
            };

            Iterator begin() {
                return {};
            }

            Iterator end() {
                return {};
            }
    };

    template <typename... Containers>
    Productor<Containers...> product(Containers&&... containers) {
        return {std::forward<Containers>(containers)...};
    }

    constexpr std::array<std::tuple<>, 1> product() {
        return {{}};
    }
}

#endif
<|endoftext|>


<commit_before>/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Value-Profiling Utility.
 *
 * The Initial Developer of the Original Code is
 * Intel Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Mohammad R. Haghighat [mohammad.r.haghighat@intel.com]
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "VMPI.h"

// Note, this is not supported in configurations with more than one AvmCore running
// in the same process.

#ifdef WIN32
#include "windows.h"
#else
#define __cdecl
#include <stdarg.h>
#include <string.h>
#endif

#include "vprof.h"

#define MIN(x,y) ((x) <= (y) ? x : y)
#define MAX(x,y) ((x) >= (y) ? x : y)

#ifndef MAXINT
#define MAXINT int(unsigned(-1)>>1)
#endif

#ifndef MAXINT64
#define MAXINT64 int64_t(uint64_t(-1)>>1)
#endif

#ifndef __STDC_WANT_SECURE_LIB__
#define sprintf_s(b,size,fmt,...) sprintf((b),(fmt),__VA_ARGS__)
#endif

#if THREADED
#define DO_LOCK(lock) Lock(lock); {
#define DO_UNLOCK(lock) }; Unlock(lock)
#else
#define DO_LOCK(lock) { (void)(lock);
#define DO_UNLOCK(lock) }
#endif

#if THREAD_SAFE
#define LOCK(lock) DO_LOCK(lock)
#define UNLOCK(lock) DO_UNLOCK(lock)
#else
#define LOCK(lock) { (void)(lock);
#define UNLOCK(lock) }
#endif

static entry* entries = NULL;
static bool notInitialized = true;
static long glock = LOCK_IS_FREE;

#define Lock(lock) while (_InterlockedCompareExchange(lock, LOCK_IS_TAKEN, LOCK_IS_FREE) == LOCK_IS_TAKEN){};
#define Unlock(lock) _InterlockedCompareExchange(lock, LOCK_IS_FREE, LOCK_IS_TAKEN);

#ifdef WIN32
	static void vprof_printf(const char* format, ...)
	{
		va_list args;
		va_start(args, format);

		char buf[1024];
		vsnprintf(buf, sizeof(buf), format, args);

		va_end(args);

		printf(buf);
		::OutputDebugStringA(buf);
	}
#else
	#define vprof_printf printf
#endif

inline static entry* reverse (entry* s)
{
    entry_t e, n, p;

    p = NULL;
    for (e = s; e; e = n) {
        n = e->next;
        e->next = p;
        p = e;
    }

    return p;
}

static char* f (double d)
{
    static char s[80];
    char* p;
    sprintf_s (s, sizeof(s), "%lf", d);
    p = s+VMPI_strlen(s)-1;
    while (*p == '0') {
        *p = '\0';
        p--;
        if (p == s) break;
    }
    if (*p == '.') *p = '\0';
    return s;
}

static void dumpProfile (void)
{
    entry_t e;

    entries = reverse(entries);
    vprof_printf ("event avg [min : max] total count\n");
    for (e = entries; e; e = e->next) {
        vprof_printf ("%s", e->file);
        if (e->line >= 0) {
            vprof_printf (":%d", e->line);
        }
        vprof_printf (" %s [%lld : %lld] %lld %lld ",
                f(((double)e->sum)/((double)e->count)), (long long int)e->min, (long long int)e->max, (long long int)e->sum, (long long int)e->count);
        if (e->h) {
            int j = MAXINT;
            for (j = 0; j < e->h->nbins; j ++) {
                vprof_printf ("(%lld < %lld) ", (long long int)e->h->count[j], (long long int)e->h->lb[j]);
            }
            vprof_printf ("(%lld >= %lld) ", (long long int)e->h->count[e->h->nbins], (long long int)e->h->lb[e->h->nbins-1]);
        }
        if (e->func) {
            int j;
            for (j = 0; j < NUM_EVARS; j++) {
                if (e->ivar[j] != 0) {
                    vprof_printf ("IVAR%d %d ", j, e->ivar[j]);
                }
            }
            for (j = 0; j < NUM_EVARS; j++) {
                if (e->i64var[j] != 0) {
                    vprof_printf ("I64VAR%d %lld ", j, (long long int)e->i64var[j]);
                }
            }
            for (j = 0; j < NUM_EVARS; j++) {
                if (e->dvar[j] != 0) {
                    vprof_printf ("DVAR%d %lf ", j, e->dvar[j]);
                }
            }
        }
        vprof_printf ("\n");
    }
    entries = reverse(entries);
}

int _profileEntryValue (void* id, int64_t value)
{
    entry_t e = (entry_t) id;
    long* lock = &(e->lock);
    LOCK (lock);
       e->value = value;
       e->sum += value;
       e->count ++;
       e->min = MIN (e->min, value);
       e->max = MAX (e->max, value);
       if (e->func) e->func (e);
    UNLOCK (lock);

    return 0;
}

inline static entry_t findEntry (char* file, int line)
{
    for (entry_t e =  entries; e; e = e->next) {
        if ((e->line == line) && (VMPI_strcmp (e->file, file) == 0)) {
            return e;
        }
    }
    return NULL;
}

int profileValue(void** id, char* file, int line, int64_t value, ...)
{
    DO_LOCK (&glock);
        entry_t e = (entry_t) *id;
        if (notInitialized) {
            atexit (dumpProfile);
            notInitialized = false;
        }

        if (e == NULL) {
            e = findEntry (file, line);
            if (e) {
                *id = e;
            }
        }

        if (e == NULL) {
            va_list va;
            e = (entry_t) malloc (sizeof(entry));
            e->lock = LOCK_IS_FREE;
            e->file = file;
            e->line = line;
            e->value = value;
            e->sum = value;
            e->count = 1;
            e->min = value;
            e->max = value;

            va_start (va, value);
            e->func = (void (__cdecl*)(void*)) va_arg (va, void*);
            va_end (va);

            e->h = NULL;

            e->genptr = NULL;

            VMPI_memset (&e->ivar,   0, sizeof(e->ivar));
            VMPI_memset (&e->i64var, 0, sizeof(e->i64var));
            VMPI_memset (&e->dvar,   0, sizeof(e->dvar));

            e->next = entries;
            entries = e;

            if (e->func) e->func (e);

            *id = e;
        } else {
            long* lock = &(e->lock);
            LOCK (lock);
                e->value = value;
                e->sum += value;
                e->count ++;
                e->min = MIN (e->min, value);
                e->max = MAX (e->max, value);
                if (e->func) e->func (e);
            UNLOCK (lock);
        }
    DO_UNLOCK (&glock);

    return 0;
}

int _histEntryValue (void* id, int64_t value)
{
    entry_t e = (entry_t) id;
    long* lock = &(e->lock);
    hist_t h = e->h;
    int nbins = h->nbins;
    int64_t* lb = h->lb;
    int b;

    for (b = 0; b < nbins; b ++) {
        if (value < lb[b]) break;
    }

    LOCK (lock);
       e->value = value;
       e->sum += value;
       e->count ++;
       e->min = MIN (e->min, value);
       e->max = MAX (e->max, value);
       h->count[b] ++;
    UNLOCK (lock);

    return 0;
}

int histValue(void** id, char* file, int line, int64_t value, int nbins, ...)
{
    DO_LOCK (&glock);
        entry_t e = (entry_t) *id;
        if (notInitialized) {
            atexit (dumpProfile);
            notInitialized = false;
        }

        if (e == NULL) {
            e = findEntry (file, line);
            if (e) {
                *id = e;
            }
        }

        if (e == NULL) {
            va_list va;
            hist_t h;
            int b, n, s;
            int64_t* lb;

            e = (entry_t) malloc (sizeof(entry));
            e->lock = LOCK_IS_FREE;
            e->file = file;
            e->line = line;
            e->value = value;
            e->sum = value;
            e->count = 1;
            e->min = value;
            e->max = value;
            e->func = NULL;
            e->h = h = (hist_t) malloc (sizeof(hist));
            n = 1+MAX(nbins,0);
            h->nbins = n-1;
            s = n*sizeof(int64_t);
            lb = (int64_t*) malloc (s);
            h->lb = lb;
            VMPI_memset (h->lb, 0, s);
            h->count = (int64_t*) malloc (s);
            VMPI_memset (h->count, 0, s);

            va_start (va, nbins);
            for (b = 0; b < nbins; b++) {
                //lb[b] = va_arg (va, int64_t);
                lb[b] = va_arg (va, int);
            }
            lb[b] = MAXINT64;
            va_end (va);

            for (b = 0; b < nbins; b ++) {
                if (value < lb[b]) break;
            }
            h->count[b] ++;

            e->genptr = NULL;

            VMPI_memset (&e->ivar,   0, sizeof(e->ivar));
            VMPI_memset (&e->i64var, 0, sizeof(e->i64var));
            VMPI_memset (&e->dvar,   0, sizeof(e->dvar));

            e->next = entries;
            entries = e;
            *id = e;
        } else {
            int b;
            long* lock = &(e->lock);
            hist_t h=e->h;
            int64_t* lb = h->lb;

            LOCK (lock);
                e->value = value;
                e->sum += value;
                e->count ++;
                e->min = MIN (e->min, value);
                e->max = MAX (e->max, value);
                for (b = 0; b < nbins; b ++) {
                    if (value < lb[b]) break;
                }
                h->count[b] ++;
            UNLOCK (lock);
        }
    DO_UNLOCK (&glock);

    return 0;
}

#if defined(_MSC_VER) && defined(_M_IX86)
inline uint64_t _rdtsc()
{
	// read the cpu cycle counter.  1 tick = 1 cycle on IA32
	_asm rdtsc;
}
#elif defined(__GNUC__) && (__i386__ || __x86_64__)
inline uint64_t _rdtsc()
{
   uint32_t lo, hi;
   __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
   return (uint64_t(hi) << 32) | lo;
}
#else
// add stub for platforms without it, so fat builds don't fail
inline uint64_t _rdtsc() { return 0; }
#endif

void* _tprof_before_id=0;
static uint64_t _tprof_before = 0;
int64_t _tprof_time()
{
    uint64_t now = _rdtsc();
    uint64_t v = _tprof_before ? now-_tprof_before : 0;
    _tprof_before = now;
    return v/2600; // v = microseconds on a 2.6ghz cpu
}

<commit_msg>Undo vprof.cpp change for OutputDebugStringA if UNDER_CE is defined, as it doesn't exist in WinMo (r=me)<commit_after>/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Value-Profiling Utility.
 *
 * The Initial Developer of the Original Code is
 * Intel Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Mohammad R. Haghighat [mohammad.r.haghighat@intel.com]
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "VMPI.h"

// Note, this is not supported in configurations with more than one AvmCore running
// in the same process.

#ifdef WIN32
#include "windows.h"
#else
#define __cdecl
#include <stdarg.h>
#include <string.h>
#endif

#include "vprof.h"

#define MIN(x,y) ((x) <= (y) ? x : y)
#define MAX(x,y) ((x) >= (y) ? x : y)

#ifndef MAXINT
#define MAXINT int(unsigned(-1)>>1)
#endif

#ifndef MAXINT64
#define MAXINT64 int64_t(uint64_t(-1)>>1)
#endif

#ifndef __STDC_WANT_SECURE_LIB__
#define sprintf_s(b,size,fmt,...) sprintf((b),(fmt),__VA_ARGS__)
#endif

#if THREADED
#define DO_LOCK(lock) Lock(lock); {
#define DO_UNLOCK(lock) }; Unlock(lock)
#else
#define DO_LOCK(lock) { (void)(lock);
#define DO_UNLOCK(lock) }
#endif

#if THREAD_SAFE
#define LOCK(lock) DO_LOCK(lock)
#define UNLOCK(lock) DO_UNLOCK(lock)
#else
#define LOCK(lock) { (void)(lock);
#define UNLOCK(lock) }
#endif

static entry* entries = NULL;
static bool notInitialized = true;
static long glock = LOCK_IS_FREE;

#define Lock(lock) while (_InterlockedCompareExchange(lock, LOCK_IS_TAKEN, LOCK_IS_FREE) == LOCK_IS_TAKEN){};
#define Unlock(lock) _InterlockedCompareExchange(lock, LOCK_IS_FREE, LOCK_IS_TAKEN);

#if defined(WIN32) && !defined(UNDER_CE)
	static void vprof_printf(const char* format, ...)
	{
		va_list args;
		va_start(args, format);

		char buf[1024];
		vsnprintf(buf, sizeof(buf), format, args);

		va_end(args);

		printf(buf);
		::OutputDebugStringA(buf);
	}
#else
	#define vprof_printf printf
#endif

inline static entry* reverse (entry* s)
{
    entry_t e, n, p;

    p = NULL;
    for (e = s; e; e = n) {
        n = e->next;
        e->next = p;
        p = e;
    }

    return p;
}

static char* f (double d)
{
    static char s[80];
    char* p;
    sprintf_s (s, sizeof(s), "%lf", d);
    p = s+VMPI_strlen(s)-1;
    while (*p == '0') {
        *p = '\0';
        p--;
        if (p == s) break;
    }
    if (*p == '.') *p = '\0';
    return s;
}

static void dumpProfile (void)
{
    entry_t e;

    entries = reverse(entries);
    vprof_printf ("event avg [min : max] total count\n");
    for (e = entries; e; e = e->next) {
        vprof_printf ("%s", e->file);
        if (e->line >= 0) {
            vprof_printf (":%d", e->line);
        }
        vprof_printf (" %s [%lld : %lld] %lld %lld ",
                f(((double)e->sum)/((double)e->count)), (long long int)e->min, (long long int)e->max, (long long int)e->sum, (long long int)e->count);
        if (e->h) {
            int j = MAXINT;
            for (j = 0; j < e->h->nbins; j ++) {
                vprof_printf ("(%lld < %lld) ", (long long int)e->h->count[j], (long long int)e->h->lb[j]);
            }
            vprof_printf ("(%lld >= %lld) ", (long long int)e->h->count[e->h->nbins], (long long int)e->h->lb[e->h->nbins-1]);
        }
        if (e->func) {
            int j;
            for (j = 0; j < NUM_EVARS; j++) {
                if (e->ivar[j] != 0) {
                    vprof_printf ("IVAR%d %d ", j, e->ivar[j]);
                }
            }
            for (j = 0; j < NUM_EVARS; j++) {
                if (e->i64var[j] != 0) {
                    vprof_printf ("I64VAR%d %lld ", j, (long long int)e->i64var[j]);
                }
            }
            for (j = 0; j < NUM_EVARS; j++) {
                if (e->dvar[j] != 0) {
                    vprof_printf ("DVAR%d %lf ", j, e->dvar[j]);
                }
            }
        }
        vprof_printf ("\n");
    }
    entries = reverse(entries);
}

int _profileEntryValue (void* id, int64_t value)
{
    entry_t e = (entry_t) id;
    long* lock = &(e->lock);
    LOCK (lock);
       e->value = value;
       e->sum += value;
       e->count ++;
       e->min = MIN (e->min, value);
       e->max = MAX (e->max, value);
       if (e->func) e->func (e);
    UNLOCK (lock);

    return 0;
}

inline static entry_t findEntry (char* file, int line)
{
    for (entry_t e =  entries; e; e = e->next) {
        if ((e->line == line) && (VMPI_strcmp (e->file, file) == 0)) {
            return e;
        }
    }
    return NULL;
}

int profileValue(void** id, char* file, int line, int64_t value, ...)
{
    DO_LOCK (&glock);
        entry_t e = (entry_t) *id;
        if (notInitialized) {
            atexit (dumpProfile);
            notInitialized = false;
        }

        if (e == NULL) {
            e = findEntry (file, line);
            if (e) {
                *id = e;
            }
        }

        if (e == NULL) {
            va_list va;
            e = (entry_t) malloc (sizeof(entry));
            e->lock = LOCK_IS_FREE;
            e->file = file;
            e->line = line;
            e->value = value;
            e->sum = value;
            e->count = 1;
            e->min = value;
            e->max = value;

            va_start (va, value);
            e->func = (void (__cdecl*)(void*)) va_arg (va, void*);
            va_end (va);

            e->h = NULL;

            e->genptr = NULL;

            VMPI_memset (&e->ivar,   0, sizeof(e->ivar));
            VMPI_memset (&e->i64var, 0, sizeof(e->i64var));
            VMPI_memset (&e->dvar,   0, sizeof(e->dvar));

            e->next = entries;
            entries = e;

            if (e->func) e->func (e);

            *id = e;
        } else {
            long* lock = &(e->lock);
            LOCK (lock);
                e->value = value;
                e->sum += value;
                e->count ++;
                e->min = MIN (e->min, value);
                e->max = MAX (e->max, value);
                if (e->func) e->func (e);
            UNLOCK (lock);
        }
    DO_UNLOCK (&glock);

    return 0;
}

int _histEntryValue (void* id, int64_t value)
{
    entry_t e = (entry_t) id;
    long* lock = &(e->lock);
    hist_t h = e->h;
    int nbins = h->nbins;
    int64_t* lb = h->lb;
    int b;

    for (b = 0; b < nbins; b ++) {
        if (value < lb[b]) break;
    }

    LOCK (lock);
       e->value = value;
       e->sum += value;
       e->count ++;
       e->min = MIN (e->min, value);
       e->max = MAX (e->max, value);
       h->count[b] ++;
    UNLOCK (lock);

    return 0;
}

int histValue(void** id, char* file, int line, int64_t value, int nbins, ...)
{
    DO_LOCK (&glock);
        entry_t e = (entry_t) *id;
        if (notInitialized) {
            atexit (dumpProfile);
            notInitialized = false;
        }

        if (e == NULL) {
            e = findEntry (file, line);
            if (e) {
                *id = e;
            }
        }

        if (e == NULL) {
            va_list va;
            hist_t h;
            int b, n, s;
            int64_t* lb;

            e = (entry_t) malloc (sizeof(entry));
            e->lock = LOCK_IS_FREE;
            e->file = file;
            e->line = line;
            e->value = value;
            e->sum = value;
            e->count = 1;
            e->min = value;
            e->max = value;
            e->func = NULL;
            e->h = h = (hist_t) malloc (sizeof(hist));
            n = 1+MAX(nbins,0);
            h->nbins = n-1;
            s = n*sizeof(int64_t);
            lb = (int64_t*) malloc (s);
            h->lb = lb;
            VMPI_memset (h->lb, 0, s);
            h->count = (int64_t*) malloc (s);
            VMPI_memset (h->count, 0, s);

            va_start (va, nbins);
            for (b = 0; b < nbins; b++) {
                //lb[b] = va_arg (va, int64_t);
                lb[b] = va_arg (va, int);
            }
            lb[b] = MAXINT64;
            va_end (va);

            for (b = 0; b < nbins; b ++) {
                if (value < lb[b]) break;
            }
            h->count[b] ++;

            e->genptr = NULL;

            VMPI_memset (&e->ivar,   0, sizeof(e->ivar));
            VMPI_memset (&e->i64var, 0, sizeof(e->i64var));
            VMPI_memset (&e->dvar,   0, sizeof(e->dvar));

            e->next = entries;
            entries = e;
            *id = e;
        } else {
            int b;
            long* lock = &(e->lock);
            hist_t h=e->h;
            int64_t* lb = h->lb;

            LOCK (lock);
                e->value = value;
                e->sum += value;
                e->count ++;
                e->min = MIN (e->min, value);
                e->max = MAX (e->max, value);
                for (b = 0; b < nbins; b ++) {
                    if (value < lb[b]) break;
                }
                h->count[b] ++;
            UNLOCK (lock);
        }
    DO_UNLOCK (&glock);

    return 0;
}

#if defined(_MSC_VER) && defined(_M_IX86)
inline uint64_t _rdtsc()
{
	// read the cpu cycle counter.  1 tick = 1 cycle on IA32
	_asm rdtsc;
}
#elif defined(__GNUC__) && (__i386__ || __x86_64__)
inline uint64_t _rdtsc()
{
   uint32_t lo, hi;
   __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
   return (uint64_t(hi) << 32) | lo;
}
#else
// add stub for platforms without it, so fat builds don't fail
inline uint64_t _rdtsc() { return 0; }
#endif

void* _tprof_before_id=0;
static uint64_t _tprof_before = 0;
int64_t _tprof_time()
{
    uint64_t now = _rdtsc();
    uint64_t v = _tprof_before ? now-_tprof_before : 0;
    _tprof_before = now;
    return v/2600; // v = microseconds on a 2.6ghz cpu
}

<|endoftext|>


<commit_before>/*
    Copyright (C) 1998 by Jorrit Tyberghein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdarg.h>

#include "cssysdef.h"
#include "video/canvas/svgalib/svga.h"
#include "csutil/csrect.h"
#include "cssys/csinput.h"
#include "isystem.h"

static unsigned short ScanCodeToChar[128] =
{
  CSKEY_ESC,27,       '1',      '2',      '3',      '4',      '5',      '6',    // 00..07
  '7',      '8',      '9',      '0',      '-',      '=',      '\b',     '\t',   // 08..0F
  'q',      'w',      'e',      'r',      't',      'y',      'u',      'i',    // 10..17
  'o',      'p',      '[',      ']',      '\n',     CSKEY_CTRL,'a',     's',    // 18..1F
  'd',      'f',      'g',      'h',      'j',      'k',      'l',      ';',    // 20..27
  39,       '`',      CSKEY_SHIFT,'\\',   'z',      'x',      'c',      'v',    // 28..2F
  'b',      'n',      'm',      ',',      '.',      '/',      CSKEY_SHIFT,'*',  // 30..37
  CSKEY_ALT,' ',      0,        CSKEY_F1, CSKEY_F2, CSKEY_F3, CSKEY_F4, CSKEY_F5,// 38..3F
  CSKEY_F6,  CSKEY_F7, CSKEY_F8, CSKEY_F9, CSKEY_F10,0,       0,        CSKEY_HOME,// 40..47
  CSKEY_UP,  CSKEY_PGUP,'-',    CSKEY_LEFT,CSKEY_CENTER,CSKEY_RIGHT,'+',CSKEY_END,// 48..4F
  CSKEY_DOWN,CSKEY_PGDN,CSKEY_INS,CSKEY_DEL,0,      0,        0,        CSKEY_F11,// 50..57
  CSKEY_F12,0,        0,        0,        0,        0,        0,        0,      // 58..5F
  CSKEY_ENTER,CSKEY_CTRL,'/',   0,CSKEY_ALT,        0,CSKEY_HOME,CSKEY_UP,      // 60..67
  CSKEY_PGUP,CSKEY_LEFT,CSKEY_RIGHT,CSKEY_END,CSKEY_DOWN,CSKEY_PGDN,CSKEY_INS,CSKEY_DEL,// 68..6F
  0,        0,        0,        0,        0,        0,        0,        0,      // 70..77
  0,        0,        0,        0,        0,        0,        0,        0       // 78..7F
};

IMPLEMENT_FACTORY (csGraphics2DSVGALib)

EXPORT_CLASS_TABLE (svga2d)
  EXPORT_CLASS_DEP (csGraphics2DSVGALib, "crystalspace.graphics2d.svgalib",
    "SVGALib 2D graphics driver for Crystal Space", "crystalspace.font.server.")
EXPORT_CLASS_TABLE_END

IMPLEMENT_IBASE (csGraphics2DSVGALib)
  IMPLEMENTS_INTERFACE (iPlugIn)
  IMPLEMENTS_INTERFACE (iGraphics2D)
  IMPLEMENTS_INTERFACE (iEventPlug)
IMPLEMENT_IBASE_END

// csGraphics2DSVGALib functions
csGraphics2DSVGALib::csGraphics2DSVGALib(iBase *iParent) : csGraphics2D ()
{
  CONSTRUCT_IBASE (iParent);
  EventOutlet = NULL;
}

bool csGraphics2DSVGALib::Initialize (iSystem *pSystem)
{
  if (!csGraphics2D::Initialize (pSystem))
    return false;

  Font = 0;
  Memory = NULL;

  // SVGALIB Starts here

  CsPrintf (MSG_INITIALIZATION, "Crystal Space Linux/SVGALIB version.\n");
  CsPrintf (MSG_INITIALIZATION,  "Using %dx%dx%d resolution.\n\n", Width, Height, Depth);

  gl_copyscreen (&physicalscreen);

  Memory = NULL;

  switch (Depth)
  {
    case 8:
      pfmt.RedMask = pfmt.GreenMask = pfmt.BlueMask = 0;
      pfmt.PalEntries = 256; pfmt.PixelBytes = 1;
      break;

    case 15:
      pfmt.RedMask   = 0x1f << 10;
      pfmt.GreenMask = 0x1f << 5;
      pfmt.BlueMask  = 0x1f;
      pfmt.PalEntries = 0;
      pfmt.PixelBytes = 2;

      _DrawPixel = DrawPixel16;
      _WriteString = WriteString16;
      _GetPixelAt = GetPixelAt16;
      break;

    case 16:
      pfmt.RedMask   = 0x1f << 11;
      pfmt.GreenMask = 0x3f << 5;
      pfmt.BlueMask  = 0x1f;
      pfmt.PalEntries = 0;
      pfmt.PixelBytes = 2;

      _DrawPixel = DrawPixel16;
      _WriteString = WriteString16;
      _GetPixelAt = GetPixelAt16;
      break;

    case 32:
      pfmt.RedMask   = 0xff << 16;
      pfmt.GreenMask = 0xff << 8;
      pfmt.BlueMask  = 0xff;
      pfmt.PalEntries = 0;
      pfmt.PixelBytes = 4;

      _DrawPixel = DrawPixel32;
      _WriteString = WriteString32;
      _GetPixelAt = GetPixelAt32;
      break;
  }

  pfmt.complete ();

  mouse_x = mouse_y = -1;
  memset (mouse_button , 0, sizeof (mouse_button));
  memset (keydown, 0, sizeof (keydown));

  // Tell system driver to call us on every frame
  System->CallOnEvents (this, CSMASK_Nothing);
  // Create the event outlet
  EventOutlet = System->CreateEventOutlet (this);

  return true;
}

csGraphics2DSVGALib::~csGraphics2DSVGALib(void)
{
  // Destroy your graphic interface
  Close();
  if (EventOutlet)
    EventOutlet->DecRef ();
}

bool csGraphics2DSVGALib::Open(const char *Title)
{
  // Open your graphic interface
  if (!csGraphics2D::Open (Title))
    return false;

  vga_init ();

  // Enable mouse support in SVGALIB
  vga_setmousesupport (1);

  int vgamode;
  char modestr[50],depthstr[10];

  switch (Depth)
  {
    case 8  :
      sprintf (depthstr, "256");
      break;
    case 15 :
      sprintf (depthstr, "32K");
      break;
    case 16 :
      sprintf (depthstr, "64K");
      break;
    case 32 :
      sprintf (depthstr, "16M32");
      break;
    default :
      CsPrintf (MSG_FATAL_ERROR, "Unsupported depth %d\n", Depth);
      return false;
  }

  sprintf (modestr, "G%dx%dx%s", Width, Height, depthstr);
  vgamode = vga_getmodenumber (modestr);

  if ((vgamode==-1) || (vga_setmode (vgamode) == -1))
  {
    CsPrintf (MSG_FATAL_ERROR, "Specified screenmode %s is not available!\n", modestr);
    return false;
  }

  gl_setcontextvga (vgamode);
  gl_getcontext (&physicalscreen);
  gl_setcontextvgavirtual (vgamode);
  Memory = (unsigned char*)VBUF;
  gl_enablepageflipping (&physicalscreen);

  keyboard_init ();
#if !defined (OS_DOS)
//mouse_setxrange (0, Width-1);
//mouse_setyrange (0, Height-1);
//mouse_setwrap (MOUSE_NOWRAP);
#endif // OS_DOS

  Clear (0);
  return true;
}

void csGraphics2DSVGALib::Close(void)
{
  // Close your graphic interface
  keyboard_close ();
  vga_setmode (TEXT);
  csGraphics2D::Close ();
}

bool csGraphics2DSVGALib::HandleEvent (iEvent &/*Event*/)
{
  static int mouse_button_mask [3] =
  { MOUSE_LEFTBUTTON, MOUSE_RIGHTBUTTON, MOUSE_MIDDLEBUTTON };

  keyboard_update ();
/*
  bool shift = keyboard_keypressed (SCANCODE_LEFTSHIFT)
            || keyboard_keypressed (SCANCODE_RIGHTSHIFT);
  bool alt   = keyboard_keypressed (SCANCODE_LEFTALT)
            || keyboard_keypressed (SCANCODE_RIGHTALT);
  bool ctrl  = keyboard_keypressed (SCANCODE_LEFTCONTROL);
  int state = (shift ? CSMASK_SHIFT : 0) | (alt ? CSMASK_ALT : 0) | (ctrl ? CSMASK_CTRL : 0);
*/
  for (unsigned int scancode = 0; scancode < 128; scancode++)
  {
    int key = ScanCodeToChar [scancode];
    bool down = key ? keyboard_keypressed (scancode) : false;
    if (down != keydown [scancode])
    {
      keydown [scancode] = down;
      EventOutlet->Key (key, -1, down);
    }
  }

  if (mouse_update ())
  {
    int x = mouse_getx ();
    int y = mouse_gety ();
    if ((x != mouse_x) || (y != mouse_y))
    {
      mouse_x = x; mouse_y = y;
      EventOutlet->Mouse (0, false, x, y);
    }

    int buttons = mouse_getbutton ();
    for (int button = 0; button < 3; button++)
    {
      bool down = (buttons & mouse_button_mask [button]) != 0;
      if (down != mouse_button [button])
      {
        mouse_button [button] = down;
        EventOutlet->Mouse (button + 1, down, x, y);
      }
    }
  }
  return false;
}

void csGraphics2DSVGALib::Print (csRect * /*area*/)
{
  gl_copyscreen (&physicalscreen);
}

void csGraphics2DSVGALib::SetRGB(int i, int r, int g, int b)
{
  if (pfmt.PalEntries)
    vga_setpalette (i, r/4, g/4, b/4);

  csGraphics2D::SetRGB (i, r, g, b);
}
<commit_msg>removed Font variable<commit_after>/*
    Copyright (C) 1998 by Jorrit Tyberghein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdarg.h>

#include "cssysdef.h"
#include "video/canvas/svgalib/svga.h"
#include "csutil/csrect.h"
#include "cssys/csinput.h"
#include "isystem.h"

static unsigned short ScanCodeToChar[128] =
{
  CSKEY_ESC,27,       '1',      '2',      '3',      '4',      '5',      '6',    // 00..07
  '7',      '8',      '9',      '0',      '-',      '=',      '\b',     '\t',   // 08..0F
  'q',      'w',      'e',      'r',      't',      'y',      'u',      'i',    // 10..17
  'o',      'p',      '[',      ']',      '\n',     CSKEY_CTRL,'a',     's',    // 18..1F
  'd',      'f',      'g',      'h',      'j',      'k',      'l',      ';',    // 20..27
  39,       '`',      CSKEY_SHIFT,'\\',   'z',      'x',      'c',      'v',    // 28..2F
  'b',      'n',      'm',      ',',      '.',      '/',      CSKEY_SHIFT,'*',  // 30..37
  CSKEY_ALT,' ',      0,        CSKEY_F1, CSKEY_F2, CSKEY_F3, CSKEY_F4, CSKEY_F5,// 38..3F
  CSKEY_F6,  CSKEY_F7, CSKEY_F8, CSKEY_F9, CSKEY_F10,0,       0,        CSKEY_HOME,// 40..47
  CSKEY_UP,  CSKEY_PGUP,'-',    CSKEY_LEFT,CSKEY_CENTER,CSKEY_RIGHT,'+',CSKEY_END,// 48..4F
  CSKEY_DOWN,CSKEY_PGDN,CSKEY_INS,CSKEY_DEL,0,      0,        0,        CSKEY_F11,// 50..57
  CSKEY_F12,0,        0,        0,        0,        0,        0,        0,      // 58..5F
  CSKEY_ENTER,CSKEY_CTRL,'/',   0,CSKEY_ALT,        0,CSKEY_HOME,CSKEY_UP,      // 60..67
  CSKEY_PGUP,CSKEY_LEFT,CSKEY_RIGHT,CSKEY_END,CSKEY_DOWN,CSKEY_PGDN,CSKEY_INS,CSKEY_DEL,// 68..6F
  0,        0,        0,        0,        0,        0,        0,        0,      // 70..77
  0,        0,        0,        0,        0,        0,        0,        0       // 78..7F
};

IMPLEMENT_FACTORY (csGraphics2DSVGALib)

EXPORT_CLASS_TABLE (svga2d)
  EXPORT_CLASS_DEP (csGraphics2DSVGALib, "crystalspace.graphics2d.svgalib",
    "SVGALib 2D graphics driver for Crystal Space", "crystalspace.font.server.")
EXPORT_CLASS_TABLE_END

IMPLEMENT_IBASE (csGraphics2DSVGALib)
  IMPLEMENTS_INTERFACE (iPlugIn)
  IMPLEMENTS_INTERFACE (iGraphics2D)
  IMPLEMENTS_INTERFACE (iEventPlug)
IMPLEMENT_IBASE_END

// csGraphics2DSVGALib functions
csGraphics2DSVGALib::csGraphics2DSVGALib(iBase *iParent) : csGraphics2D ()
{
  CONSTRUCT_IBASE (iParent);
  EventOutlet = NULL;
}

bool csGraphics2DSVGALib::Initialize (iSystem *pSystem)
{
  if (!csGraphics2D::Initialize (pSystem))
    return false;

  Memory = NULL;

  // SVGALIB Starts here

  CsPrintf (MSG_INITIALIZATION, "Crystal Space Linux/SVGALIB version.\n");
  CsPrintf (MSG_INITIALIZATION,  "Using %dx%dx%d resolution.\n\n", Width, Height, Depth);

  gl_copyscreen (&physicalscreen);

  Memory = NULL;

  switch (Depth)
  {
    case 8:
      pfmt.RedMask = pfmt.GreenMask = pfmt.BlueMask = 0;
      pfmt.PalEntries = 256; pfmt.PixelBytes = 1;
      break;

    case 15:
      pfmt.RedMask   = 0x1f << 10;
      pfmt.GreenMask = 0x1f << 5;
      pfmt.BlueMask  = 0x1f;
      pfmt.PalEntries = 0;
      pfmt.PixelBytes = 2;

      _DrawPixel = DrawPixel16;
      _WriteString = WriteString16;
      _GetPixelAt = GetPixelAt16;
      break;

    case 16:
      pfmt.RedMask   = 0x1f << 11;
      pfmt.GreenMask = 0x3f << 5;
      pfmt.BlueMask  = 0x1f;
      pfmt.PalEntries = 0;
      pfmt.PixelBytes = 2;

      _DrawPixel = DrawPixel16;
      _WriteString = WriteString16;
      _GetPixelAt = GetPixelAt16;
      break;

    case 32:
      pfmt.RedMask   = 0xff << 16;
      pfmt.GreenMask = 0xff << 8;
      pfmt.BlueMask  = 0xff;
      pfmt.PalEntries = 0;
      pfmt.PixelBytes = 4;

      _DrawPixel = DrawPixel32;
      _WriteString = WriteString32;
      _GetPixelAt = GetPixelAt32;
      break;
  }

  pfmt.complete ();

  mouse_x = mouse_y = -1;
  memset (mouse_button , 0, sizeof (mouse_button));
  memset (keydown, 0, sizeof (keydown));

  // Tell system driver to call us on every frame
  System->CallOnEvents (this, CSMASK_Nothing);
  // Create the event outlet
  EventOutlet = System->CreateEventOutlet (this);

  return true;
}

csGraphics2DSVGALib::~csGraphics2DSVGALib(void)
{
  // Destroy your graphic interface
  Close();
  if (EventOutlet)
    EventOutlet->DecRef ();
}

bool csGraphics2DSVGALib::Open(const char *Title)
{
  // Open your graphic interface
  if (!csGraphics2D::Open (Title))
    return false;

  vga_init ();

  // Enable mouse support in SVGALIB
  vga_setmousesupport (1);

  int vgamode;
  char modestr[50],depthstr[10];

  switch (Depth)
  {
    case 8  :
      sprintf (depthstr, "256");
      break;
    case 15 :
      sprintf (depthstr, "32K");
      break;
    case 16 :
      sprintf (depthstr, "64K");
      break;
    case 32 :
      sprintf (depthstr, "16M32");
      break;
    default :
      CsPrintf (MSG_FATAL_ERROR, "Unsupported depth %d\n", Depth);
      return false;
  }

  sprintf (modestr, "G%dx%dx%s", Width, Height, depthstr);
  vgamode = vga_getmodenumber (modestr);

  if ((vgamode==-1) || (vga_setmode (vgamode) == -1))
  {
    CsPrintf (MSG_FATAL_ERROR, "Specified screenmode %s is not available!\n", modestr);
    return false;
  }

  gl_setcontextvga (vgamode);
  gl_getcontext (&physicalscreen);
  gl_setcontextvgavirtual (vgamode);
  Memory = (unsigned char*)VBUF;
  gl_enablepageflipping (&physicalscreen);

  keyboard_init ();
#if !defined (OS_DOS)
//mouse_setxrange (0, Width-1);
//mouse_setyrange (0, Height-1);
//mouse_setwrap (MOUSE_NOWRAP);
#endif // OS_DOS

  Clear (0);
  return true;
}

void csGraphics2DSVGALib::Close(void)
{
  // Close your graphic interface
  keyboard_close ();
  vga_setmode (TEXT);
  csGraphics2D::Close ();
}

bool csGraphics2DSVGALib::HandleEvent (iEvent &/*Event*/)
{
  static int mouse_button_mask [3] =
  { MOUSE_LEFTBUTTON, MOUSE_RIGHTBUTTON, MOUSE_MIDDLEBUTTON };

  keyboard_update ();
/*
  bool shift = keyboard_keypressed (SCANCODE_LEFTSHIFT)
            || keyboard_keypressed (SCANCODE_RIGHTSHIFT);
  bool alt   = keyboard_keypressed (SCANCODE_LEFTALT)
            || keyboard_keypressed (SCANCODE_RIGHTALT);
  bool ctrl  = keyboard_keypressed (SCANCODE_LEFTCONTROL);
  int state = (shift ? CSMASK_SHIFT : 0) | (alt ? CSMASK_ALT : 0) | (ctrl ? CSMASK_CTRL : 0);
*/
  for (unsigned int scancode = 0; scancode < 128; scancode++)
  {
    int key = ScanCodeToChar [scancode];
    bool down = key ? keyboard_keypressed (scancode) : false;
    if (down != keydown [scancode])
    {
      keydown [scancode] = down;
      EventOutlet->Key (key, -1, down);
    }
  }

  if (mouse_update ())
  {
    int x = mouse_getx ();
    int y = mouse_gety ();
    if ((x != mouse_x) || (y != mouse_y))
    {
      mouse_x = x; mouse_y = y;
      EventOutlet->Mouse (0, false, x, y);
    }

    int buttons = mouse_getbutton ();
    for (int button = 0; button < 3; button++)
    {
      bool down = (buttons & mouse_button_mask [button]) != 0;
      if (down != mouse_button [button])
      {
        mouse_button [button] = down;
        EventOutlet->Mouse (button + 1, down, x, y);
      }
    }
  }
  return false;
}

void csGraphics2DSVGALib::Print (csRect * /*area*/)
{
  gl_copyscreen (&physicalscreen);
}

void csGraphics2DSVGALib::SetRGB(int i, int r, int g, int b)
{
  if (pfmt.PalEntries)
    vga_setpalette (i, r/4, g/4, b/4);

  csGraphics2D::SetRGB (i, r, g, b);
}
<|endoftext|>


<commit_before>#include "VSprite.h"
#include "VGlobal.h"

void VSprite::setSize(unsigned int texWidth, unsigned int texHeight, bool animated, int width, int height, int offsetX, int offsetY)
{
	Size = sf::Vector2f(sf::Vector2u(width, height));

	if (Size.x <= 0)
	{
		Size.x = static_cast<float>(animated ? texHeight : texWidth);
		Size.x = static_cast<float>(Size.x > texWidth ? texWidth : Size.x);
	}
	if (Size.y <= 0)
	{
		Size.y = static_cast<float>(animated ? Size.x : texHeight);
		Size.y = static_cast<float>(Size.y > texHeight ? texHeight : Size.y);
	}

	FrameSize = sf::Vector2u(Size);
	Animation = VAnimationManager(texWidth, texHeight, FrameSize.x, FrameSize.y, offsetX, offsetY);
	Origin = sf::Vector2f(FrameSize) / 2.0f;

	Radius = Size.x < Size.y ? Size.x / 2 : Size.y / 2;

	vertexArray[0].position = sf::Vector2f();
	vertexArray[1].position = sf::Vector2f(Size.x, 0.0f);
	vertexArray[2].position = sf::Vector2f(Size.x, Size.y);
	vertexArray[3].position = sf::Vector2f(0.0f, Size.y);
}

void VSprite::updateTransform()
{
	float angle = -Angle * 3.141592654f / 180.f;
	float cosine = static_cast<float>(std::cos(angle));
	float sine = static_cast<float>(std::sin(angle));
	float sxc = Scale.x * cosine;
	float syc = Scale.y * cosine;
	float sxs = Scale.x * sine;
	float sys = Scale.y * sine;
	float tx = -Origin.x * sxc - Origin.y * sys + (Position + Origin - Offset).x;
	float ty =  Origin.x * sxs - Origin.y * syc + (Position + Origin - Offset).y;

	RenderState.transform =
		sf::Transform(	sxc, sys, tx,
						-sxs, syc, ty,
						0.f, 0.f, 1.f);

	if (vertexArray[0].color != Tint)
	{
		vertexArray[0].color = Tint;
		vertexArray[1].color = Tint;
		vertexArray[2].color = Tint;
		vertexArray[3].color = Tint;
	}
}

void VSprite::updateFrame()
{
	sf::FloatRect rect;
	rect.left		= FlipX ? Animation.GetU() + FrameSize.x : Animation.GetU();
	rect.top		= FlipY ? Animation.GetV() + FrameSize.y : Animation.GetV();
	rect.width		= FlipX ? -(float)FrameSize.x : (float)FrameSize.x;
	rect.height		= FlipY ? -(float)FrameSize.y : (float)FrameSize.y;
	vertexArray[0].texCoords = sf::Vector2f(rect.left,				rect.top);
	vertexArray[1].texCoords = sf::Vector2f(rect.left + rect.width, rect.top);
	vertexArray[2].texCoords = sf::Vector2f(rect.left + rect.width, rect.top + rect.height);
	vertexArray[3].texCoords = sf::Vector2f(rect.left,				rect.top + rect.height);
}

VSprite* VSprite::LoadGraphic(sf::String filename, bool animated, int width, int height, const sf::IntRect& area)
{
	RenderState.texture = &VGlobal::p()->Content->LoadTexture(filename);

	setSize(
		area.width == 0 ? RenderState.texture->getSize().x : area.width,
		area.height == 0 ? RenderState.texture->getSize().y : area.height,
		animated, width, height, area.left, area.top
		);

	updateFrame();

	return this;
}

VSprite* VSprite::LoadGraphicFromTexture(sf::Texture& texture, bool animated, int width, int height, const sf::IntRect& area)
{
	RenderState.texture = &texture;

	setSize(
		area.width == 0 ? RenderState.texture->getSize().x : area.width,
		area.height == 0 ? RenderState.texture->getSize().y : area.height,
		animated, width, height, area.left, area.top
		);

	updateFrame();
	return this;
}

VSprite* VSprite::MakeGraphic(int width, int height, sf::Color color, float outline, sf::Color outlineColor)
{
	if (disposible && RenderState.texture)
	{
		delete RenderState.texture;
		RenderState.texture = nullptr;
		disposible = false;
	}

	sf::Image image;
	image.create(width, height, color);

	for (int y = 0; y < height; y++)
	{
		for (int x = 0; x < width; x++)
		{
			if (x < outline || y < outline || x > width - outline || y > height - outline)
			{
				image.setPixel(x, y, outlineColor);
			}
		}
	}

	sf::Texture* texture = new sf::Texture();
	texture->loadFromImage(image);
	disposible = true;

	RenderState.texture = texture;
	setSize(width, height, false, width, height);

	return this;
}

VSprite* VSprite::MakeGraphicCircle(int radius, sf::Color color, float outline, sf::Color outlineColor)
{
	if (disposible && RenderState.texture)
	{
		delete RenderState.texture;
		RenderState.texture = nullptr;
		disposible = false;
	}

	unsigned int diameter = radius * 2;

	sf::Image image;
	image.create(diameter, diameter, sf::Color::Transparent);

	for (unsigned int y = 0; y < diameter; y++)
	{
		for (unsigned int x = 0; x < diameter; x++)
		{
			int dx = radius - x;
			int dy = radius - y;
			int length = (dx * dx) + (dy * dy);

			if (length <= (radius * radius))
			{
				if (outline <= 0 || length <= ((radius - outline) * (radius - outline)))
					image.setPixel(x, y, color);
				else
					image.setPixel(x, y, outlineColor);
			}
		}
	}

	sf::Texture* texture = new sf::Texture();
	texture->loadFromImage(image);
	disposible = true;

	RenderState.texture = texture;
	setSize(radius * 2, radius * 2, false, radius * 2, radius * 2);

	return this;
}

void VSprite::Destroy()
{
	VSUPERCLASS::Destroy();

	if (disposible && RenderState.texture)
	{
		delete RenderState.texture;
		RenderState.texture = nullptr;
		disposible = false;
	}
}

void VSprite::Update(float dt)
{
	VSUPERCLASS::Update(dt);

	Animation.Update(dt);

	bool updateTexture = false;
	if (Animation.GetLastFrame() != Animation.GetCurrentFrame())
		updateTexture = true;

	if ((FlipX && vertexArray[2].texCoords.x - vertexArray[0].texCoords.x > 0) || (!FlipX && vertexArray[2].texCoords.x - vertexArray[0].texCoords.x < 0))
		updateTexture = true;

	if ((FlipY && vertexArray[2].texCoords.y - vertexArray[0].texCoords.y > 0) || (!FlipY && vertexArray[2].texCoords.y - vertexArray[0].texCoords.y < 0))
		updateTexture = true;

	if (updateTexture)
	{
		updateFrame();
	}
}

void VSprite::Draw(sf::RenderTarget& RenderTarget)
{
	VSUPERCLASS::Draw(RenderTarget);

	sf::View renderTargetView = RenderTarget.getView();
	sf::View scrollView = RenderTarget.getDefaultView();

	if (TestInView(renderTargetView, scrollView, this, RenderState.transform.transformRect(vertexArray.getBounds())))
	{
		RenderTarget.setView(scrollView);
		RenderTarget.draw(vertexArray, RenderState);
		RenderTarget.setView(renderTargetView);
	}
}<commit_msg>Fixed flipping for sprites.<commit_after>#include "VSprite.h"
#include "VGlobal.h"

void VSprite::setSize(unsigned int texWidth, unsigned int texHeight, bool animated, int width, int height, int offsetX, int offsetY)
{
	Size = sf::Vector2f(sf::Vector2u(width, height));

	if (Size.x <= 0)
	{
		Size.x = static_cast<float>(animated ? texHeight : texWidth);
		Size.x = static_cast<float>(Size.x > texWidth ? texWidth : Size.x);
	}
	if (Size.y <= 0)
	{
		Size.y = static_cast<float>(animated ? Size.x : texHeight);
		Size.y = static_cast<float>(Size.y > texHeight ? texHeight : Size.y);
	}

	FrameSize = sf::Vector2u(Size);
	Animation = VAnimationManager(texWidth, texHeight, FrameSize.x, FrameSize.y, offsetX, offsetY);
	Origin = sf::Vector2f(FrameSize) / 2.0f;

	Radius = Size.x < Size.y ? Size.x / 2 : Size.y / 2;

	vertexArray[0].position = sf::Vector2f();
	vertexArray[1].position = sf::Vector2f(Size.x, 0.0f);
	vertexArray[2].position = sf::Vector2f(Size.x, Size.y);
	vertexArray[3].position = sf::Vector2f(0.0f, Size.y);
}

void VSprite::updateTransform()
{
	float angle = -Angle * 3.141592654f / 180.f;
	float cosine = static_cast<float>(std::cos(angle));
	float sine = static_cast<float>(std::sin(angle));
	float sxc = Scale.x * cosine;
	float syc = Scale.y * cosine;
	float sxs = Scale.x * sine;
	float sys = Scale.y * sine;
	float tx = -Origin.x * sxc - Origin.y * sys + (Position + Origin - Offset).x;
	float ty =  Origin.x * sxs - Origin.y * syc + (Position + Origin - Offset).y;

	RenderState.transform =
		sf::Transform(	sxc, sys, tx,
						-sxs, syc, ty,
						0.f, 0.f, 1.f);

	if (vertexArray[0].color != Tint)
	{
		vertexArray[0].color = Tint;
		vertexArray[1].color = Tint;
		vertexArray[2].color = Tint;
		vertexArray[3].color = Tint;
	}
}

void VSprite::updateFrame()
{
	sf::FloatRect rect;
	rect.left		= FlipX ? Animation.GetU() + (float)FrameSize.x : Animation.GetU();
	rect.top		= FlipY ? Animation.GetV() + (float)FrameSize.y : Animation.GetV();
	rect.width		= FlipX ? -(float)FrameSize.x : (float)FrameSize.x;
	rect.height		= FlipY ? -(float)FrameSize.y : (float)FrameSize.y;
	vertexArray[0].texCoords = sf::Vector2f(rect.left,				rect.top);
	vertexArray[1].texCoords = sf::Vector2f(rect.left + rect.width, rect.top);
	vertexArray[2].texCoords = sf::Vector2f(rect.left + rect.width, rect.top + rect.height);
	vertexArray[3].texCoords = sf::Vector2f(rect.left,				rect.top + rect.height);
}

VSprite* VSprite::LoadGraphic(sf::String filename, bool animated, int width, int height, const sf::IntRect& area)
{
	RenderState.texture = &VGlobal::p()->Content->LoadTexture(filename);

	setSize(
		area.width == 0 ? RenderState.texture->getSize().x : area.width,
		area.height == 0 ? RenderState.texture->getSize().y : area.height,
		animated, width, height, area.left, area.top
		);

	updateFrame();

	return this;
}

VSprite* VSprite::LoadGraphicFromTexture(sf::Texture& texture, bool animated, int width, int height, const sf::IntRect& area)
{
	RenderState.texture = &texture;

	setSize(
		area.width == 0 ? RenderState.texture->getSize().x : area.width,
		area.height == 0 ? RenderState.texture->getSize().y : area.height,
		animated, width, height, area.left, area.top
		);

	updateFrame();
	return this;
}

VSprite* VSprite::MakeGraphic(int width, int height, sf::Color color, float outline, sf::Color outlineColor)
{
	if (disposible && RenderState.texture)
	{
		delete RenderState.texture;
		RenderState.texture = nullptr;
		disposible = false;
	}

	sf::Image image;
	image.create(width, height, color);

	for (int y = 0; y < height; y++)
	{
		for (int x = 0; x < width; x++)
		{
			if (x < outline || y < outline || x > width - outline || y > height - outline)
			{
				image.setPixel(x, y, outlineColor);
			}
		}
	}

	sf::Texture* texture = new sf::Texture();
	texture->loadFromImage(image);
	disposible = true;

	RenderState.texture = texture;
	setSize(width, height, false, width, height);

	return this;
}

VSprite* VSprite::MakeGraphicCircle(int radius, sf::Color color, float outline, sf::Color outlineColor)
{
	if (disposible && RenderState.texture)
	{
		delete RenderState.texture;
		RenderState.texture = nullptr;
		disposible = false;
	}

	unsigned int diameter = radius * 2;

	sf::Image image;
	image.create(diameter, diameter, sf::Color::Transparent);

	for (unsigned int y = 0; y < diameter; y++)
	{
		for (unsigned int x = 0; x < diameter; x++)
		{
			int dx = radius - x;
			int dy = radius - y;
			int length = (dx * dx) + (dy * dy);

			if (length <= (radius * radius))
			{
				if (outline <= 0 || length <= ((radius - outline) * (radius - outline)))
					image.setPixel(x, y, color);
				else
					image.setPixel(x, y, outlineColor);
			}
		}
	}

	sf::Texture* texture = new sf::Texture();
	texture->loadFromImage(image);
	disposible = true;

	RenderState.texture = texture;
	setSize(radius * 2, radius * 2, false, radius * 2, radius * 2);

	return this;
}

void VSprite::Destroy()
{
	VSUPERCLASS::Destroy();

	if (disposible && RenderState.texture)
	{
		delete RenderState.texture;
		RenderState.texture = nullptr;
		disposible = false;
	}
}

void VSprite::Update(float dt)
{
	VSUPERCLASS::Update(dt);

	Animation.Update(dt);

	bool updateTexture = false;
	if (Animation.GetLastFrame() != Animation.GetCurrentFrame())
		updateTexture = true;

	if ((FlipX && vertexArray[2].texCoords.x - vertexArray[0].texCoords.x > 0) || (!FlipX && vertexArray[2].texCoords.x - vertexArray[0].texCoords.x < 0))
		updateTexture = true;

	if ((FlipY && vertexArray[2].texCoords.y - vertexArray[0].texCoords.y > 0) || (!FlipY && vertexArray[2].texCoords.y - vertexArray[0].texCoords.y < 0))
		updateTexture = true;

	if (updateTexture)
	{
		updateFrame();
	}
}

void VSprite::Draw(sf::RenderTarget& RenderTarget)
{
	VSUPERCLASS::Draw(RenderTarget);

	sf::View renderTargetView = RenderTarget.getView();
	sf::View scrollView = RenderTarget.getDefaultView();

	if (TestInView(renderTargetView, scrollView, this, RenderState.transform.transformRect(vertexArray.getBounds())))
	{
		RenderTarget.setView(scrollView);
		RenderTarget.draw(vertexArray, RenderState);
		RenderTarget.setView(renderTargetView);
	}
}<|endoftext|>