Tacton library initial import
authorThomas Pietrzak <thomas.pietrzak@gmail.com>
Tue, 14 Jun 2011 19:13:33 +0000 (19:13 +0000)
committerThomas Pietrzak <thomas.pietrzak@gmail.com>
Tue, 14 Jun 2011 19:13:33 +0000 (19:13 +0000)
git-svn-id: svn+ssh://thomaspietrzak.com/var/svn/rep@28 47cf9a05-e0a8-4ed5-9e9b-101a649bc004

13 files changed:
TactonLibrary.sdf [new file with mode: 0644]
TactonLibrary.sln [new file with mode: 0644]
TactonLibrary.suo [new file with mode: 0644]
TactonPlayer/Serial.cpp [new file with mode: 0644]
TactonPlayer/Serial.hpp [new file with mode: 0644]
TactonPlayer/SerialWindows.cpp [new file with mode: 0644]
TactonPlayer/SerialWindows.hpp [new file with mode: 0644]
TactonPlayer/Tacton.cpp [new file with mode: 0644]
TactonPlayer/Tacton.hpp [new file with mode: 0644]
TactonPlayer/TactonPlayer.cpp [new file with mode: 0644]
TactonPlayer/TactonPlayer.hpp [new file with mode: 0644]
TactonPlayer/TactonPlayer.vcxproj [new file with mode: 0644]
TactonPlayer/TactonPlayer.vcxproj.filters [new file with mode: 0644]

diff --git a/TactonLibrary.sdf b/TactonLibrary.sdf
new file mode 100644 (file)
index 0000000..9557225
Binary files /dev/null and b/TactonLibrary.sdf differ
diff --git a/TactonLibrary.sln b/TactonLibrary.sln
new file mode 100644 (file)
index 0000000..9cc6d11
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual Studio 2010\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TactonPlayer", "TactonPlayer\TactonPlayer.vcxproj", "{6D5C62C0-562D-4B2A-9AAC-806372810CBF}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               Release|Win32 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {6D5C62C0-562D-4B2A-9AAC-806372810CBF}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {6D5C62C0-562D-4B2A-9AAC-806372810CBF}.Debug|Win32.Build.0 = Debug|Win32\r
+               {6D5C62C0-562D-4B2A-9AAC-806372810CBF}.Release|Win32.ActiveCfg = Release|Win32\r
+               {6D5C62C0-562D-4B2A-9AAC-806372810CBF}.Release|Win32.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/TactonLibrary.suo b/TactonLibrary.suo
new file mode 100644 (file)
index 0000000..4b9a884
Binary files /dev/null and b/TactonLibrary.suo differ
diff --git a/TactonPlayer/Serial.cpp b/TactonPlayer/Serial.cpp
new file mode 100644 (file)
index 0000000..e527263
--- /dev/null
@@ -0,0 +1,10 @@
+#include "Serial.hpp"\r
+\r
+Serial::Serial(char *)\r
+:_connected(false)\r
+{\r
+}\r
+\r
+Serial::~Serial()\r
+{\r
+}\r
diff --git a/TactonPlayer/Serial.hpp b/TactonPlayer/Serial.hpp
new file mode 100644 (file)
index 0000000..f306af7
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _SERIAL_\r
+#define _SERIAL_\r
+\r
+#define ARDUINO_WAIT_TIME 500\r
+\r
+class Serial\r
+{\r
+    public:\r
+        //Initialize Serial communication with the given COM port\r
+        Serial(char *portName);\r
+\r
+        //Close the connection\r
+        //NOTA: for some reason you can't connect again before exiting\r
+        //the program and running it again\r
+        virtual ~Serial();\r
+\r
+        //Read data in a buffer, if nbChar is greater than the\r
+        //maximum number of bytes available, it will return only the\r
+        //bytes available. The function return -1 when nothing could\r
+        //be read, the number of bytes actually read.\r
+        virtual int ReadData(void *buffer, unsigned int nbChar)=0;\r
+\r
+        //Writes data from a buffer through the Serial connection\r
+        //return true on success.\r
+        virtual bool WriteData(void *buffer, unsigned int nbChar)=0;\r
+\r
+        //Check if we are actually connected\r
+               bool IsConnected() { return _connected; }\r
+\r
+    protected:\r
+        //Connection status\r
+        bool _connected;\r
+};\r
+\r
+#endif\r
diff --git a/TactonPlayer/SerialWindows.cpp b/TactonPlayer/SerialWindows.cpp
new file mode 100644 (file)
index 0000000..38806ef
--- /dev/null
@@ -0,0 +1,142 @@
+#include "SerialWindows.hpp"\r
+\r
+#include <iostream>\r
+using namespace std;\r
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+\r
+SerialWindows::SerialWindows(char *portName)\r
+:Serial(portName)\r
+{\r
+    //Try to connect to the given port throuh CreateFile\r
+    _hSerial = CreateFileA(portName,\r
+            GENERIC_READ | GENERIC_WRITE,\r
+            0,\r
+            NULL,\r
+            OPEN_EXISTING,\r
+            FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, //FILE_ATTRIBUTE_NORMAL,\r
+            NULL);\r
+\r
+    //Check if the connection was successfull\r
+    if(_hSerial == INVALID_HANDLE_VALUE)\r
+    {\r
+        //If not success full display an Error\r
+        if(GetLastError() == ERROR_FILE_NOT_FOUND)\r
+            cerr << "ERROR: Handle was not attached. Reason: " << portName << " not available." << endl;\r
+        else\r
+            cerr << "ERROR unknown" << endl;\r
+               char buffer[256];\r
+               sprintf(buffer, "Port %s does not exist or not reachable", portName);\r
+               throw buffer;\r
+    }\r
+    else\r
+    {\r
+       /*      
+       COMMTIMEOUTS commTimeouts;
+       commTimeouts.ReadIntervalTimeout = 1;
+       commTimeouts.ReadTotalTimeoutMultiplier = 10;
+       commTimeouts.ReadTotalTimeoutConstant = 100;
+       commTimeouts.WriteTotalTimeoutMultiplier = 10;
+       commTimeouts.WriteTotalTimeoutConstant = 100;
+       if (SetCommTimeouts(_comport, &commTimeouts) == 0)
+               throw "Cannot set COM port timeouts";*/
+\r
+\r
+        //If connected we try to set the comm parameters\r
+        DCB dcbSerialParams = {0};\r
+\r
+        //Try to get the current\r
+        if (!GetCommState(_hSerial, &dcbSerialParams))\r
+            //If impossible, show an error\r
+            cerr << "ERROR: failed to get current serial parameters!" << endl;\r
+        else\r
+        {\r
+            //Define serial connection parameters for the arduino board\r
+            dcbSerialParams.BaudRate=CBR_57600;\r
+            dcbSerialParams.ByteSize=8;\r
+            dcbSerialParams.StopBits=ONESTOPBIT;\r
+            dcbSerialParams.Parity=NOPARITY;\r
+\r
+             //Set the parameters and check for their proper application\r
+             if(!SetCommState(_hSerial, &dcbSerialParams))\r
+                cerr << "ERROR: Could not set Serial Port parameters" << endl;\r
+             else\r
+             {\r
+                 //If everything went fine we're connected\r
+                 _connected = true;\r
+                 //We wait 2s as the arduino board will be reseting\r
+                                Sleep(2000);\r
+                 //SDL_Delay(ARDUINO_WAIT_TIME);\r
+             }\r
+        }\r
+    }\r
+}\r
+\r
+SerialWindows::~SerialWindows()\r
+{\r
+    //Check if we are connected before trying to disconnect\r
+    if(_connected)\r
+    {\r
+        //We're no longer connected\r
+        _connected = false;\r
+        //Close the serial handler\r
+        CloseHandle(_hSerial);\r
+    }\r
+}\r
+\r
+int SerialWindows::ReadData(void *buffer, unsigned int nbChar)\r
+{\r
+    //Number of bytes we'll have read\r
+    DWORD bytesRead = 0;\r
+    //Number of bytes we'll really ask to read\r
+    unsigned int toRead = 0;\r
+\r
+    //Use the ClearCommError function to get status info on the Serial port\r
+    ClearCommError(_hSerial, &_errors, &_status);\r
+\r
+    //Check if there is something to read\r
+    if(_status.cbInQue > 0)\r
+    {\r
+        //If there is we check if there is enough data to read the required number\r
+        //of characters, if not we'll read only the available characters to prevent\r
+        //locking of the application.\r
+        if(_status.cbInQue > nbChar)\r
+                       toRead = nbChar;\r
+        else\r
+                       toRead = _status.cbInQue;\r
+\r
+        //Try to read the require number of chars, and return the number of read bytes on success\r
+        if(ReadFile(_hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)\r
+            return bytesRead;\r
+    }\r
+\r
+    //If nothing has been read, or that an error was detected return -1\r
+    return -1;\r
+}\r
+\r
+\r
+bool SerialWindows::WriteData(void *buffer, unsigned int nbChar)\r
+{\r
+    DWORD bytesSend;\r
+\r
+    //Try to write the buffer on the Serial port\r
+    if(!WriteFile(_hSerial, buffer, nbChar, &bytesSend, 0))\r
+    {\r
+        //In case it don't work get comm error and return false\r
+        ClearCommError(_hSerial, &_errors, &_status);\r
+\r
+        return false;\r
+    }\r
+    else\r
+       {\r
+        ClearCommError(_hSerial, &_errors, &_status);\r
+/*             if(!FlushFileBuffers(_hSerial))\r
+                       cout << "ERROR while flushing" << endl;*/\r
+/*             stringstream s;
+               s << bytesSend << " SENT" << endl;
+               OutputDebugString(s.str().c_str());*/
+        return true;\r
+       }\r
+}\r
diff --git a/TactonPlayer/SerialWindows.hpp b/TactonPlayer/SerialWindows.hpp
new file mode 100644 (file)
index 0000000..28eb1af
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _SERIALWINDOWS_\r
+#define _SERIALWINDOWS_\r
+\r
+#include "Serial.hpp"\r
+\r
+#include <windows.h>\r
+\r
+class SerialWindows : public Serial\r
+{\r
+    public:\r
+        //Initialize Serial communication with the given COM port\r
+        SerialWindows(char *portName);\r
+        //Close the connection\r
+        //NOTA: for some reason you can't connect again before exiting\r
+        //the program and running it again\r
+        ~SerialWindows();\r
+        //Read data in a buffer, if nbChar is greater than the\r
+        //maximum number of bytes available, it will return only the\r
+        //bytes available. The function return -1 when nothing could\r
+        //be read, the number of bytes actually read.\r
+        int ReadData(void *buffer, unsigned int nbChar);\r
+        //Writes data from a buffer through the Serial connection\r
+        //return true on success.\r
+        bool WriteData(void *buffer, unsigned int nbChar);\r
+\r
+\r
+    private:\r
+        //Serial comm handler\r
+        HANDLE _hSerial;\r
+        //Get various information about the connection\r
+        COMSTAT _status;\r
+        //Keep track of last error\r
+        DWORD _errors;\r
+};\r
+#endif\r
diff --git a/TactonPlayer/Tacton.cpp b/TactonPlayer/Tacton.cpp
new file mode 100644 (file)
index 0000000..3e38661
--- /dev/null
@@ -0,0 +1,109 @@
+#include "Tacton.hpp"\r
+\r
+#include <cstring>\r
+#include <cstdlib>\r
+\r
+Tacton::Tacton(unsigned int nbframes, unsigned char *desc)\r
+:_nbframes(nbframes), _patterns(new unsigned char[nbframes]), _durations(new unsigned int[nbframes]), _frequencies(new unsigned int[nbframes]), _amplitudes(new unsigned char[nbframes])\r
+{\r
+       for(unsigned int i = 0 ; i < nbframes ; i++)\r
+       {\r
+               _patterns[i] = desc[6*i];\r
+               _durations[i] = (((unsigned int)(desc[6*i+1])) << 8) | ((unsigned int)(desc[6*i+2]));\r
+               _frequencies[i] = (((unsigned int)(desc[6*i+3])) << 8) | ((unsigned int)(desc[6*i+4]));\r
+               _amplitudes[i] = desc[6*i+5];\r
+       }\r
+}\r
+\r
+Tacton::Tacton(char *desc)\r
+{\r
+       char *buffer = strdup(desc);\r
+\r
+       //read the number of frames\r
+       char *token = strtok(buffer, "; ,");\r
+       if (token == NULL)\r
+               throw "Invalid description";\r
+       _nbframes = atoi(token);\r
+\r
+        _patterns = new unsigned char[_nbframes];\r
+        _durations = new unsigned int[_nbframes];\r
+        _frequencies = new unsigned int[_nbframes];\r
+        _amplitudes = new unsigned char[_nbframes];\r
+\r
+       for (unsigned int i = 0 ; i < _nbframes ; i++)\r
+       {\r
+               //read the pattern\r
+               if ((token = strtok(NULL, "; ,")) == NULL || strlen(token) != 4)\r
+                       throw "Invalid description";\r
+               unsigned char t1 = token[0] == '1';\r
+               unsigned char t2 = token[1] == '1';\r
+               unsigned char t3 = token[2] == '1';\r
+               unsigned char t4 = token[3] == '1';\r
+               _patterns[i] = (t1 << 3) | (t2 << 2) | (t3 << 1) | t4;\r
+\r
+               //read the duration\r
+               if ((token = strtok(NULL, "; ,")) == NULL)\r
+                       throw "Invalid description";\r
+               _durations[i] = atoi(token);\r
+\r
+               //read the frequency\r
+               if ((token = strtok(NULL, "; ,")) == NULL)\r
+                       throw "Invalid description";\r
+               _frequencies[i] = atoi(token);\r
+\r
+               //read the amplitude\r
+               if ((token = strtok(NULL, "; ,")) == NULL)\r
+                       throw "Invalid description";\r
+               _amplitudes[i] = atoi(token);\r
+       }\r
+\r
+       free(buffer);\r
+}\r
+\r
+Tacton::Tacton(unsigned int nbframes, unsigned char *patterns, unsigned int *durations, unsigned int *frequencies, unsigned char *amplitudes)\r
+:_nbframes(nbframes), _patterns(new unsigned char[nbframes]), _durations(new unsigned int[nbframes]), _frequencies(new unsigned int[nbframes]), _amplitudes(new unsigned char[nbframes])\r
+{\r
+       memcpy(_patterns, patterns, nbframes * sizeof(unsigned char));\r
+       memcpy(_durations, durations, nbframes * sizeof(unsigned int));\r
+       memcpy(_frequencies, frequencies, nbframes * sizeof(unsigned int));\r
+       memcpy(_amplitudes, amplitudes, nbframes * sizeof(unsigned char));\r
+}\r
+\r
+Tacton::Tacton(unsigned char pattern, unsigned int duration, unsigned int frequency, unsigned char amplitude)\r
+:_nbframes(1), _patterns(new unsigned char[1]), _durations(new unsigned int[1]), _frequencies(new unsigned int[1]), _amplitudes(new unsigned char[1])\r
+{\r
+       _patterns[0] = pattern;\r
+       _durations[0] = duration;\r
+       _frequencies[0] = frequency;\r
+       _amplitudes[0] = amplitude;\r
+}\r
+\r
+Tacton::~Tacton()\r
+{\r
+       delete []_patterns;\r
+       delete []_durations;\r
+       delete []_frequencies;\r
+       delete []_amplitudes;\r
+}\r
+\r
+const unsigned int Tacton::getNbFrames() const\r
+{\r
+       return _nbframes;\r
+}\r
+\r
+void *Tacton::rawCode() const\r
+{\r
+       unsigned char *res = new unsigned char[_nbframes * 6];\r
+       for (unsigned int i = 0 ; i < _nbframes ; i++)\r
+       {\r
+               res[6*i] = _patterns[i];\r
+               res[6*i+1] = (_durations[i] & 0xff00) >> 8;\r
+               res[6*i+2] = _durations[i] & 0xff;\r
+               res[6*i+3] = (_frequencies[i] & 0xff00) >> 8;\r
+               res[6*i+4] = _frequencies[i] & 0xff;\r
+               res[6*i+5] = _amplitudes[i];\r
+       }\r
+       return res;\r
+}\r
+\r
+  
\ No newline at end of file
diff --git a/TactonPlayer/Tacton.hpp b/TactonPlayer/Tacton.hpp
new file mode 100644 (file)
index 0000000..b5162c4
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _TACTON_\r
+#define _TACTON_\r
+\r
+class Tacton \r
+{\r
+       public:\r
+               //creates a tacton using the raw data format\r
+               //6 bytes per frame : \r
+               //1 for the pattern\r
+               //2 for the duration\r
+               //2 for the frequency\r
+               //1 for the amplitude\r
+               __declspec(dllexport) Tacton(unsigned int nbframes, unsigned char *desc);\r
+               //creates a tacton using the CSV format\r
+               //1 field for the number of frames, then 4 fields per frame \r
+               //1 for the pattern\r
+               //1 for the duration\r
+               //1 for the frequency\r
+               //1 for the amplitude\r
+               __declspec(dllexport) Tacton(char *desc);\r
+               __declspec(dllexport) Tacton(unsigned int nbframes, unsigned char *patterns, unsigned int *durations, unsigned int *frequencies, unsigned char *amplitudes);\r
+               //create a simple vibration\r
+               __declspec(dllexport) Tacton(unsigned char pattern, unsigned int duration, unsigned int frequency, unsigned char amplitude);\r
+               __declspec(dllexport) ~Tacton();\r
+               \r
+               //returns the number of frames\r
+               __declspec(dllexport) const unsigned int getNbFrames() const;\r
+\r
+               //returns the raw code (useful to send to the serial port)\r
+               __declspec(dllexport) void *rawCode() const;\r
+\r
+       private:\r
+               unsigned int _nbframes;\r
+               unsigned char *_patterns;\r
+               unsigned int *_durations;\r
+               unsigned int *_frequencies;\r
+               unsigned char *_amplitudes;\r
+};\r
+\r
+#endif\r
diff --git a/TactonPlayer/TactonPlayer.cpp b/TactonPlayer/TactonPlayer.cpp
new file mode 100644 (file)
index 0000000..acebf80
--- /dev/null
@@ -0,0 +1,97 @@
+#include "TactonPlayer.hpp"\r
+\r
+#include "SerialWindows.hpp"\r
+\r
+#include <stdexcept>\r
+\r
+TactonPlayer::TactonPlayer(char *port)\r
+:_comport(new SerialWindows(port))\r
+{\r
+}\r
+\r
+TactonPlayer::~TactonPlayer()\r
+{\r
+       delete _comport;\r
+}\r
+\r
+void TactonPlayer::start()\r
+{\r
+       _comport->WriteData("S", 1);\r
+}\r
+\r
+void TactonPlayer::stop()\r
+{\r
+       _comport->WriteData("Q", 1);\r
+}\r
+\r
+void TactonPlayer::regist(const Tacton &t)\r
+{\r
+       unsigned int nbframes = t.getNbFrames();\r
+       unsigned char *buffer = new unsigned char[3 + 6 * nbframes];\r
+       buffer[0] = 'N';\r
+       buffer[1] = (nbframes & 0xff00) >> 8;\r
+       buffer[2] = nbframes & 0xff;\r
+       memcpy(buffer + 3, t.rawCode(), 6 * nbframes);\r
+       _comport->WriteData(buffer, 3 + 6 * nbframes);\r
+       delete []buffer;\r
+}\r
+\r
+unsigned int TactonPlayer::registFile(char *filename)\r
+{\r
+       unsigned int nb = 0;\r
+\r
+       //load icons\r
+       FILE *f = fopen(filename, "r");\r
+       if (!f)\r
+               throw "Invalid file";\r
+\r
+       char buffer[256];\r
+       while ((fgets(buffer, 256, f)) != NULL)\r
+       {\r
+               while((buffer[strlen(buffer) - 1] == '\r') || (buffer[strlen(buffer) - 1] == '\n'))\r
+                       buffer[strlen(buffer) - 1] = '\0';\r
+               try\r
+               {\r
+                       Tacton t(buffer);\r
+                       regist(t);\r
+                       nb++;\r
+               }\r
+               catch(...)\r
+               {\r
+               }\r
+       }\r
+       fclose(f);\r
+       return nb;\r
+}\r
+\r
+void TactonPlayer::play(unsigned char index)\r
+{\r
+       unsigned char buffer[2];\r
+       buffer[0] = 'T';\r
+       buffer[1] = index;\r
+       _comport->WriteData(buffer, 2);\r
+}\r
+\r
+void TactonPlayer::play(const Tacton &t)\r
+{\r
+       unsigned int nbframes = t.getNbFrames();\r
+       unsigned char *buffer = new unsigned char[3 + 6 * nbframes];\r
+       buffer[0] = 'V';\r
+       buffer[1] = (nbframes & 0xff00) >> 8;\r
+       buffer[2] = nbframes & 0xff;\r
+       memcpy(buffer + 3, t.rawCode(), 6 * nbframes);\r
+       _comport->WriteData(buffer, 3 + 6 * nbframes);\r
+       delete []buffer;\r
+}\r
+\r
+void TactonPlayer::schedule(unsigned char index, unsigned long timestamp)\r
+{\r
+       unsigned char buffer[6];\r
+       buffer[0] = 'P';\r
+       buffer[1] = index;\r
+       buffer[2] = (unsigned char)((timestamp & 0xff000000) >> 24);\r
+       buffer[3] = (unsigned char)((timestamp & 0x00ff0000) >> 16);\r
+       buffer[4] = (unsigned char)((timestamp & 0x0000ff00) >> 8);\r
+       buffer[5] = (unsigned char)(timestamp & 0x000000ff);\r
+       _comport->WriteData(buffer, 6);\r
+}
\ No newline at end of file
diff --git a/TactonPlayer/TactonPlayer.hpp b/TactonPlayer/TactonPlayer.hpp
new file mode 100644 (file)
index 0000000..48296a9
--- /dev/null
@@ -0,0 +1,30 @@
+#include "Tacton.hpp"\r
+\r
+#include "Serial.hpp"\r
+\r
+class TactonPlayer\r
+{\r
+       public:\r
+                       __declspec(dllexport) TactonPlayer(char *port = "COM5");\r
+                       __declspec(dllexport) ~TactonPlayer();\r
+\r
+                       //set the timestamp to 0, and watch for scheduled tactons\r
+                       void __declspec(dllexport) start();\r
+                       //stop watching scheduled tactons, and erase registered tactons\r
+                       void __declspec(dllexport) stop();\r
+\r
+                       //register a tacton\r
+                       void __declspec(dllexport) regist(const Tacton &t);\r
+                       //register a list of tactons in a file, returns the number of tactons loaded\r
+                       unsigned int __declspec(dllexport) registFile(char *filename);\r
+\r
+                       //play a registered tacton\r
+                       void __declspec(dllexport) play(unsigned char index);\r
+                       //play a specified tacton\r
+                       void __declspec(dllexport) play(const Tacton &t);\r
+                       //schedule the play of a registered tacton\r
+                       void __declspec(dllexport) schedule(unsigned char index, unsigned long timestamp);\r
+\r
+private:\r
+               Serial *_comport;\r
+};\r
diff --git a/TactonPlayer/TactonPlayer.vcxproj b/TactonPlayer/TactonPlayer.vcxproj
new file mode 100644 (file)
index 0000000..aa962eb
--- /dev/null
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{6D5C62C0-562D-4B2A-9AAC-806372810CBF}</ProjectGuid>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <RootNamespace>TactonPlayer</RootNamespace>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TACTONPLAYER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Windows</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <PrecompiledHeader>\r
+      </PrecompiledHeader>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TACTONPLAYER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <DisableSpecificWarnings>4996</DisableSpecificWarnings>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Windows</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="Serial.hpp" />\r
+    <ClInclude Include="SerialWindows.hpp" />\r
+    <ClInclude Include="Tacton.hpp" />\r
+    <ClInclude Include="TactonPlayer.hpp" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="Serial.cpp" />\r
+    <ClCompile Include="SerialWindows.cpp" />\r
+    <ClCompile Include="Tacton.cpp" />\r
+    <ClCompile Include="TactonPlayer.cpp" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/TactonPlayer/TactonPlayer.vcxproj.filters b/TactonPlayer/TactonPlayer.vcxproj.filters
new file mode 100644 (file)
index 0000000..8f2e3f7
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="SerialWindows.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Serial.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Tacton.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="TactonPlayer.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="Tacton.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Serial.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="SerialWindows.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="TactonPlayer.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file