<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	FT5206 class @n
			FocalTech @n
			Capacitive Touch Panel Controller ドライバー @n
			・I2C 割り込み対応
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>
#include "common/delay.hpp"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  FT5206 テンプレートクラス
		@param[in]	I2C	I2C 制御クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class I2C>
	class FT5206 {
	public:
		struct xy {
			uint8_t		st;
			uint16_t	x;
			uint16_t	y;
			xy() : st(0), x(0), y(0) { }
		};

	private:
		static const uint8_t	FT5206_ADR = 0x38;

		I2C&	i2c_;

		enum class REG : uint8_t {
			DEVICE_MODE,		// R/W
			GEST_ID,			// R
			TD_STATUS,			// R
			TOUCH_XH,			// R
			TOUCH_XL,			// R
			TOUCH_YH,			// R
			TOUCH_YL,			// R

			TOUCH2_XH = 0x09,	// R
			TOUCH2_XL,			// R
			TOUCH2_YH,			// R
			TOUCH2_YL,			// R

			TOUCH3_XH = 0x0F,	// R
			TOUCH3_XL,			// R
			TOUCH3_YH,			// R
			TOUCH3_YL,			// R

			TOUCH4_XH = 0x15,	// R
			TOUCH4_XL,			// R
			TOUCH4_YH,			// R
			TOUCH4_YL,			// R

			TOUCH5_XH = 0x1B,	// R
			TOUCH5_XL,			// R
			TOUCH5_YH,			// R
			TOUCH5_YL,			// R

			ID_G_THGROUP = 0x80,		// R/W
			ID_G_THPEAK,				// R/W
			ID_G_THCAL,					// R/W
			ID_G_THWATER,				// R/W
			ID_G_THTEMP,				// R/W

			ID_G_CTRL = 0x86,			// R/W
			ID_G_TIME_ENTER_MONITOR,	// R/W
			ID_G_PERIODACTIVE,			// R/W
			ID_G_PERIODMONITOR,			// R/W

			ID_G_AUTO_CLB_MODE = 0xA0,	// R/W
			ID_G_LIB_VERSION_H,			// R
			ID_G_LIB_VERSION_L,			// R
			ID_G_CIPHER,				// R
			ID_G_MODE,					// R
			ID_G_PMODE,					// R
			ID_G_FIRMID,				// R
			ID_G_STATE,					// R
			ID_G_FT5201ID,				// R
			ID_G_ERR,					// R
			ID_G_CLB,					// R/W

			ID_G_B_AREA_TH = 0xAE,		// R/W

			LOG_MSG_CNT = 0xFE,			// R
			LOG_CUR_CHA					// R
		};

		uint8_t		touch_num_;
		bool		start_;
		uint16_t	version_;
		uint8_t		chip_;
		uint8_t		touch_tmp_[11];
		xy			xy_[2];

		void write_(REG reg, uint8_t data) noexcept
		{
			uint8_t tmp[2];
			tmp[0] = static_cast<uint8_t>(reg);
			tmp[1] = data;
			i2c_.send(FT5206_ADR, tmp, sizeof(tmp));
			i2c_.sync();
		}

		uint8_t read_(REG reg) noexcept
		{
			uint8_t tmp[1];
			tmp[0] = static_cast<uint8_t>(reg);
			i2c_.send(FT5206_ADR, tmp, sizeof(tmp));
			i2c_.recv(FT5206_ADR, tmp, sizeof(tmp));
			i2c_.sync();
			return tmp[0];
		}

		void convert_touch_() noexcept
		{
			touch_num_ = touch_tmp_[0];
			if(touch_num_ == 0) return;

			if(touch_num_ >= 1) {
				xy_[0].st = touch_tmp_[1] >> 6;
				xy_[0].x = (static_cast<uint16_t>(touch_tmp_[1] & 0x3F) << 8)
					| static_cast<uint16_t>(touch_tmp_[2]);
				xy_[0].y = (static_cast<uint16_t>(touch_tmp_[3]) << 8)
					| static_cast<uint16_t>(touch_tmp_[4]);
			}
			if(touch_num_ > 1) {
				xy_[1].st = touch_tmp_[7] >> 6;
				xy_[1].x = (static_cast<uint16_t>(touch_tmp_[7] & 0x3F) << 8)
					| static_cast<uint16_t>(touch_tmp_[8]);
				xy_[1].y = (static_cast<uint16_t>(touch_tmp_[9]) << 8)
					| static_cast<uint16_t>(touch_tmp_[10]);
			}
		}

		void request_touch_() noexcept
		{
			touch_tmp_[0] = static_cast<uint8_t>(REG::TD_STATUS);
			i2c_.send(FT5206_ADR, touch_tmp_, 1);
			i2c_.recv(FT5206_ADR, touch_tmp_, sizeof(touch_tmp_));
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	i2c	i2c 制御クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		FT5206(I2C& i2c) noexcept : i2c_(i2c), touch_num_(0), start_(false),
			version_(0), chip_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイスのバージョンを取得
			@return デバイスのバージョン
		 */
		//-----------------------------------------------------------------//
		uint16_t get_version() const noexcept { return version_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	チップ・コードを取得
			@return チップ・コード
		 */
		//-----------------------------------------------------------------//
		uint8_t get_chip() const noexcept { return chip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイス・リセット
			@param[in]	RES	リセット端子
		 */
		//-----------------------------------------------------------------//
		template <class RES>
		static void reset() noexcept {
			RES::DIR = 1;
			RES::P = 0;
			utils::delay::milli_second(5);
			RES::P = 1;
			utils::delay::milli_second(300);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	開始
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool start() noexcept
		{
			uint8_t tmp[3];
			tmp[0] = static_cast<uint8_t>(REG::ID_G_LIB_VERSION_H);
			if(!i2c_.send(FT5206_ADR, tmp, 1)) {
				utils::format("Send fail\n");
				return false;
			}
			i2c_.sync();

			tmp[0] = 0xff;
			tmp[1] = 0xff;
			tmp[2] = 0xff;
			if(!i2c_.recv(FT5206_ADR, tmp, sizeof(tmp))) {
				utils::format("Recv fail\n");
				return false;
			}
			i2c_.sync();
			version_ = (static_cast<uint16_t>(tmp[0]) << 8) | tmp[1];
			chip_ = tmp[2];

			write_(REG::DEVICE_MODE, 0x00);

			start_ = true;

			request_touch_();
			i2c_.sync();

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		 */
		//-----------------------------------------------------------------//
		void update() noexcept
		{
			if(!start_) return;

			convert_touch_();
			request_touch_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ数を取得
			@return タッチ数
		 */
		//-----------------------------------------------------------------//
		uint8_t get_touch_num() const noexcept { return touch_num_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ位置を取得
			@param[in]	idx	タッチ・インデックス（０～１）
			@return タッチ位置
		 */
		//-----------------------------------------------------------------//
		const xy& get_touch_pos(uint8_t idx) const noexcept { return xy_[idx & 1]; }
	};
}
<commit_msg>update: touch event, ID<commit_after>#pragma once
//=========================================================================//
/*!	@file
	@brief	FT5206 class @n
			FocalTech @n
			Capacitive Touch Panel Controller ドライバー @n
			・I2C 割り込み対応
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=========================================================================//
#include <cstdint>
#include "common/delay.hpp"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  FT5206 テンプレートクラス
		@param[in]	I2C	I2C 制御クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class I2C>
	class FT5206 {
	public:
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  Touch Event Type
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class EVENT : uint8_t {
			DOWN,
			UP,
			CONTACT,
			NONE
		};

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  Touch Struct
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct xy {
			EVENT		event;	///< Touch Event
			uint8_t		id;		///< Touch ID
			uint16_t	x;		///< Touch Position X
			uint16_t	y;		///< Touch Position Y
			xy() : event(EVENT::NONE), id(0), x(0), y(0) { }
		};

	private:

		static const uint8_t	FT5206_ADR = 0x38;

		I2C&	i2c_;

		enum class REG : uint8_t {
			DEVICE_MODE,		// R/W
			GEST_ID,			// R
			TD_STATUS,			// R
			TOUCH_XH,			// R
			TOUCH_XL,			// R
			TOUCH_YH,			// R
			TOUCH_YL,			// R

			TOUCH2_XH = 0x09,	// R
			TOUCH2_XL,			// R
			TOUCH2_YH,			// R
			TOUCH2_YL,			// R

			TOUCH3_XH = 0x0F,	// R
			TOUCH3_XL,			// R
			TOUCH3_YH,			// R
			TOUCH3_YL,			// R

			TOUCH4_XH = 0x15,	// R
			TOUCH4_XL,			// R
			TOUCH4_YH,			// R
			TOUCH4_YL,			// R

			TOUCH5_XH = 0x1B,	// R
			TOUCH5_XL,			// R
			TOUCH5_YH,			// R
			TOUCH5_YL,			// R

			ID_G_THGROUP = 0x80,		// R/W
			ID_G_THPEAK,				// R/W
			ID_G_THCAL,					// R/W
			ID_G_THWATER,				// R/W
			ID_G_THTEMP,				// R/W

			ID_G_CTRL = 0x86,			// R/W
			ID_G_TIME_ENTER_MONITOR,	// R/W
			ID_G_PERIODACTIVE,			// R/W
			ID_G_PERIODMONITOR,			// R/W

			ID_G_AUTO_CLB_MODE = 0xA0,	// R/W
			ID_G_LIB_VERSION_H,			// R
			ID_G_LIB_VERSION_L,			// R
			ID_G_CIPHER,				// R
			ID_G_MODE,					// R
			ID_G_PMODE,					// R
			ID_G_FIRMID,				// R
			ID_G_STATE,					// R
			ID_G_FT5201ID,				// R
			ID_G_ERR,					// R
			ID_G_CLB,					// R/W

			ID_G_B_AREA_TH = 0xAE,		// R/W

			LOG_MSG_CNT = 0xFE,			// R
			LOG_CUR_CHA					// R
		};

		uint8_t		touch_num_;
		bool		start_;
		uint16_t	version_;
		uint8_t		chip_;
		uint8_t		touch_tmp_[11];
		xy			xy_[2];

		void write_(REG reg, uint8_t data) noexcept
		{
			uint8_t tmp[2];
			tmp[0] = static_cast<uint8_t>(reg);
			tmp[1] = data;
			i2c_.send(FT5206_ADR, tmp, sizeof(tmp));
			i2c_.sync();
		}

		uint8_t read_(REG reg) noexcept
		{
			uint8_t tmp[1];
			tmp[0] = static_cast<uint8_t>(reg);
			i2c_.send(FT5206_ADR, tmp, sizeof(tmp));
			i2c_.recv(FT5206_ADR, tmp, sizeof(tmp));
			i2c_.sync();
			return tmp[0];
		}

		void convert_touch_() noexcept
		{
			touch_num_ = touch_tmp_[0];
			if(touch_num_ == 0) return;

			if(touch_num_ >= 1) {
				xy_[0].event = static_cast<EVENT>(touch_tmp_[1] >> 6);
				xy_[0].id = touch_tmp_[3] >> 4;
				xy_[0].x = (static_cast<uint16_t>(touch_tmp_[1] & 0x0F) << 8)
					| static_cast<uint16_t>(touch_tmp_[2]);
				xy_[0].y = (static_cast<uint16_t>(touch_tmp_[3] & 0x0F) << 8)
					| static_cast<uint16_t>(touch_tmp_[4]);
			}
			if(touch_num_ > 1) {
				xy_[1].event = static_cast<EVENT>(touch_tmp_[7] >> 6);
				xy_[1].id = touch_tmp_[9] >> 4;
				xy_[1].x = (static_cast<uint16_t>(touch_tmp_[7] & 0x0F) << 8)
					| static_cast<uint16_t>(touch_tmp_[8]);
				xy_[1].y = (static_cast<uint16_t>(touch_tmp_[9] & 0x0F) << 8)
					| static_cast<uint16_t>(touch_tmp_[10]);
			}
		}

		void request_touch_() noexcept
		{
			touch_tmp_[0] = static_cast<uint8_t>(REG::TD_STATUS);
			i2c_.send(FT5206_ADR, touch_tmp_, 1);
			i2c_.recv(FT5206_ADR, touch_tmp_, sizeof(touch_tmp_));
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	i2c	i2c 制御クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		FT5206(I2C& i2c) noexcept : i2c_(i2c), touch_num_(0), start_(false),
			version_(0), chip_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイスのバージョンを取得
			@return デバイスのバージョン
		 */
		//-----------------------------------------------------------------//
		uint16_t get_version() const noexcept { return version_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	チップ・コードを取得
			@return チップ・コード
		 */
		//-----------------------------------------------------------------//
		uint8_t get_chip() const noexcept { return chip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	デバイス・リセット
			@param[in]	RES	リセット端子
		 */
		//-----------------------------------------------------------------//
		template <class RES>
		static void reset() noexcept {
			RES::DIR = 1;
			RES::P = 0;
			utils::delay::milli_second(5);
			RES::P = 1;
			utils::delay::milli_second(300);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	開始
			@return 成功なら「true」
		 */
		//-----------------------------------------------------------------//
		bool start() noexcept
		{
			uint8_t tmp[3];
			tmp[0] = static_cast<uint8_t>(REG::ID_G_LIB_VERSION_H);
			if(!i2c_.send(FT5206_ADR, tmp, 1)) {
				utils::format("Send fail\n");
				return false;
			}
			i2c_.sync();

			tmp[0] = 0xff;
			tmp[1] = 0xff;
			tmp[2] = 0xff;
			if(!i2c_.recv(FT5206_ADR, tmp, sizeof(tmp))) {
				utils::format("Recv fail\n");
				return false;
			}
			i2c_.sync();
			version_ = (static_cast<uint16_t>(tmp[0]) << 8) | tmp[1];
			chip_ = tmp[2];

			write_(REG::DEVICE_MODE, 0x00);

			start_ = true;

			request_touch_();
			i2c_.sync();

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		 */
		//-----------------------------------------------------------------//
		void update() noexcept
		{
			if(!start_) return;

			convert_touch_();
			request_touch_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ数を取得
			@return タッチ数
		 */
		//-----------------------------------------------------------------//
		uint8_t get_touch_num() const noexcept { return touch_num_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ位置を取得
			@param[in]	idx	タッチ・インデックス（０～１）
			@return タッチ位置
		 */
		//-----------------------------------------------------------------//
		const xy& get_touch_pos(uint8_t idx) const noexcept { return xy_[idx & 1]; }
	};
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	BUS R/W テンプレート・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>
#include "common/delay.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  BUS R/W テンプレート・クラス
		@param[in]	CS	チップ選択
		@param[in]	RS	レジスタ選択
		@param[in]	RD	リード
		@param[in]	WR	ライト
		@param[in]	DL	データパスＬ（DB0 - DB7）
		@param[in]	DH	データパスＨ（DB8 - DB15）
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class CS, class RS, class RD, class WR, class DL, class DH>
	class bus_rw16 {

		static void write16_(uint16_t val) noexcept {
			DH::P = val >> 8;
			DL::P = val & 0xff;
			WR::P = 0;
			CS::P = 0;
			utils::delay::loop(5);
			WR::P = 1;
			CS::P = 1;
		}

		static uint16_t read16_() noexcept {
			RD::P = 0;
			CS::P = 0;
			utils::delay::micro_second(1);
			uint16_t val = static_cast<uint16_t>(DH::P());
			val <<= 8;
			val |= static_cast<uint16_t>(DL::P());
			CS::P = 1;
			RD::P = 1;
			return val;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	開始
		 */
		//-----------------------------------------------------------------//
		static void start() noexcept
		{
			RS::DIR = 1;
			RD::DIR = 1;
			WR::DIR = 1;
			CS::DIR = 1;

			CS::P = 1;
			RS::P = 0;
			RD::P = 1;
			WR::P = 1;

			DL::DIR = 0xff;
			DH::DIR = 0xff;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	書き込み
			@param[in]	rs		レジスタ選択
			@param[in]	val		書き込みデータ
		 */
		//-----------------------------------------------------------------//
		static void write(bool rs, uint16_t val) noexcept {
			RS::P = rs;
			write16_(val);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	読み込み @n
					※あらかじめ、リードアドレスを設定しておく
			@param[in]	rs		レジスタ選択
			@return	読み出しデータ
		 */
		//-----------------------------------------------------------------//
		static uint16_t read(bool rs) noexcept {
			RS::P = rs;
			DL::DIR = 0x00;
			DH::DIR = 0x00;
			auto dat = read16_();
			DL::DIR = 0xff;
			DH::DIR = 0xff;
			return dat;
		}
	};

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  BUS R/W テンプレート・クラス
		@param[in]	CS	チップ選択
		@param[in]	RS	レジスタ選択
		@param[in]	RD	リード
		@param[in]	WR	ライト
		@param[in]	DA	データパス（DB0 - DB7）
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class CS, class RS, class RD, class WR, class DA>
	class bus_rw8 {

		static void write16_(uint16_t val) noexcept {
			DA::P = val >> 8;
			CS::P = 0;
			WR::P = 0;
			utils::delay::loop(3);
			WR::P = 1;
			utils::delay::loop(3);
			DA::P = val & 0xff;
			WR::P = 0;
			utils::delay::loop(3);
			CS::P = 1;
			WR::P = 1;
		}

		static uint16_t read16_() noexcept {
			RD::P = 0;
			CS::P = 0;
			utils::delay::micro_second(1);
			uint16_t val = static_cast<uint16_t>(DA::P());
			val <<= 8;
			CS::P = 1;
			utils::delay::micro_second(1);
			CS::P = 0;
			utils::delay::micro_second(1);
			val |= static_cast<uint16_t>(DA::P());
			CS::P = 1;
			RD::P = 1;
			return val;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	開始
		 */
		//-----------------------------------------------------------------//
		static void start() noexcept
		{
			RS::DIR = 1;
			RD::DIR = 1;
			WR::DIR = 1;
			CS::DIR = 1;

			CS::P = 1;
			RS::P = 0;
			RD::P = 1;
			WR::P = 1;

			DA::DIR = 0xff;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	書き込み
			@param[in]	rs		レジスタ選択
			@param[in]	val		書き込みデータ
		 */
		//-----------------------------------------------------------------//
		static void write(bool rs, uint16_t val) noexcept {
			RS::P = rs;
			write16_(val);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	読み込み @n
					※あらかじめ、リードアドレスを設定しておく
			@param[in]	rs		レジスタ選択
			@return	読み出しデータ
		 */
		//-----------------------------------------------------------------//
		static uint16_t read(bool rs) noexcept {
			RS::P = rs;
			DA::DIR = 0x00;
			auto dat = read16_();
			DA::DIR = 0xff;
			return dat;
		}
	};
}
<commit_msg>update: tune bus cycle<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	BUS R/W テンプレート・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>
#include "common/delay.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  BUS R/W テンプレート・クラス
		@param[in]	CS	チップ選択
		@param[in]	RS	レジスタ選択
		@param[in]	RD	リード
		@param[in]	WR	ライト
		@param[in]	DL	データパスＬ（DB0 - DB7）
		@param[in]	DH	データパスＨ（DB8 - DB15）
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class CS, class RS, class RD, class WR, class DL, class DH>
	class bus_rw16 {

		static void write16_(uint16_t val) noexcept {
			DH::P = val >> 8;
			DL::P = val & 0xff;
			WR::P = 0;
			CS::P = 0;
			utils::delay::loop(5);
			WR::P = 1;
			CS::P = 1;
		}

		static uint16_t read16_() noexcept {
			RD::P = 0;
			CS::P = 0;
			utils::delay::micro_second(1);
			uint16_t val = static_cast<uint16_t>(DH::P());
			val <<= 8;
			val |= static_cast<uint16_t>(DL::P());
			CS::P = 1;
			RD::P = 1;
			return val;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	開始
		 */
		//-----------------------------------------------------------------//
		static void start() noexcept
		{
			RS::DIR = 1;
			RD::DIR = 1;
			WR::DIR = 1;
			CS::DIR = 1;

			CS::P = 1;
			RS::P = 0;
			RD::P = 1;
			WR::P = 1;

			DL::DIR = 0xff;
			DH::DIR = 0xff;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	書き込み
			@param[in]	rs		レジスタ選択
			@param[in]	val		書き込みデータ
		 */
		//-----------------------------------------------------------------//
		static void write(bool rs, uint16_t val) noexcept {
			RS::P = rs;
			write16_(val);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	読み込み @n
					※あらかじめ、リードアドレスを設定しておく
			@param[in]	rs		レジスタ選択
			@return	読み出しデータ
		 */
		//-----------------------------------------------------------------//
		static uint16_t read(bool rs) noexcept {
			RS::P = rs;
			DL::DIR = 0x00;
			DH::DIR = 0x00;
			auto dat = read16_();
			DL::DIR = 0xff;
			DH::DIR = 0xff;
			return dat;
		}
	};

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  BUS R/W テンプレート・クラス
		@param[in]	CS	チップ選択
		@param[in]	RS	レジスタ選択
		@param[in]	RD	リード
		@param[in]	WR	ライト
		@param[in]	DA	データパス（DB0 - DB7）
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class CS, class RS, class RD, class WR, class DA>
	class bus_rw8 {

		static void write16_(uint16_t val) noexcept {
			DA::P = val >> 8;
			CS::P = 0;
			WR::P = 0;
			utils::delay::loop(2);
			WR::P = 1;
			utils::delay::loop(2);
			DA::P = val & 0xff;
			WR::P = 0;
			utils::delay::loop(2);
			CS::P = 1;
			WR::P = 1;
		}

		static uint16_t read16_() noexcept {
			RD::P = 0;
			CS::P = 0;
			utils::delay::micro_second(1);
			uint16_t val = static_cast<uint16_t>(DA::P());
			val <<= 8;
			CS::P = 1;
			utils::delay::micro_second(1);
			CS::P = 0;
			utils::delay::micro_second(1);
			val |= static_cast<uint16_t>(DA::P());
			CS::P = 1;
			RD::P = 1;
			return val;
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	開始
		 */
		//-----------------------------------------------------------------//
		static void start() noexcept
		{
			RS::DIR = 1;
			RD::DIR = 1;
			WR::DIR = 1;
			CS::DIR = 1;

			CS::P = 1;
			RS::P = 0;
			RD::P = 1;
			WR::P = 1;

			DA::DIR = 0xff;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	書き込み
			@param[in]	rs		レジスタ選択
			@param[in]	val		書き込みデータ
		 */
		//-----------------------------------------------------------------//
		static void write(bool rs, uint16_t val) noexcept {
			RS::P = rs;
			write16_(val);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	読み込み @n
					※あらかじめ、リードアドレスを設定しておく
			@param[in]	rs		レジスタ選択
			@return	読み出しデータ
		 */
		//-----------------------------------------------------------------//
		static uint16_t read(bool rs) noexcept {
			RS::P = rs;
			DA::DIR = 0x00;
			auto dat = read16_();
			DA::DIR = 0xff;
			return dat;
		}
	};
}
<|endoftext|>


<commit_before>#include "FileIO.h"
#include "StagePanel.h"
#include "ToolbarPanel.h"
#include "ParticleSystem.h"
#include "config.h"
#include "ps_config.h"

namespace eparticle3d
{

void FileIO::store(const char* filepath, ToolbarPanel* toolbar)
{
	Json::Value value;

	toolbar->Store(value);
	value["version"] = VERSION;

	value["name"] = toolbar->m_name->GetValue().ToStdString();
	value["package"] = toolbar->m_package->GetValue().ToStdString();
	value["layer"] = toolbar->m_layer->GetValue();
	value["min_hori"] = toolbar->m_min_hori->GetValue();
	value["max_hori"] = toolbar->m_max_hori->GetValue();
	value["min_vert"] = toolbar->m_min_vert->GetValue();
	value["max_vert"] = toolbar->m_max_vert->GetValue();
	value["inertia"] = toolbar->m_inertia->GetValue();
	value["bounce"] = toolbar->m_bounce->GetValue();
	value["additive_blend"] = toolbar->m_additiveBlend->GetValue();
	value["start_radius_3d"] = toolbar->m_radius_3d->GetValue();
	value["orient_to_movement"] = toolbar->m_orient_to_movement->GetValue();
	value["orient_to_parent"] = toolbar->m_orient_to_parent->GetValue();

	std::string dir = d2d::FilenameTools::getFileDir(filepath);
	for (size_t i = 0, n = toolbar->m_children.size(); i < n; ++i)
	{
		ToolbarPanel::ChildPanel* cp = toolbar->m_children[i];
		ParticleChild* pc = cp->m_pc;
		value["components"][i]["filepath"] =
			d2d::FilenameTools::getRelativePath(dir, pc->symbol->GetFilepath()).ToStdString();
		if (pc->bind_ps) {
			value["components"][i]["bind ps filepath"] =
				d2d::FilenameTools::getRelativePath(dir, pc->bind_ps->filepath).ToStdString();
		}
		value["components"][i]["name"] = cp->m_name->GetValue().ToStdString();
		value["components"][i]["start_z"] = cp->m_startz->GetValue();
		for (int j = 0, m = cp->m_sliders.size(); j < m; ++j) {
			cp->m_sliders[j]->Store(value["components"][i]);
		}
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath);
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void FileIO::load(const char* filepath, ParticleSystem* ps,
				  ToolbarPanel* toolbar)
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath);
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	int version = value["version"].asInt();

	FileAdapter adapter;
	adapter.load(filepath, version);

	if (version == 0) {
		int center = (adapter.min_life + adapter.max_life) * 0.5f;
		int offset = (adapter.max_life - adapter.min_life) * 0.5f;
		value["life"]["center"] = center;
		value["life"]["offset"] = offset;

		center = (adapter.min_spd + adapter.max_spd) * 0.5f;
		offset = (adapter.max_spd - adapter.min_spd) * 0.5f;
		value["speed"]["center"] = center;
		value["speed"]["offset"] = offset;
	}

	toolbar->Load(value, version);

	//////////////////////////////////////////////////////////////////////////

	toolbar->m_name->SetValue(adapter.name);
	toolbar->m_package->SetValue(adapter.package);

	toolbar->m_layer->SetValue(adapter.layer);
	toolbar->m_min_hori->SetValue(adapter.min_hori);
	toolbar->m_max_hori->SetValue(adapter.max_hori);
	ps->setHori(adapter.min_hori, adapter.max_hori);
	toolbar->m_min_vert->SetValue(adapter.min_vert);
	toolbar->m_max_vert->SetValue(adapter.max_vert);
	ps->setVert(adapter.min_vert, adapter.max_vert);
	toolbar->m_inertia->SetValue(adapter.inertia);
	toolbar->m_bounce->SetValue(adapter.bounce);
	ps->setBounce(adapter.bounce);
	toolbar->m_additiveBlend->SetValue(adapter.additive_blend);
	toolbar->m_orient_to_movement->SetValue(adapter.orient_to_movement);
	toolbar->m_radius_3d->SetValue(adapter.start_radius_3d);
	toolbar->m_orient_to_parent->SetValue(adapter.orient_to_parent);
	for (size_t i = 0, n = adapter.children.size(); i < n; ++i) {
		toolbar->add(adapter.children[i]);
	}
}

ParticleSystem* FileIO::LoadPS(const char* filepath)
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath);
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	int version = value["version"].asInt();

	FileAdapter adapter;
	adapter.load(filepath, version);

	ParticleSystem* ps = new ParticleSystem(PARTICLE_CAP);

	ps->filepath = filepath;
	ps->SetValue(PS_COUNT, d2d::UICallback::Data(adapter.count));
	ps->SetValue(PS_EMISSION_TIME, d2d::UICallback::Data(adapter.emission_time));
	ps->SetValue(PS_LIFE_TIME, d2d::UICallback::Data((adapter.min_life + adapter.max_life) * 0.5f, (adapter.max_life - adapter.min_life) * 0.5f));
	ps->SetValue(PS_SPEED, d2d::UICallback::Data((adapter.min_spd + adapter.max_spd) * 0.5f, (adapter.max_spd - adapter.min_spd) * 0.5f));
	ps->SetValue(PS_ANGULAR_SPEED, d2d::UICallback::Data((adapter.min_angular_spd + adapter.max_angular_spd) * 0.5f, (adapter.max_angular_spd - adapter.min_angular_spd) * 0.5f));
	ps->SetValue(PS_DISTURBANCE_RADIUS, d2d::UICallback::Data((adapter.min_dis_region + adapter.max_dis_region) * 0.5f, (adapter.max_dis_region - adapter.min_dis_region) * 0.5f));
	ps->SetValue(PS_DISTURBANCE_SPD, d2d::UICallback::Data((adapter.min_dis_spd + adapter.max_dis_spd) * 0.5f, (adapter.max_dis_spd - adapter.min_dis_spd) * 0.5f));
	ps->SetValue(PS_GRAVITY, d2d::UICallback::Data(adapter.gravity));
	ps->SetValue(PS_LINEAR_ACC, d2d::UICallback::Data((adapter.min_linear_acc + adapter.max_angular_spd) * 0.5f, (adapter.max_angular_spd - adapter.max_linear_acc) * 0.5f));
	ps->SetValue(PS_FADEOUT_TIME, d2d::UICallback::Data(adapter.fadeout_time));
	ps->SetValue(PS_START_RADIUS, d2d::UICallback::Data(adapter.start_radius));

	ps->setHori(adapter.min_hori, adapter.max_hori);
	ps->setVert(adapter.min_vert, adapter.max_vert);
	ps->setBounce(adapter.bounce);
	for (size_t i = 0, n = adapter.children.size(); i < n; ++i)
	{
		const FileAdapter::Child& child = adapter.children[i];

		ParticleChild* pc = new ParticleChild;

		// todo Release symbol
		pc->symbol = d2d::SymbolMgr::Instance()->FetchSymbol(child.filepath);

		pc->start_scale = child.start_scale * 0.01f;
		pc->end_scale = child.end_scale * 0.01f;
		pc->min_rotate = child.min_rotate * d2d::TRANS_DEG_TO_RAD;
		pc->max_rotate = child.max_rotate * d2d::TRANS_DEG_TO_RAD;

		ps->addChild(pc);
	}

	return ps;
}

}<commit_msg>[FIXED] particle3d导入的某些属性没设置<commit_after>#include "FileIO.h"
#include "StagePanel.h"
#include "ToolbarPanel.h"
#include "ParticleSystem.h"
#include "config.h"
#include "ps_config.h"

namespace eparticle3d
{

void FileIO::store(const char* filepath, ToolbarPanel* toolbar)
{
	Json::Value value;

	toolbar->Store(value);
	value["version"] = VERSION;

	value["name"] = toolbar->m_name->GetValue().ToStdString();
	value["package"] = toolbar->m_package->GetValue().ToStdString();
	value["layer"] = toolbar->m_layer->GetValue();
	value["min_hori"] = toolbar->m_min_hori->GetValue();
	value["max_hori"] = toolbar->m_max_hori->GetValue();
	value["min_vert"] = toolbar->m_min_vert->GetValue();
	value["max_vert"] = toolbar->m_max_vert->GetValue();
	value["inertia"] = toolbar->m_inertia->GetValue();
	value["bounce"] = toolbar->m_bounce->GetValue();
	value["additive_blend"] = toolbar->m_additiveBlend->GetValue();
	value["start_radius_3d"] = toolbar->m_radius_3d->GetValue();
	value["orient_to_movement"] = toolbar->m_orient_to_movement->GetValue();
	value["orient_to_parent"] = toolbar->m_orient_to_parent->GetValue();

	std::string dir = d2d::FilenameTools::getFileDir(filepath);
	for (size_t i = 0, n = toolbar->m_children.size(); i < n; ++i)
	{
		ToolbarPanel::ChildPanel* cp = toolbar->m_children[i];
		ParticleChild* pc = cp->m_pc;
		value["components"][i]["filepath"] =
			d2d::FilenameTools::getRelativePath(dir, pc->symbol->GetFilepath()).ToStdString();
		if (pc->bind_ps) {
			value["components"][i]["bind ps filepath"] =
				d2d::FilenameTools::getRelativePath(dir, pc->bind_ps->filepath).ToStdString();
		}
		value["components"][i]["name"] = cp->m_name->GetValue().ToStdString();
		value["components"][i]["start_z"] = cp->m_startz->GetValue();
		for (int j = 0, m = cp->m_sliders.size(); j < m; ++j) {
			cp->m_sliders[j]->Store(value["components"][i]);
		}
	}

	Json::StyledStreamWriter writer;
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath);
	std::locale::global(std::locale("C"));
	writer.write(fout, value);
	fout.close();
}

void FileIO::load(const char* filepath, ParticleSystem* ps,
				  ToolbarPanel* toolbar)
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath);
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	int version = value["version"].asInt();

	FileAdapter adapter;
	adapter.load(filepath, version);

	if (version == 0) {
		int center = (adapter.min_life + adapter.max_life) * 0.5f;
		int offset = (adapter.max_life - adapter.min_life) * 0.5f;
		value["life"]["center"] = center;
		value["life"]["offset"] = offset;

		center = (adapter.min_spd + adapter.max_spd) * 0.5f;
		offset = (adapter.max_spd - adapter.min_spd) * 0.5f;
		value["speed"]["center"] = center;
		value["speed"]["offset"] = offset;
	}

	toolbar->Load(value, version);

	//////////////////////////////////////////////////////////////////////////

	toolbar->m_name->SetValue(adapter.name);
	toolbar->m_package->SetValue(adapter.package);

	toolbar->m_layer->SetValue(adapter.layer);
	toolbar->m_min_hori->SetValue(adapter.min_hori);
	toolbar->m_max_hori->SetValue(adapter.max_hori);
	ps->setHori(adapter.min_hori, adapter.max_hori);
	toolbar->m_min_vert->SetValue(adapter.min_vert);
	toolbar->m_max_vert->SetValue(adapter.max_vert);
	ps->setVert(adapter.min_vert, adapter.max_vert);
	toolbar->m_inertia->SetValue(adapter.inertia);
	toolbar->m_bounce->SetValue(adapter.bounce);
	ps->setBounce(adapter.bounce);
	toolbar->m_additiveBlend->SetValue(adapter.additive_blend);
	ps->setAdditiveBlend(adapter.additive_blend);
	toolbar->m_orient_to_movement->SetValue(adapter.orient_to_movement);
	ps->SetOrientToMovement(adapter.orient_to_movement);
	toolbar->m_radius_3d->SetValue(adapter.start_radius_3d);
	ps->SetRadius3D(adapter.start_radius_3d);
	toolbar->m_orient_to_parent->SetValue(adapter.orient_to_parent);
	for (size_t i = 0, n = adapter.children.size(); i < n; ++i) {
		toolbar->add(adapter.children[i]);
	}
}

ParticleSystem* FileIO::LoadPS(const char* filepath)
{
	Json::Value value;
	Json::Reader reader;
	std::locale::global(std::locale(""));
	std::ifstream fin(filepath);
	std::locale::global(std::locale("C"));
	reader.parse(fin, value);
	fin.close();

	int version = value["version"].asInt();

	FileAdapter adapter;
	adapter.load(filepath, version);

	ParticleSystem* ps = new ParticleSystem(PARTICLE_CAP);

	ps->filepath = filepath;
	ps->SetValue(PS_COUNT, d2d::UICallback::Data(adapter.count));
	ps->SetValue(PS_EMISSION_TIME, d2d::UICallback::Data(adapter.emission_time));
	ps->SetValue(PS_LIFE_TIME, d2d::UICallback::Data((adapter.min_life + adapter.max_life) * 0.5f, (adapter.max_life - adapter.min_life) * 0.5f));
	ps->SetValue(PS_SPEED, d2d::UICallback::Data((adapter.min_spd + adapter.max_spd) * 0.5f, (adapter.max_spd - adapter.min_spd) * 0.5f));
	ps->SetValue(PS_ANGULAR_SPEED, d2d::UICallback::Data((adapter.min_angular_spd + adapter.max_angular_spd) * 0.5f, (adapter.max_angular_spd - adapter.min_angular_spd) * 0.5f));
	ps->SetValue(PS_DISTURBANCE_RADIUS, d2d::UICallback::Data((adapter.min_dis_region + adapter.max_dis_region) * 0.5f, (adapter.max_dis_region - adapter.min_dis_region) * 0.5f));
	ps->SetValue(PS_DISTURBANCE_SPD, d2d::UICallback::Data((adapter.min_dis_spd + adapter.max_dis_spd) * 0.5f, (adapter.max_dis_spd - adapter.min_dis_spd) * 0.5f));
	ps->SetValue(PS_GRAVITY, d2d::UICallback::Data(adapter.gravity));
	ps->SetValue(PS_LINEAR_ACC, d2d::UICallback::Data((adapter.min_linear_acc + adapter.max_angular_spd) * 0.5f, (adapter.max_angular_spd - adapter.max_linear_acc) * 0.5f));
	ps->SetValue(PS_FADEOUT_TIME, d2d::UICallback::Data(adapter.fadeout_time));
	ps->SetValue(PS_START_RADIUS, d2d::UICallback::Data(adapter.start_radius));

	ps->setHori(adapter.min_hori, adapter.max_hori);
	ps->setVert(adapter.min_vert, adapter.max_vert);
	ps->setBounce(adapter.bounce);
	ps->setAdditiveBlend(adapter.additive_blend);
	ps->SetRadius3D(adapter.start_radius_3d);
	ps->SetOrientToMovement(adapter.orient_to_movement);

	for (size_t i = 0, n = adapter.children.size(); i < n; ++i)
	{
		const FileAdapter::Child& child = adapter.children[i];

		ParticleChild* pc = new ParticleChild;

		// todo Release symbol
		pc->symbol = d2d::SymbolMgr::Instance()->FetchSymbol(child.filepath);

		pc->start_scale = child.start_scale * 0.01f;
		pc->end_scale = child.end_scale * 0.01f;
		pc->min_rotate = child.min_rotate * d2d::TRANS_DEG_TO_RAD;
		pc->max_rotate = child.max_rotate * d2d::TRANS_DEG_TO_RAD;

		ps->addChild(pc);
	}

	return ps;
}

}<|endoftext|>


<commit_before>#include "ForceFields.h"
#include "../Effekseer.Matrix44.h"
#include "../SIMD/Effekseer.SIMDUtils.h"
#include "../Utils/Effekseer.BinaryReader.h"

namespace Effekseer
{

ForceFieldTurbulenceParameter::ForceFieldTurbulenceParameter(int32_t seed, float scale, float strength, int octave)
	: Noise(seed)
{
	Noise.Octave = octave;
	Noise.Scale = scale;
	Power = strength;
}

LocalForceFieldTurbulenceParameterOld::LocalForceFieldTurbulenceParameterOld(int32_t seed, float scale, float strength, int octave)
	: Noise(seed)
{
	Noise.Octave = octave;
	Noise.Scale = scale;
	Strength = strength;
}

bool LocalForceFieldParameterOld::Load(uint8_t*& pos, int32_t version)
{
	auto br = BinaryReader<false>(pos, std::numeric_limits<int>::max());

	LocalForceFieldType type{};
	br.Read(type);

	if (type == LocalForceFieldType::Turbulence)
	{
		int32_t seed{};
		float scale{};
		float strength{};
		int octave{};

		br.Read(seed);
		br.Read(scale);
		br.Read(strength);
		br.Read(octave);

		scale = 1.0f / scale;

		Turbulence = std::unique_ptr<LocalForceFieldTurbulenceParameterOld>(
			new LocalForceFieldTurbulenceParameterOld(seed, scale, strength, octave));
	}

	pos += br.GetOffset();

	return true;
}

bool LocalForceFieldElementParameter::Load(uint8_t*& pos, int32_t version)
{
	auto br = BinaryReader<false>(pos, std::numeric_limits<int>::max());

	LocalForceFieldType type{};
	br.Read(type);

	HasValue = true;
	float power = 1.0f;

	if (version >= 1600)
	{
		br.Read(power);

		br.Read(Position.X);
		br.Read(Position.Y);
		br.Read(Position.Z);

		Vector3D rotation;
		br.Read(rotation.X);
		br.Read(rotation.Y);
		br.Read(rotation.Z);

		IsRotated = rotation.X != 0.0f || rotation.Y != 0.0f || rotation.Z != 0.0f;

		if (IsRotated)
		{
			Rotation = Mat44f::RotationZXY(rotation.Z, rotation.X, rotation.Y);
			Matrix44 invMat;
			InvRotation = Mat44f(Matrix44::Inverse(invMat, ToStruct(Rotation)));
		}
	}

	if (type == LocalForceFieldType::Force)
	{
		int gravitation = 0;
		br.Read(gravitation);

		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldForceParameter();
		ff->Power = power;
		ff->Gravitation = gravitation > 0;
		Force = std::unique_ptr<ForceFieldForceParameter>(ff);
	}
	else if (type == LocalForceFieldType::Wind)
	{
		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldWindParameter();
		ff->Power = power;
		Wind = std::unique_ptr<ForceFieldWindParameter>(ff);
	}
	else if (type == LocalForceFieldType::Vortex)
	{
		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldVortexParameter();
		ff->Power = power;
		Vortex = std::unique_ptr<ForceFieldVortexParameter>(ff);
	}
	else if (type == LocalForceFieldType::Maginetic)
	{
		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldMagineticParameter();
		ff->Power = power;
		Maginetic = std::unique_ptr<ForceFieldMagineticParameter>(ff);
	}
	else if (type == LocalForceFieldType::Turbulence)
	{
		int32_t seed{};
		float scale{};
		float strength{};
		int octave{};

		br.Read(seed);
		br.Read(scale);
		br.Read(strength);
		br.Read(octave);

		scale = 1.0f / scale;

		Turbulence = std::unique_ptr<ForceFieldTurbulenceParameter>(new ForceFieldTurbulenceParameter(seed, scale, strength, octave));
	}
	else if (type == LocalForceFieldType::Drag)
	{
		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldDragParameter();
		ff->Power = power;
		Drag = std::unique_ptr<ForceFieldDragParameter>(ff);
	}
	else
	{
		HasValue = false;
	}

	if (version >= 1600)
	{
		LocalForceFieldFalloffType ffType{};
		br.Read(ffType);

		if (ffType != LocalForceFieldFalloffType::None)
		{
			FalloffCommon = std::make_unique<ForceFieldFalloffCommonParameter>();
			br.Read(FalloffCommon->Power);
			br.Read(FalloffCommon->MaxDistance);
			br.Read(FalloffCommon->MinDistance);
		}

		if (ffType == LocalForceFieldFalloffType::None)
		{
		}
		else if (ffType == LocalForceFieldFalloffType::Sphere)
		{
			FalloffSphere = std::make_unique<ForceFieldFalloffSphereParameter>();
		}
		else if (ffType == LocalForceFieldFalloffType::Tube)
		{
			FalloffTube = std::make_unique<ForceFieldFalloffTubeParameter>();
			br.Read(FalloffTube->RadiusPower);
			br.Read(FalloffTube->MaxRadius);
			br.Read(FalloffTube->MinRadius);
		}
		else if (ffType == LocalForceFieldFalloffType::Cone)
		{
			FalloffCone = std::make_unique<ForceFieldFalloffConeParameter>();
			br.Read(FalloffCone->AnglePower);
			br.Read(FalloffCone->MaxAngle);
			br.Read(FalloffCone->MinAngle);
		}
		else
		{
			assert(0);
		}
	}

	pos += br.GetOffset();

	return true;
}

bool LocalForceFieldParameter::Load(uint8_t*& pos, int32_t version)
{
	int32_t count = 0;
	memcpy(&count, pos, sizeof(int));
	pos += sizeof(int);

	for (int32_t i = 0; i < count; i++)
	{
		if (!LocalForceFields[i].Load(pos, version))
		{
			return false;
		}
	}

	for (auto& ff : LocalForceFields)
	{
		if (ff.HasValue)
		{
			HasValue = true;
		}
	}

	return true;
}

void LocalForceFieldInstance::Update(const LocalForceFieldParameter& parameter, const Vec3f& location, float magnification)
{
	for (size_t i = 0; i < parameter.LocalForceFields.size(); i++)
	{
		auto& field = parameter.LocalForceFields[i];
		if (!field.HasValue)
		{
			continue;
		}

		ForceFieldCommonParameter ffcp;
		ffcp.FieldCenter = parameter.LocalForceFields[i].Position;
		ffcp.Position = location / magnification;
		ffcp.PreviousSumVelocity = VelocitySum;
		ffcp.PreviousVelocity = Velocities[i];
		ffcp.IsFieldRotated = field.IsRotated;

		if (field.IsRotated)
		{
			ffcp.PreviousSumVelocity = Vec3f::Transform(VelocitySum, field.InvRotation);
			ffcp.PreviousVelocity = Vec3f::Transform(Velocities[i], field.InvRotation);
			ffcp.Position = Vec3f::Transform(ffcp.Position, field.InvRotation);
		}

		ForceField ff;

		Vec3f acc = Vec3f(0, 0, 0);
		if (field.Force != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Force) * magnification;
		}

		if (field.Wind != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Wind) * magnification;
		}

		if (field.Vortex != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Vortex) * magnification;
		}

		if (field.Maginetic != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Maginetic) * magnification;
		}

		if (field.Turbulence != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Turbulence) * magnification;
		}

		if (field.Drag != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Drag) * magnification;
		}

		float power = 1.0f;
		if (field.FalloffCommon != nullptr && field.FalloffCone != nullptr)
		{
			ForceFieldFalloff fff;
			power = fff.GetPower(power, ffcp, *field.FalloffCommon, *field.FalloffCone);
		}

		if (field.FalloffCommon != nullptr && field.FalloffSphere != nullptr)
		{
			ForceFieldFalloff fff;
			power = fff.GetPower(power, ffcp, *field.FalloffCommon, *field.FalloffSphere);
		}

		if (field.FalloffCommon != nullptr && field.FalloffTube != nullptr)
		{
			ForceFieldFalloff fff;
			power = fff.GetPower(power, ffcp, *field.FalloffCommon, *field.FalloffTube);
		}

		acc *= power;

		if (field.IsRotated)
		{
			acc = Vec3f::Transform(acc, field.Rotation);
		}

		Velocities[i] += acc;
	}

	VelocitySum = Vec3f(0, 0, 0);

	for (size_t i = 0; i < parameter.LocalForceFields.size(); i++)
	{
		VelocitySum += Velocities[i];
	}

	ModifyLocation += VelocitySum;
}

void LocalForceFieldInstance::Reset()
{
	Velocities.fill(Vec3f(0, 0, 0));
	VelocitySum = Vec3f(0, 0, 0);
	ModifyLocation = Vec3f(0, 0, 0);
}

} // namespace Effekseer<commit_msg>Fix uninitialized bug<commit_after>#include "ForceFields.h"
#include "../Effekseer.Matrix44.h"
#include "../SIMD/Effekseer.SIMDUtils.h"
#include "../Utils/Effekseer.BinaryReader.h"

namespace Effekseer
{

ForceFieldTurbulenceParameter::ForceFieldTurbulenceParameter(int32_t seed, float scale, float strength, int octave)
	: Noise(seed)
{
	Noise.Octave = octave;
	Noise.Scale = scale;
	Power = strength;
}

LocalForceFieldTurbulenceParameterOld::LocalForceFieldTurbulenceParameterOld(int32_t seed, float scale, float strength, int octave)
	: Noise(seed)
{
	Noise.Octave = octave;
	Noise.Scale = scale;
	Strength = strength;
}

bool LocalForceFieldParameterOld::Load(uint8_t*& pos, int32_t version)
{
	auto br = BinaryReader<false>(pos, std::numeric_limits<int>::max());

	LocalForceFieldType type{};
	br.Read(type);

	if (type == LocalForceFieldType::Turbulence)
	{
		int32_t seed{};
		float scale{};
		float strength{};
		int octave{};

		br.Read(seed);
		br.Read(scale);
		br.Read(strength);
		br.Read(octave);

		scale = 1.0f / scale;

		Turbulence = std::unique_ptr<LocalForceFieldTurbulenceParameterOld>(
			new LocalForceFieldTurbulenceParameterOld(seed, scale, strength, octave));
	}

	pos += br.GetOffset();

	return true;
}

bool LocalForceFieldElementParameter::Load(uint8_t*& pos, int32_t version)
{
	auto br = BinaryReader<false>(pos, std::numeric_limits<int>::max());

	LocalForceFieldType type{};
	br.Read(type);

	HasValue = true;
	float power = 1.0f;

	if (version >= 1600)
	{
		br.Read(power);

		br.Read(Position.X);
		br.Read(Position.Y);
		br.Read(Position.Z);

		Vector3D rotation;
		br.Read(rotation.X);
		br.Read(rotation.Y);
		br.Read(rotation.Z);

		IsRotated = rotation.X != 0.0f || rotation.Y != 0.0f || rotation.Z != 0.0f;

		if (IsRotated)
		{
			Rotation = Mat44f::RotationZXY(rotation.Z, rotation.X, rotation.Y);
			Matrix44 invMat;
			InvRotation = Mat44f(Matrix44::Inverse(invMat, ToStruct(Rotation)));
		}
	}

	if (type == LocalForceFieldType::Force)
	{
		int gravitation = 0;
		br.Read(gravitation);

		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldForceParameter();
		ff->Power = power;
		ff->Gravitation = gravitation > 0;
		Force = std::unique_ptr<ForceFieldForceParameter>(ff);
	}
	else if (type == LocalForceFieldType::Wind)
	{
		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldWindParameter();
		ff->Power = power;
		Wind = std::unique_ptr<ForceFieldWindParameter>(ff);
	}
	else if (type == LocalForceFieldType::Vortex)
	{
		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldVortexParameter();
		ff->Power = power;
		Vortex = std::unique_ptr<ForceFieldVortexParameter>(ff);
	}
	else if (type == LocalForceFieldType::Maginetic)
	{
		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldMagineticParameter();
		ff->Power = power;
		Maginetic = std::unique_ptr<ForceFieldMagineticParameter>(ff);
	}
	else if (type == LocalForceFieldType::Turbulence)
	{
		int32_t seed{};
		float scale{};
		float strength{};
		int octave{};

		br.Read(seed);
		br.Read(scale);
		br.Read(strength);
		br.Read(octave);

		scale = 1.0f / scale;

		Turbulence = std::unique_ptr<ForceFieldTurbulenceParameter>(new ForceFieldTurbulenceParameter(seed, scale, strength, octave));
	}
	else if (type == LocalForceFieldType::Drag)
	{
		// convert it by frames
		power /= 60.0f;

		auto ff = new ForceFieldDragParameter();
		ff->Power = power;
		Drag = std::unique_ptr<ForceFieldDragParameter>(ff);
	}
	else
	{
		HasValue = false;
	}

	if (version >= 1600)
	{
		LocalForceFieldFalloffType ffType{};
		br.Read(ffType);

		if (ffType != LocalForceFieldFalloffType::None)
		{
			FalloffCommon = std::make_unique<ForceFieldFalloffCommonParameter>();
			br.Read(FalloffCommon->Power);
			br.Read(FalloffCommon->MaxDistance);
			br.Read(FalloffCommon->MinDistance);
		}

		if (ffType == LocalForceFieldFalloffType::None)
		{
		}
		else if (ffType == LocalForceFieldFalloffType::Sphere)
		{
			FalloffSphere = std::make_unique<ForceFieldFalloffSphereParameter>();
		}
		else if (ffType == LocalForceFieldFalloffType::Tube)
		{
			FalloffTube = std::make_unique<ForceFieldFalloffTubeParameter>();
			br.Read(FalloffTube->RadiusPower);
			br.Read(FalloffTube->MaxRadius);
			br.Read(FalloffTube->MinRadius);
		}
		else if (ffType == LocalForceFieldFalloffType::Cone)
		{
			FalloffCone = std::make_unique<ForceFieldFalloffConeParameter>();
			br.Read(FalloffCone->AnglePower);
			br.Read(FalloffCone->MaxAngle);
			br.Read(FalloffCone->MinAngle);
		}
		else
		{
			assert(0);
		}
	}
	else
	{
		IsRotated = false;
	}

	pos += br.GetOffset();

	return true;
}

bool LocalForceFieldParameter::Load(uint8_t*& pos, int32_t version)
{
	int32_t count = 0;
	memcpy(&count, pos, sizeof(int));
	pos += sizeof(int);

	for (int32_t i = 0; i < count; i++)
	{
		if (!LocalForceFields[i].Load(pos, version))
		{
			return false;
		}
	}

	for (auto& ff : LocalForceFields)
	{
		if (ff.HasValue)
		{
			HasValue = true;
		}
	}

	return true;
}

void LocalForceFieldInstance::Update(const LocalForceFieldParameter& parameter, const Vec3f& location, float magnification)
{
	for (size_t i = 0; i < parameter.LocalForceFields.size(); i++)
	{
		auto& field = parameter.LocalForceFields[i];
		if (!field.HasValue)
		{
			continue;
		}

		ForceFieldCommonParameter ffcp;
		ffcp.FieldCenter = parameter.LocalForceFields[i].Position;
		ffcp.Position = location / magnification;
		ffcp.PreviousSumVelocity = VelocitySum;
		ffcp.PreviousVelocity = Velocities[i];
		ffcp.IsFieldRotated = field.IsRotated;

		if (field.IsRotated)
		{
			ffcp.PreviousSumVelocity = Vec3f::Transform(VelocitySum, field.InvRotation);
			ffcp.PreviousVelocity = Vec3f::Transform(Velocities[i], field.InvRotation);
			ffcp.Position = Vec3f::Transform(ffcp.Position, field.InvRotation);
		}

		ForceField ff;

		Vec3f acc = Vec3f(0, 0, 0);
		if (field.Force != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Force) * magnification;
		}

		if (field.Wind != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Wind) * magnification;
		}

		if (field.Vortex != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Vortex) * magnification;
		}

		if (field.Maginetic != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Maginetic) * magnification;
		}

		if (field.Turbulence != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Turbulence) * magnification;
		}

		if (field.Drag != nullptr)
		{
			acc = ff.GetAcceleration(ffcp, *field.Drag) * magnification;
		}

		float power = 1.0f;
		if (field.FalloffCommon != nullptr && field.FalloffCone != nullptr)
		{
			ForceFieldFalloff fff;
			power = fff.GetPower(power, ffcp, *field.FalloffCommon, *field.FalloffCone);
		}

		if (field.FalloffCommon != nullptr && field.FalloffSphere != nullptr)
		{
			ForceFieldFalloff fff;
			power = fff.GetPower(power, ffcp, *field.FalloffCommon, *field.FalloffSphere);
		}

		if (field.FalloffCommon != nullptr && field.FalloffTube != nullptr)
		{
			ForceFieldFalloff fff;
			power = fff.GetPower(power, ffcp, *field.FalloffCommon, *field.FalloffTube);
		}

		acc *= power;

		if (field.IsRotated)
		{
			acc = Vec3f::Transform(acc, field.Rotation);
		}

		Velocities[i] += acc;
	}

	VelocitySum = Vec3f(0, 0, 0);

	for (size_t i = 0; i < parameter.LocalForceFields.size(); i++)
	{
		VelocitySum += Velocities[i];
	}

	ModifyLocation += VelocitySum;
}

void LocalForceFieldInstance::Reset()
{
	Velocities.fill(Vec3f(0, 0, 0));
	VelocitySum = Vec3f(0, 0, 0);
	ModifyLocation = Vec3f(0, 0, 0);
}

} // namespace Effekseer<|endoftext|>


<commit_before>#include "CallBackWrapper.hpp"
#include "Config.hpp"
#include "EventWatcher.hpp"
#include "keycode.hpp"

namespace org_pqrs_KeyRemap4MacBook {
  void
  Params_KeyboardEventCallBack::log(const char* message) const
  {
    if (! config.debug) return;

    printf("KeyRemap4MacBook KeyboardEventCallback [%s]: eventType %d, flags 0x%x, key %d, kbdType %d\n",
           message, eventType, flags, key, keyboardType);
  }

  void
  Params_KeyboardSpecialEventCallback::log(const char* message) const
  {
    if (! config.debug) return;

    printf("KeyRemap4MacBook KeyboardSpecialEventCallBack [%s]: eventType %d, flags 0x%x, key %d, flavor %d, guid %lld\n",
           message, eventType, flags, key, flavor, guid);
  }

  void
  Params_RelativePointerEventCallback::log(const char* message) const
  {
    if (! config.debug_pointing) return;

    printf("KeyRemap4MacBook RelativePointerEventCallBack [%s]: buttons: %d, dx: %d, dy: %d\n",
           message, buttons, dx, dy);
  }

  void
  Params_ScrollWheelEventCallback::log(const char* message) const
  {
    if (! config.debug_pointing) return;

#if __x86_64__
    const char* format = "KeyRemap4MacBook ScrollWheelEventCallback [%s]: deltaAxis(%d, %d, %d), fixedDelta(%ld, %ld, %ld), pointDelta(%d,%d,%d), options: %d\n";
#else
    const char* format = "KeyRemap4MacBook ScrollWheelEventCallback [%s]: deltaAxis(%d, %d, %d), fixedDelta(%d, %d, %d), pointDelta(%d,%d,%d), options: %d\n";
#endif
    printf(format,
           message,
           deltaAxis1, deltaAxis2, deltaAxis3,
           fixedDelta1, fixedDelta2, fixedDelta3,
           pointDelta1, pointDelta2, pointDelta3,
           options);
  }

  // ----------------------------------------------------------------------
  void
  Params_KeyboardEventCallBack::apply(KeyboardEventCallback callback) const
  {
    if (! callback) return;

    // ------------------------------------------------------------
    if (key >= KeyCode::VK__BEGIN__) {
      // Invalid keycode
      IOLog("[KeyRemap4MacBook ERROR] Params_KeyboardEventCallBack::apply invalid key:%d\n", key);
      return;
    }

    if (config.option_drop_slowexpose) {
      // Skip if Shift+F8,F9,F10,F11,F12,EXPOSE_ALL.
      if (key == KeyCode::F8 || key == KeyCode::F9 ||
          key == KeyCode::F10 || key == KeyCode::F11 ||
          key == KeyCode::F12 || key == KeyCode::EXPOSE_ALL) {
        if (ModifierFlag::isOn(flags, ModifierFlag::SHIFT_L) ||
            ModifierFlag::isOn(flags, ModifierFlag::SHIFT_R)) {
          return;
        }
      }
    }

    if (config.option_jis_drop_eisuukana_with_modifiers) {
      // Skip if EISUU,KANA with any modifiers.
      if (key == KeyCode::JIS_EISUU || key == KeyCode::JIS_KANA) {
        if (flags != 0) {
          return;
        }
      }
    }

    // ------------------------------------------------------------
    log("sending");
    callback(target, eventType, flags, key, charCode, charSet, origCharCode, origCharSet,
             keyboardType, repeat, ts, sender, refcon);

    // XXX: comment out temporarily
    //EventWatcher::on();
  }

  void
  Params_KeyboardSpecialEventCallback::apply(KeyboardSpecialEventCallback callback) const
  {
    if (! callback) return;

    log("sending");
    callback(target, eventType, flags, key, flavor, guid, repeat, ts, sender, refcon);

    // XXX: comment out temporarily
    //EventWatcher::on();
  }

  void
  Params_RelativePointerEventCallback::apply(RelativePointerEventCallback callback) const
  {
    if (! callback) return;

    log("sending");
    callback(target, buttons, dx, dy, ts, sender, refcon);

    if (buttons != PointingButton::NONE) {
      EventWatcher::on();
    }
  }

  void
  Params_ScrollWheelEventCallback::apply(ScrollWheelEventCallback callback) const
  {
    if (! callback) return;

    log("sending");
    callback(target,
             deltaAxis1, deltaAxis2, deltaAxis3,
             fixedDelta1, fixedDelta2, fixedDelta3,
             pointDelta1, pointDelta2, pointDelta3,
             options, ts, sender, refcon);

    // EventWatcher::on is not necessary.
  }
}
<commit_msg>update CallBackWrapper around EventWatcher @ kext<commit_after>#include "CallBackWrapper.hpp"
#include "Config.hpp"
#include "EventWatcher.hpp"
#include "keycode.hpp"
#include "RemapUtil.hpp"

namespace org_pqrs_KeyRemap4MacBook {
  void
  Params_KeyboardEventCallBack::log(const char* message) const
  {
    if (! config.debug) return;

    printf("KeyRemap4MacBook KeyboardEventCallback [%s]: eventType %d, flags 0x%x, key %d, kbdType %d\n",
           message, eventType, flags, key, keyboardType);
  }

  void
  Params_KeyboardSpecialEventCallback::log(const char* message) const
  {
    if (! config.debug) return;

    printf("KeyRemap4MacBook KeyboardSpecialEventCallBack [%s]: eventType %d, flags 0x%x, key %d, flavor %d, guid %lld\n",
           message, eventType, flags, key, flavor, guid);
  }

  void
  Params_RelativePointerEventCallback::log(const char* message) const
  {
    if (! config.debug_pointing) return;

    printf("KeyRemap4MacBook RelativePointerEventCallBack [%s]: buttons: %d, dx: %d, dy: %d\n",
           message, buttons, dx, dy);
  }

  void
  Params_ScrollWheelEventCallback::log(const char* message) const
  {
    if (! config.debug_pointing) return;

#if __x86_64__
    const char* format = "KeyRemap4MacBook ScrollWheelEventCallback [%s]: deltaAxis(%d, %d, %d), fixedDelta(%ld, %ld, %ld), pointDelta(%d,%d,%d), options: %d\n";
#else
    const char* format = "KeyRemap4MacBook ScrollWheelEventCallback [%s]: deltaAxis(%d, %d, %d), fixedDelta(%d, %d, %d), pointDelta(%d,%d,%d), options: %d\n";
#endif
    printf(format,
           message,
           deltaAxis1, deltaAxis2, deltaAxis3,
           fixedDelta1, fixedDelta2, fixedDelta3,
           pointDelta1, pointDelta2, pointDelta3,
           options);
  }

  // ----------------------------------------------------------------------
  void
  Params_KeyboardEventCallBack::apply(KeyboardEventCallback callback) const
  {
    if (! callback) return;

    // ------------------------------------------------------------
    if (key >= KeyCode::VK__BEGIN__) {
      // Invalid keycode
      IOLog("[KeyRemap4MacBook ERROR] Params_KeyboardEventCallBack::apply invalid key:%d\n", key);
      return;
    }

    if (config.option_drop_slowexpose) {
      // Skip if Shift+F8,F9,F10,F11,F12,EXPOSE_ALL.
      if (key == KeyCode::F8 || key == KeyCode::F9 ||
          key == KeyCode::F10 || key == KeyCode::F11 ||
          key == KeyCode::F12 || key == KeyCode::EXPOSE_ALL) {
        if (ModifierFlag::isOn(flags, ModifierFlag::SHIFT_L) ||
            ModifierFlag::isOn(flags, ModifierFlag::SHIFT_R)) {
          return;
        }
      }
    }

    if (config.option_jis_drop_eisuukana_with_modifiers) {
      // Skip if EISUU,KANA with any modifiers.
      if (key == KeyCode::JIS_EISUU || key == KeyCode::JIS_KANA) {
        if (flags != 0) {
          return;
        }
      }
    }

    // ------------------------------------------------------------
    log("sending");
    callback(target, eventType, flags, key, charCode, charSet, origCharCode, origCharSet,
             keyboardType, repeat, ts, sender, refcon);

    switch (eventType) {
      case KeyEvent::DOWN:
        EventWatcher::on();
        break;
      case KeyEvent::MODIFY:
        if (RemapUtil::isModifierOn(flags, RemapUtil::getKeyCodeModifier(key))) {
          EventWatcher::on();
        }
        break;
      default:
        break;
    }
  }

  void
  Params_KeyboardSpecialEventCallback::apply(KeyboardSpecialEventCallback callback) const
  {
    if (! callback) return;

    log("sending");
    callback(target, eventType, flags, key, flavor, guid, repeat, ts, sender, refcon);

    if (eventType == KeyEvent::DOWN) {
      EventWatcher::on();
    }
  }

  void
  Params_RelativePointerEventCallback::apply(RelativePointerEventCallback callback) const
  {
    if (! callback) return;

    log("sending");
    callback(target, buttons, dx, dy, ts, sender, refcon);

    if (buttons != PointingButton::NONE) {
      EventWatcher::on();
    }
  }

  void
  Params_ScrollWheelEventCallback::apply(ScrollWheelEventCallback callback) const
  {
    if (! callback) return;

    log("sending");
    callback(target,
             deltaAxis1, deltaAxis2, deltaAxis3,
             fixedDelta1, fixedDelta2, fixedDelta3,
             pointDelta1, pointDelta2, pointDelta3,
             options, ts, sender, refcon);

    // EventWatcher::on is not necessary.
  }
}
<|endoftext|>


<commit_before>/*
 (Ported from Arduino to Energia)

USBSerial.cpp (formerly NewSoftSerial.cpp) -
 Multi-instance USB serial library for Arduino/Wiring

 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

//
// Includes
//
//#include <avr/interrupt.h>
//#include <avr/pgmspace.h>
//#include "Arduino.h"
#include "Energia.h"
#include "USBSerial.h"

#include "descriptors.h"

#include "device.h"
#include "types.h"               //Basic Type declarations
#include "usb.h"                 //USB-specific functions

#include "HAL_UCS.h"
//#include "HAL_PMM.h"

#include "UsbCdc.h"
#include "usbConstructs.h"

//
// Statics
//

//
// Private methods
//

volatile BYTE bCDCDataReceived_event = FALSE;   //Flag set by event handler to indicate data has been received into USB buffer

#define BUFFER_SIZE 256
char nl[2] = "\n";
char dataBuffer[BUFFER_SIZE] = "";
WORD count;

//
// Interrupt handling
//

/* static */
void USBSerial::handle_interrupt()
{
}

//
// Constructor
//
USBSerial::USBSerial(uint16_t port)
{
}

//
// Destructor
//
USBSerial::~USBSerial()
{
  end();
}

//
// Public methods
//

void USBSerial::begin()
{
    __disable_interrupt();                           //Enable interrupts globally
    //Initialization of clock module
    if (USB_PLL_XT == 2){
		#if defined (__MSP430F552x) || defined (__MSP430F550x)
			P5SEL |= 0x0C;                                      //enable XT2 pins for F5529
		#elif defined (__MSP430F563x_F663x)
			P7SEL |= 0x0C;
		#endif

        XT2_Start(XT2DRIVE_0);                                          //Start the "USB crystal"
    }
	else {
		#if defined (__MSP430F552x) || defined (__MSP430F550x)
			P5SEL |= 0x10;                                      //enable XT1 pins
		#endif

        XT1_Start(XT1DRIVE_0);                                          //Start the "USB crystal"
    }

    USB_init();                 //Init USB

    //Enable various USB event handling routines
    USB_setEnabledEvents(kUSB_allUsbEvents);

    // See if we're already attached physically to USB, and if so, connect to it
    // Normally applications don't invoke the event handlers, but this is an exception.
    if (USB_connectionInfo() & kUSB_vbusPresent)
      USB_handleVbusOnEvent();
    __enable_interrupt();                           //Enable interrupts globally
}

void USBSerial::end()
{
  USB_disable();
}

// Read data from buffer
int USBSerial::read()
{
  WORD count;
  BYTE dataBuffer = 0;

  // Read from "head"
  count = cdcReceiveDataInBuffer((BYTE*)&dataBuffer,
    1,
    CDC0_INTFNUM);                                //Count has the number of bytes received into
                                                  //dataBuffer
  // Empty buffer?
  if (count == 0){
    bCDCDataReceived_event = FALSE;
    return -1;
	}

  return (int)dataBuffer;
}

int USBSerial::available()
{
  if ( (USB_connectionState() == ST_ENUM_ACTIVE) && (USBCDC_bytesInUSBBuffer(CDC0_INTFNUM) > 0) ) return 1;
  return 0;
}

size_t USBSerial::write(uint8_t b)
{

  if (cdcSendDataInBackground((BYTE*)&b,1,CDC0_INTFNUM,0)){  	//send char to the Host
    return 0;   // could not write
  }
  return 1;
}

size_t USBSerial::write(const uint8_t *buffer, size_t size)
{

  if (cdcSendDataInBackground((BYTE*)buffer,size,CDC0_INTFNUM,0)){  	//send char to the Host
    return 0;   // could not write
  }
  return 1;
}

void USBSerial::flush()
{
  while (USBCDC_bytesInUSBBuffer(CDC0_INTFNUM) > 0);            // wait till all send
}

int USBSerial::peek()
{

  // Empty buffer?
  if (USBCDC_bytesInUSBBuffer(CDC0_INTFNUM) == 0)
    return -1;

  // Read from "head"
  return USBCDC_bytesInUSBBuffer(CDC0_INTFNUM);
}

/*
 * ======== UNMI_ISR ========
 */
#ifndef __GNUC__
#pragma vector = UNMI_VECTOR
__interrupt
#else
__attribute__((interrupt(UNMI_VECTOR)))
#endif
//UNMI interrupt service routine
static void UNMI_ISR(void)
{
    switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG ))
    {
        case SYSUNIV_NONE:
            __no_operation();
            break;
        case SYSUNIV_NMIIFG:
            __no_operation();
            break;
        case SYSUNIV_OFIFG:
            UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT2OFFG); //Clear OSC flaut Flags fault flags
            SFRIFG1 &= ~OFIFG;                          //Clear OFIFG fault flag
            break;
        case SYSUNIV_ACCVIFG:
            __no_operation();
            break;
        case SYSUNIV_BUSIFG:
            SYSBERRIV = 0;                                      //clear bus error flag
            USB_disable();                                      //Disable
    }
}
<commit_msg>change transmition mode from cdcSendDataInBackground to cdcSendDataWaitTilDone old method give issues if data on Stack should be transmited and the stack get cleaned up in the main function during the background process<commit_after>/*
 (Ported from Arduino to Energia)

USBSerial.cpp (formerly NewSoftSerial.cpp) -
 Multi-instance USB serial library for Arduino/Wiring

 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

//
// Includes
//
//#include <avr/interrupt.h>
//#include <avr/pgmspace.h>
//#include "Arduino.h"
#include "Energia.h"
#include "USBSerial.h"

#include "descriptors.h"

#include "device.h"
#include "types.h"               //Basic Type declarations
#include "usb.h"                 //USB-specific functions

#include "HAL_UCS.h"
//#include "HAL_PMM.h"

#include "UsbCdc.h"
#include "usbConstructs.h"

//
// Statics
//

//
// Private methods
//

volatile BYTE bCDCDataReceived_event = FALSE;   //Flag set by event handler to indicate data has been received into USB buffer

#define BUFFER_SIZE 256
char nl[2] = "\n";
char dataBuffer[BUFFER_SIZE] = "";
WORD count;

//
// Interrupt handling
//

/* static */
void USBSerial::handle_interrupt()
{
}

//
// Constructor
//
USBSerial::USBSerial(uint16_t port)
{
}

//
// Destructor
//
USBSerial::~USBSerial()
{
  end();
}

//
// Public methods
//

void USBSerial::begin()
{
    __disable_interrupt();                           //Enable interrupts globally
    //Initialization of clock module
    if (USB_PLL_XT == 2){
		#if defined (__MSP430F552x) || defined (__MSP430F550x)
			P5SEL |= 0x0C;                                      //enable XT2 pins for F5529
		#elif defined (__MSP430F563x_F663x)
			P7SEL |= 0x0C;
		#endif

        XT2_Start(XT2DRIVE_0);                                          //Start the "USB crystal"
    }
	else {
		#if defined (__MSP430F552x) || defined (__MSP430F550x)
			P5SEL |= 0x10;                                      //enable XT1 pins
		#endif

        XT1_Start(XT1DRIVE_0);                                          //Start the "USB crystal"
    }

    USB_init();                 //Init USB

    //Enable various USB event handling routines
    USB_setEnabledEvents(kUSB_allUsbEvents);

    // See if we're already attached physically to USB, and if so, connect to it
    // Normally applications don't invoke the event handlers, but this is an exception.
    if (USB_connectionInfo() & kUSB_vbusPresent)
      USB_handleVbusOnEvent();
    __enable_interrupt();                           //Enable interrupts globally
}

void USBSerial::end()
{
  USB_disable();
}

// Read data from buffer
int USBSerial::read()
{
  WORD count;
  BYTE dataBuffer = 0;

  // Read from "head"
  count = cdcReceiveDataInBuffer((BYTE*)&dataBuffer,
    1,
    CDC0_INTFNUM);                                //Count has the number of bytes received into
                                                  //dataBuffer
  // Empty buffer?
  if (count == 0){
    bCDCDataReceived_event = FALSE;
    return -1;
	}

  return (int)dataBuffer;
}

int USBSerial::available()
{
  if ( (USB_connectionState() == ST_ENUM_ACTIVE) && (USBCDC_bytesInUSBBuffer(CDC0_INTFNUM) > 0) ) return 1;
  return 0;
}

size_t USBSerial::write(uint8_t b)
{

  if (cdcSendDataWaitTilDone((BYTE*)&b,1,CDC0_INTFNUM,0)){  	//send char to the Host
    return 0;   // could not write
  }
  return 1;
}

size_t USBSerial::write(const uint8_t *buffer, size_t size)
{

  if (cdcSendDataWaitTilDone((BYTE*)buffer,size,CDC0_INTFNUM,0)){  	//send char to the Host
    return 0;   // could not write
  }
  return 1;
}

void USBSerial::flush()
{
  while (USBCDC_bytesInUSBBuffer(CDC0_INTFNUM) > 0);            // wait till all send
}

int USBSerial::peek()
{

  // Empty buffer?
  if (USBCDC_bytesInUSBBuffer(CDC0_INTFNUM) == 0)
    return -1;

  // Read from "head"
  return USBCDC_bytesInUSBBuffer(CDC0_INTFNUM);
}

/*
 * ======== UNMI_ISR ========
 */
#ifndef __GNUC__
#pragma vector = UNMI_VECTOR
__interrupt
#else
__attribute__((interrupt(UNMI_VECTOR)))
#endif
//UNMI interrupt service routine
static void UNMI_ISR(void)
{
    switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG ))
    {
        case SYSUNIV_NONE:
            __no_operation();
            break;
        case SYSUNIV_NMIIFG:
            __no_operation();
            break;
        case SYSUNIV_OFIFG:
            UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT2OFFG); //Clear OSC flaut Flags fault flags
            SFRIFG1 &= ~OFIFG;                          //Clear OFIFG fault flag
            break;
        case SYSUNIV_ACCVIFG:
            __no_operation();
            break;
        case SYSUNIV_BUSIFG:
            SYSBERRIV = 0;                                      //clear bus error flag
            USB_disable();                                      //Disable
    }
}
<|endoftext|>


<commit_before>#include "opencv2/opencv.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace cv;

#include "Pipeline.hpp"

void Pipeline::extract_features(const Images& images,CamFrames& cam_Frames,DescriptorsVec& descriptors_vec)
{
	// create a sift detector
	// const int feature_num = 50;
	// Ptr<Feature2D> sift_detector = SIFT::create(feature_num);

	// create brist detector
	// parameters for brisk : int thresh = 30, int octaves = 3, float patternScale = 1.0f
	Ptr<Feature2D> brisk_detector = BRISK::create();

	// detect features in a loop
	for (int i = 0; i < images.size(); ++i)
	{
		KeyPoints key_points;
		Descriptors descriptors;
		// detects and computes descriptors

		brisk_detector->detectAndCompute(images[i].gray,noArray(),key_points,descriptors);
		// wrap keypoints to cam_Frame and add in to cam_Frames
		cam_Frames.push_back((CamFrame) {key_points});
		descriptors_vec.push_back(descriptors);
	}
}<commit_msg>Try SIFT feature detection<commit_after>#include "opencv2/opencv.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d/nonfree.hpp"
using namespace cv;

#include "Pipeline.hpp"

void Pipeline::extract_features(const Images& images,CamFrames& cam_Frames,DescriptorsVec& descriptors_vec)
{
	// create a sift detector
	const int    feature_num      = 800;
	const int    octavelayers_num = 3;
	const double constrast_thresh = .04f;
	const double edge_threshold   = 4.f;
	const double sigma            = 1.3f;
	Ptr<Feature2D> sift_detector = xfeatures2d::SIFT::create(feature_num,
		octavelayers_num, constrast_thresh, edge_threshold, sigma);

	// create brist detector
	// parameters for brisk : int thresh = 30, int octaves = 3, float patternScale = 1.0f
	//Ptr<Feature2D> brisk_detector = BRISK::create();

	// detect features in a loop
	for (int i = 0; i < images.size(); ++i)
	{
		KeyPoints key_points;
		Descriptors descriptors;
		// detects and computes descriptors

		sift_detector->detectAndCompute(images[i].gray,noArray(),key_points,descriptors);
		// wrap keypoints to cam_Frame and add in to cam_Frames
		cam_Frames.push_back((CamFrame) {key_points});
		descriptors_vec.push_back(descriptors);
	}
}
<|endoftext|>


<commit_before>/*
flink.cpp

 ࠧ 㭪権  ࠡ⪥ Link` - Hard&Sym

*/

/* Revision: 1.01 04.01.2001 $ */

/*
Modify:
  04.01.2001 SVS
    + 㦪  CreateJunctionPoint, DeleteJunctionPoint
    + GetJunctionPointInfo -    Junc
  03.01.2001 SVS
    ! 뤥  ⢥ ᠬ⥫쭮
    + GetNumberOfLinks  MkLink ॥堫  mix.cpp
*/

#include "headers.hpp"
#pragma hdrstop

#include "internalheaders.hpp"

#if defined(__BORLANDC__)
  #define CP_THREAD_ACP             3           // current thread's ANSI code page

  #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE      ( 16 * 1024 )
  // Predefined reparse tags.
  // These tags need to avoid conflicting with IO_REMOUNT defined in ntos\inc\io.h
  #define IO_REPARSE_TAG_RESERVED_ZERO             (0)
  #define IO_REPARSE_TAG_RESERVED_ONE              (1)

  // The value of the following constant needs to satisfy the following conditions:
  //  (1) Be at least as large as the largest of the reserved tags.
  //  (2) Be strictly smaller than all the tags in use.
  #define IO_REPARSE_TAG_RESERVED_RANGE            IO_REPARSE_TAG_RESERVED_ONE
  // The following constant represents the bits that are valid to use in
  // reparse tags.
  #define IO_REPARSE_TAG_VALID_VALUES     (0xE000FFFF)
  // Macro to determine whether a reparse tag is a valid tag.
  #define IsReparseTagValid(_tag) (                               \
                    !((_tag) & ~IO_REPARSE_TAG_VALID_VALUES) &&   \
                    ((_tag) > IO_REPARSE_TAG_RESERVED_RANGE)      \
                   )
  #define FILE_FLAG_OPEN_REPARSE_POINT    0x00200000
  #define FSCTL_GET_REPARSE_POINT         CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) // REPARSE_DATA_BUFFER
#endif
struct TMN_REPARSE_DATA_BUFFER
{
  DWORD  ReparseTag;
  WORD   ReparseDataLength;
  WORD   Reserved;

  // IO_REPARSE_TAG_MOUNT_POINT specifics follow
  WORD   SubstituteNameOffset;
  WORD   SubstituteNameLength;
  WORD   PrintNameOffset;
  WORD   PrintNameLength;
  WCHAR  PathBuffer[1];

  // Some helper functions
  //BOOL Init(LPCSTR szJunctionPoint);
  //BOOL Init(LPCWSTR wszJunctionPoint);
  //int BytesForIoControl() const;
};

BOOL WINAPI CreateJunctionPoint(LPCTSTR szMountDir, LPCTSTR szDestDirArg)
{
  return TRUE;
}

BOOL WINAPI DeleteJunctionPoint(LPCTSTR szDir)
{
  return TRUE;
}

DWORD WINAPI GetJunctionPointInfo(LPCTSTR szMountDir,
              LPTSTR  szDestBuff,
              DWORD   dwBuffSize)
{
  const DWORD FileAttr = GetFileAttributes(szMountDir);
  if (FileAttr == 0xffffffff || !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
  {
    SetLastError(ERROR_PATH_NOT_FOUND);
    return 0;
  }

  HANDLE hDir=CreateFile(szMountDir,GENERIC_READ|0,0,0,OPEN_EXISTING,
          FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,0);

  if (hDir == INVALID_HANDLE_VALUE)
  {
    SetLastError(ERROR_PATH_NOT_FOUND);
    return 0;
  }

  char szBuff[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
  TMN_REPARSE_DATA_BUFFER& rdb = *(TMN_REPARSE_DATA_BUFFER*)szBuff;

  DWORD dwBytesReturned;
  if (!DeviceIoControl(hDir,
            FSCTL_GET_REPARSE_POINT,
            NULL,
            0,
            (LPVOID)&rdb,
            MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
            &dwBytesReturned,
            0) ||
    !IsReparseTagValid(rdb.ReparseTag))
  {
    CloseHandle(hDir);
    return 0;
  }

  CloseHandle(hDir);

  if (dwBuffSize < rdb.SubstituteNameLength / sizeof(TCHAR) + sizeof(TCHAR))
  {
    return rdb.SubstituteNameLength / sizeof(TCHAR) + sizeof(TCHAR);
  }

#ifdef UNICODE
  lstrcpy(szDestBuff, rdb.PathBuffer);
#else
  if (!WideCharToMultiByte(CP_THREAD_ACP,
              0,
              rdb.PathBuffer,
              rdb.SubstituteNameLength / sizeof(WCHAR) + 1,
              szDestBuff,
              dwBuffSize,
              "",
              FALSE))
  {
    //printf("WideCharToMultiByte failed (%d)\n", GetLastError());
    return 0;
  }
#endif
  return rdb.SubstituteNameLength / sizeof(TCHAR);
}

/* $ 07.09.2000 SVS
   㭪 GetNumberOfLinks ⮦ 㯭  :-)
*/
int WINAPI GetNumberOfLinks(char *Name)
{
  HANDLE hFile=CreateFile(Name,0,FILE_SHARE_READ|FILE_SHARE_WRITE,
                          NULL,OPEN_EXISTING,0,NULL);
  if (hFile==INVALID_HANDLE_VALUE)
    return(1);
  BY_HANDLE_FILE_INFORMATION bhfi;
  int GetCode=GetFileInformationByHandle(hFile,&bhfi);
  CloseHandle(hFile);
  return(GetCode ? bhfi.nNumberOfLinks:0);
}
/* SVS $*/

#if defined(__BORLANDC__)
#pragma option -a4
#endif
int WINAPI MkLink(char *Src,char *Dest)
{
  struct CORRECTED_WIN32_STREAM_ID
  {
    DWORD          dwStreamId ;
    DWORD          dwStreamAttributes ;
    LARGE_INTEGER  Size ;
    DWORD          dwStreamNameSize ;
    WCHAR          cStreamName[ ANYSIZE_ARRAY ] ;
  } StreamId;

  char FileSource[NM],FileDest[NM];
  WCHAR FileLink[NM];

  HANDLE hFileSource;

  DWORD dwBytesWritten;
  LPVOID lpContext;
  DWORD cbPathLen;
  DWORD StreamSize;

  BOOL bSuccess;

//  ConvertNameToFull(Src,FileSource, sizeof(FileSource));
  if (ConvertNameToFull(Src,FileSource, sizeof(FileSource)) >= sizeof(FileSource)){
    return FALSE;
  }
//  ConvertNameToFull(Dest,FileDest, sizeof(FileDest));
  if (ConvertNameToFull(Dest,FileDest, sizeof(FileDest)) >= sizeof(FileDest)){
    return FALSE;
  }
  MultiByteToWideChar(CP_OEMCP,0,FileDest,-1,FileLink,sizeof(FileLink)/sizeof(FileLink[0]));

  hFileSource = CreateFile(FileSource,FILE_WRITE_ATTRIBUTES,
                FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);

  if(hFileSource == INVALID_HANDLE_VALUE)
    return(FALSE);

  lpContext = NULL;
  cbPathLen = (lstrlenW(FileLink) + 1) * sizeof(WCHAR);

  StreamId.dwStreamId = BACKUP_LINK;
  StreamId.dwStreamAttributes = 0;
  StreamId.dwStreamNameSize = 0;
  StreamId.Size.u.HighPart = 0;
  StreamId.Size.u.LowPart = cbPathLen;

  StreamSize=sizeof(StreamId)-sizeof(WCHAR **)+StreamId.dwStreamNameSize;

  bSuccess = BackupWrite(hFileSource,(LPBYTE)&StreamId,StreamSize,
             &dwBytesWritten,FALSE,FALSE,&lpContext);

  int LastError=0;

  if (bSuccess)
  {
    bSuccess = BackupWrite(hFileSource,(LPBYTE)FileLink,cbPathLen,
                &dwBytesWritten,FALSE,FALSE,&lpContext);
    if (!bSuccess)
      LastError=GetLastError();

    BackupWrite(hFileSource,NULL,0,&dwBytesWritten,TRUE,FALSE,&lpContext);
  }
  else
    LastError=GetLastError();

  CloseHandle(hFileSource);

  if (LastError)
    SetLastError(LastError);

  return(bSuccess);
}
#if defined(__BORLANDC__)
#pragma option -a.
#endif

<commit_msg>FAR patch 00364.flink.cpp Дата              : 05.01.2001 Сделал            : Oleg Taranenko Описание          : - Косметика, из-за которой не компилился под VC :) Измененные файлы  : flink.cpp Состав            : 00364.flink.cpp.txt                     flink.cpp.364.diff Основан на патче  : 362 Дополнение        :      Все определения будут видны всем компиляторам<commit_after>/*
flink.cpp

 ࠧ 㭪権  ࠡ⪥ Link` - Hard&Sym

*/

/* Revision: 1.03 04.01.2001 $ */

/*
Modify:
  05.01.2000 OT
    - ᬥ⨪, - ன    VC :)
  04.01.2001 SVS
    + 誨  CreateJunctionPoint, DeleteJunctionPoint
    + GetJunctionPointInfo -    Junc
  03.01.2001 SVS
    ! 뤥  ⢥ ᠬ⥫쭮
    + GetNumberOfLinks  MkLink ॥堫  mix.cpp
*/

#include "headers.hpp"
#pragma hdrstop

#include "internalheaders.hpp"

//#if defined(__BORLANDC__)
// current thread's ANSI code page
  #define CP_THREAD_ACP             3

  #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE      ( 16 * 1024 )
  // Predefined reparse tags.
  // These tags need to avoid conflicting with IO_REMOUNT defined in ntos\inc\io.h
  #define IO_REPARSE_TAG_RESERVED_ZERO             (0)
  #define IO_REPARSE_TAG_RESERVED_ONE              (1)

  // The value of the following constant needs to satisfy the following conditions:
  //  (1) Be at least as large as the largest of the reserved tags.
  //  (2) Be strictly smaller than all the tags in use.
  #define IO_REPARSE_TAG_RESERVED_RANGE            IO_REPARSE_TAG_RESERVED_ONE
  // The following constant represents the bits that are valid to use in
  // reparse tags.
  #define IO_REPARSE_TAG_VALID_VALUES     (0xE000FFFF)
  // Macro to determine whether a reparse tag is a valid tag.
  #define IsReparseTagValid(_tag) (                               \
                    !((_tag) & ~IO_REPARSE_TAG_VALID_VALUES) &&   \
                    ((_tag) > IO_REPARSE_TAG_RESERVED_RANGE)      \
                   )
  #define FILE_FLAG_OPEN_REPARSE_POINT    0x00200000
  #define FSCTL_GET_REPARSE_POINT         CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
// REPARSE_DATA_BUFFER
//#endif
struct TMN_REPARSE_DATA_BUFFER
{
  DWORD  ReparseTag;
  WORD   ReparseDataLength;
  WORD   Reserved;

  // IO_REPARSE_TAG_MOUNT_POINT specifics follow
  WORD   SubstituteNameOffset;
  WORD   SubstituteNameLength;
  WORD   PrintNameOffset;
  WORD   PrintNameLength;
  WCHAR  PathBuffer[1];

  // Some helper functions
  //BOOL Init(LPCSTR szJunctionPoint);
  //BOOL Init(LPCWSTR wszJunctionPoint);
  //int BytesForIoControl() const;
};

BOOL WINAPI CreateJunctionPoint(LPCTSTR szMountDir, LPCTSTR szDestDirArg)
{
  return TRUE;
}

BOOL WINAPI DeleteJunctionPoint(LPCTSTR szDir)
{
  return TRUE;
}

DWORD WINAPI GetJunctionPointInfo(LPCTSTR szMountDir,
              LPTSTR  szDestBuff,
              DWORD   dwBuffSize)
{
  const DWORD FileAttr = GetFileAttributes(szMountDir);
  if (FileAttr == 0xffffffff || !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
  {
    SetLastError(ERROR_PATH_NOT_FOUND);
    return 0;
  }

  HANDLE hDir=CreateFile(szMountDir,GENERIC_READ|0,0,0,OPEN_EXISTING,
          FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,0);

  if (hDir == INVALID_HANDLE_VALUE)
  {
    SetLastError(ERROR_PATH_NOT_FOUND);
    return 0;
  }

  char szBuff[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
  TMN_REPARSE_DATA_BUFFER& rdb = *(TMN_REPARSE_DATA_BUFFER*)szBuff;

  DWORD dwBytesReturned;
  if (!DeviceIoControl(hDir,
            FSCTL_GET_REPARSE_POINT,
            NULL,
            0,
            (LPVOID)&rdb,
            MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
            &dwBytesReturned,
            0) ||
    !IsReparseTagValid(rdb.ReparseTag))
  {
    CloseHandle(hDir);
    return 0;
  }

  CloseHandle(hDir);

  if (dwBuffSize < rdb.SubstituteNameLength / sizeof(TCHAR) + sizeof(TCHAR))
  {
    return rdb.SubstituteNameLength / sizeof(TCHAR) + sizeof(TCHAR);
  }

#ifdef UNICODE
  lstrcpy(szDestBuff, rdb.PathBuffer);
#else
  if (!WideCharToMultiByte(CP_THREAD_ACP,
              0,
              rdb.PathBuffer,
              rdb.SubstituteNameLength / sizeof(WCHAR) + 1,
              szDestBuff,
              dwBuffSize,
              "",
              FALSE))
  {
    //printf("WideCharToMultiByte failed (%d)\n", GetLastError());
    return 0;
  }
#endif
  return rdb.SubstituteNameLength / sizeof(TCHAR);
}

/* $ 07.09.2000 SVS
   㭪 GetNumberOfLinks ⮦ 㯭  :-)
*/
int WINAPI GetNumberOfLinks(char *Name)
{
  HANDLE hFile=CreateFile(Name,0,FILE_SHARE_READ|FILE_SHARE_WRITE,
                          NULL,OPEN_EXISTING,0,NULL);
  if (hFile==INVALID_HANDLE_VALUE)
    return(1);
  BY_HANDLE_FILE_INFORMATION bhfi;
  int GetCode=GetFileInformationByHandle(hFile,&bhfi);
  CloseHandle(hFile);
  return(GetCode ? bhfi.nNumberOfLinks:0);
}
/* SVS $*/

#if defined(__BORLANDC__)
#pragma option -a4
#endif
int WINAPI MkLink(char *Src,char *Dest)
{
  struct CORRECTED_WIN32_STREAM_ID
  {
    DWORD          dwStreamId ;
    DWORD          dwStreamAttributes ;
    LARGE_INTEGER  Size ;
    DWORD          dwStreamNameSize ;
    WCHAR          cStreamName[ ANYSIZE_ARRAY ] ;
  } StreamId;

  char FileSource[NM],FileDest[NM];
  WCHAR FileLink[NM];

  HANDLE hFileSource;

  DWORD dwBytesWritten;
  LPVOID lpContext;
  DWORD cbPathLen;
  DWORD StreamSize;

  BOOL bSuccess;

//  ConvertNameToFull(Src,FileSource, sizeof(FileSource));
  if (ConvertNameToFull(Src,FileSource, sizeof(FileSource)) >= sizeof(FileSource)){
    return FALSE;
  }
//  ConvertNameToFull(Dest,FileDest, sizeof(FileDest));
  if (ConvertNameToFull(Dest,FileDest, sizeof(FileDest)) >= sizeof(FileDest)){
    return FALSE;
  }
  MultiByteToWideChar(CP_OEMCP,0,FileDest,-1,FileLink,sizeof(FileLink)/sizeof(FileLink[0]));

  hFileSource = CreateFile(FileSource,FILE_WRITE_ATTRIBUTES,
                FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);

  if(hFileSource == INVALID_HANDLE_VALUE)
    return(FALSE);

  lpContext = NULL;
  cbPathLen = (lstrlenW(FileLink) + 1) * sizeof(WCHAR);

  StreamId.dwStreamId = BACKUP_LINK;
  StreamId.dwStreamAttributes = 0;
  StreamId.dwStreamNameSize = 0;
  StreamId.Size.u.HighPart = 0;
  StreamId.Size.u.LowPart = cbPathLen;

  StreamSize=sizeof(StreamId)-sizeof(WCHAR **)+StreamId.dwStreamNameSize;

  bSuccess = BackupWrite(hFileSource,(LPBYTE)&StreamId,StreamSize,
             &dwBytesWritten,FALSE,FALSE,&lpContext);

  int LastError=0;

  if (bSuccess)
  {
    bSuccess = BackupWrite(hFileSource,(LPBYTE)FileLink,cbPathLen,
                &dwBytesWritten,FALSE,FALSE,&lpContext);
    if (!bSuccess)
      LastError=GetLastError();

    BackupWrite(hFileSource,NULL,0,&dwBytesWritten,TRUE,FALSE,&lpContext);
  }
  else
    LastError=GetLastError();

  CloseHandle(hFileSource);

  if (LastError)
    SetLastError(LastError);

  return(bSuccess);
}
#if defined(__BORLANDC__)
#pragma option -a.
#endif

<|endoftext|>


<commit_before>#include	"Action/UseConnection.hh"

/**
   Change to another map using a connection

   @param dir   The direction of the next screen
 */
Action::UseConnection::UseConnection(uint8_t dir)
  : _dir(dir)
{
}

Action::UseConnection::~UseConnection()
{
}

void		Action::UseConnection::_init()
{
  EKey          dirToKey[] = {KEY_DOWN, KEY_UP, KEY_LEFT, KEY_RIGHT};
  Player        &p = _data.getPlayer();
  World::Map    &m = _data.getWorld()[p.getBankId()][p.getMapId()];

  if (_dir == CO_NONE || _dir > CO_RIGHT)
    {
      fprintf(stderr, "Only _directions Up, Down, Left and Right are currently suported\n");
      _state = Action::ERROR;
      return;
    }
  bool          vtcl = _dir == CO_UP || _dir == CO_DOWN;
  uint32_t      x = (_dir == CO_RIGHT ? m.getWidth() - 1 : 0);
  uint32_t      y = (_dir == CO_DOWN ? m.getHeight() - 1 : 0);
  int           xstep = vtcl;
  int           ystep = !vtcl;

  while (x < m.getWidth() && y < m.getHeight())
    {
      if (m.getNode(x, y).getStatus() == 0x0C) // Empty node, we should be able to cross there
        break;
      x += xstep;
      y += ystep;
    }
  if (x >= m.getWidth() || y >= m.getHeight())
    {
      fprintf(stderr, "Couldn't find an exit in the specified direction\n");
      _state = Action::ERROR;
      return;
    }
  _tx = x;
  _ty = y;
  _keyDir = dirToKey[_dir - 1];
  _origBank = p.getBankId();
  _origMap = p.getMapId();
  queue(new Action::MoveTo(_tx, _ty));
}

void		Action::UseConnection::_update()
{
  Player        &p = _data.getPlayer();

  if (p.getBankId() != _origBank || p.getMapId() != _origMap)
    _state = Action::FINISHED;
  else if (p.getX() != _tx || p.getY() != _ty)
    emit("onInit");
  else
    sdlSetButton(_keyDir, getCounter() % 2);
}
<commit_msg>wait for the movement to next screen to complete<commit_after>#include	"Action/UseConnection.hh"

/**
   Change to another map using a connection

   @param dir   The direction of the next screen
 */
Action::UseConnection::UseConnection(uint8_t dir)
  : _dir(dir)
{
}

Action::UseConnection::~UseConnection()
{
}

void		Action::UseConnection::_init()
{
  EKey          dirToKey[] = {KEY_DOWN, KEY_UP, KEY_LEFT, KEY_RIGHT};
  Player        &p = _data.getPlayer();
  World::Map    &m = _data.getWorld()[p.getBankId()][p.getMapId()];

  if (_dir == CO_NONE || _dir > CO_RIGHT)
    {
      fprintf(stderr, "Only _directions Up, Down, Left and Right are currently suported\n");
      _state = Action::ERROR;
      return;
    }
  bool          vtcl = _dir == CO_UP || _dir == CO_DOWN;
  uint32_t      x = (_dir == CO_RIGHT ? m.getWidth() - 1 : 0);
  uint32_t      y = (_dir == CO_DOWN ? m.getHeight() - 1 : 0);
  int           xstep = vtcl;
  int           ystep = !vtcl;

  while (x < m.getWidth() && y < m.getHeight())
    {
      if (m.getNode(x, y).getStatus() == 0x0C) // Empty node, we should be able to cross there
        break;
      x += xstep;
      y += ystep;
    }
  if (x >= m.getWidth() || y >= m.getHeight())
    {
      fprintf(stderr, "Couldn't find an exit in the specified direction\n");
      _state = Action::ERROR;
      return;
    }
  _tx = x;
  _ty = y;
  _keyDir = dirToKey[_dir - 1];
  _origBank = p.getBankId();
  _origMap = p.getMapId();
  queue(new Action::MoveTo(_tx, _ty));
}

void		Action::UseConnection::_update()
{
  Player        &p = _data.getPlayer();
  const OverWorld       &ow = _data.getOverWorld(0);

  if (p.getBankId() != _origBank || p.getMapId() != _origMap)
    {
      if (p.getX() == ow.getX() && p.getX() == ow.getDestX() &&
          p.getY() == ow.getY() && p.getY() == ow.getDestY())
        _state = Action::FINISHED;
    }
  else if (p.getX() != _tx || p.getY() != _ty)
    emit("onInit");
  else
    sdlSetButton(_keyDir, getCounter() % 2);
}
<|endoftext|>