aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore32
-rw-r--r--Makefile29
-rw-r--r--README.md12
-rw-r--r--calibrate.c6
-rw-r--r--calibrate_client.c5
-rw-r--r--data_recorder.c6
-rw-r--r--include/libsurvive/survive.h18
-rw-r--r--redist/CNFGFunctions.c (renamed from redist/DrawFunctions.c)11
-rw-r--r--redist/CNFGFunctions.h (renamed from redist/DrawFunctions.h)6
-rw-r--r--redist/CNFGNullDriver.c74
-rw-r--r--redist/CNFGRasterizer.h247
-rw-r--r--redist/CNFGWinDriver.c (renamed from redist/WinDriver.c)234
-rw-r--r--redist/CNFGXDriver.c (renamed from redist/XDriver.c)16
-rw-r--r--redist/hid-osx.c1111
-rw-r--r--redist/hid-windows.c (renamed from windows/hid.c)22
-rw-r--r--redist/hidapi.h (renamed from windows/hidapi.h)0
-rw-r--r--redist/json_helpers.c15
-rw-r--r--redist/json_helpers.h2
-rw-r--r--redist/linmath.c16
-rw-r--r--redist/os_generic.c1
-rw-r--r--redist/symbol_enumerator.c10
-rw-r--r--src/poser_charlesslow.c8
-rw-r--r--src/poser_daveortho.c2
-rwxr-xr-xsrc/survive.c8
-rwxr-xr-xsrc/survive_cal.c6
-rw-r--r--src/survive_config.c16
-rw-r--r--src/survive_config.h4
-rw-r--r--src/survive_data.c3
-rw-r--r--src/survive_driverman.c2
-rwxr-xr-xsrc/survive_vive.c9
-rwxr-xr-xtest.c27
-rw-r--r--winbuild/build_tcc.bat (renamed from windows/build_tcc.bat)4
-rw-r--r--winbuild/calibrate/calibrate.vcxproj26
-rw-r--r--winbuild/libsurvive/libsurvive.vcxproj38
-rw-r--r--winbuild/libsurvive/libsurvive.vcxproj.filters26
-rw-r--r--winbuild/tcc_stubs.c (renamed from windows/tcc_stubs.c)0
-rw-r--r--windows/custom_msvcrt.def1400
37 files changed, 1825 insertions, 1627 deletions
diff --git a/.gitignore b/.gitignore
index a7db3ac..4c22fa3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,18 +1,20 @@
*.o
lib
test
-windows/calibrate.exe
-windows/calinfo/1.json.gz
-windows/calibrate.def
-windows/calinfo/3.json.gz
-windows/calinfo/WM1_points.csv
-windows/calinfo/HMD_normals.csv
-windows/calinfo/WM0_points.csv
-windows/calinfo/WM1_normals.csv
-windows/calinfo/HMD_points.csv
-windows/calinfo/WM0_normals.csv
-windows/calinfo/2.json.gz
-windows/calinfo - Copy/WM1_points.csv
-windows/udev[USB_DEV_LIGHTHOUSE]
-windows/udev[USB_DEV_LIGHTHOUSE]
-windows/config.json
+winbuild/calibrate.exe
+winbuild/calinfo/*
+winbuild/calibrate.def
+winbuild/udev[USB_DEV_LIGHTHOUSE]
+winbuild/config.json
+winbuild/x64/*
+winbuild/calibrate/calinfo/*
+winbuild/calibrate/config.json
+winbuild/calibrate/x64/*
+winbuild/libsurvive/x64/*
+winbuild/.vs/*
+*.user
+*.ipch
+winbuild/.vs/libsurvive/v15/.suo
+*.tlog
+winbuild/calibrate.exe
+winbuild/calibrate.def
diff --git a/Makefile b/Makefile
index 525f7c5..a642877 100644
--- a/Makefile
+++ b/Makefile
@@ -2,11 +2,31 @@ all : lib data_recorder test calibrate calibrate_client
CC:=gcc
+
CFLAGS:=-Iinclude/libsurvive -I. -fPIC -g -O3 -Iredist -flto -DUSE_DOUBLE -std=gnu99 -rdynamic
-LDFLAGS:=-lpthread -lusb-1.0 -lz -lX11 -lm -flto -g
+LDFLAGS:=-L/usr/local/lib -lpthread -lusb-1.0 -lz -lm -flto -g
+
+#----------
+# Platform specific changes to CFLAGS/LDFLAGS
+#----------
+UNAME=$(shell uname)
+
+# Mac OSX
+ifeq ($(UNAME), Darwin)
+DRAWFUNCTIONS=redist/CNFGFunctions.c redist/CNFGNullDriver.c
+GRAPHICS_LOFI:=redist/CNFGFunctions.o redist/CNFGNullDriver.o
+
+# Linux / FreeBSD
+else
+LDFLAGS:=$(LDFLAGS) -lX11
+DRAWFUNCTIONS=redist/CNFGFunctions.c redist/CNFGXDriver.c
+GRAPHICS_LOFI:=redist/CNFGFunctions.o redist/CNFGXDriver.o
+
+endif
+
POSERS:=src/poser_dummy.o src/poser_daveortho.o src/poser_charlesslow.o
-REDISTS:=redist/json_helpers.o redist/linmath.o redist/jsmn.o
+REDISTS:=redist/json_helpers.o redist/linmath.o redist/jsmn.o redist/os_generic.o
LIBSURVIVE_CORE:=src/survive.o src/survive_usb.o src/survive_data.o src/survive_process.o src/ootx_decoder.o src/survive_driverman.o src/survive_vive.o src/survive_config.o src/survive_cal.o
LIBSURVIVE_CORE:=$(LIBSURVIVE_CORE)
LIBSURVIVE_O:=$(POSERS) $(REDISTS) $(LIBSURVIVE_CORE)
@@ -21,7 +41,6 @@ LIBSURVIVE_C:=$(LIBSURVIVE_O:.o=.c)
# -DRUNTIME_SYMNUM = Don't assume __attribute__((constructor)) works. Instead comb for anything starting with REGISTER.
-GRAPHICS_LOFI:=redist/DrawFunctions.o redist/XDriver.o
# unused: redist/crc32.c
@@ -38,7 +57,7 @@ calibrate_client : calibrate_client.c ./lib/libsurvive.so redist/os_generic.c $
$(CC) -o $@ $^ $(LDFLAGS) $(CFLAGS)
## Still not working!!! Don't use.
-static_calibrate : calibrate.c redist/os_generic.c redist/XDriver.c redist/DrawFunctions.c $(LIBSURVIVE_C)
+static_calibrate : calibrate.c redist/os_generic.c $(DRAWFUNCTIONS) $(LIBSURVIVE_C)
tcc -o $@ $^ $(CFLAGS) $(LDFLAGS) -DTCC
lib:
@@ -49,7 +68,7 @@ lib/libsurvive.so : $(LIBSURVIVE_O)
calibrate_tcc : $(LIBSURVIVE_C)
- tcc -DRUNTIME_SYMNUM $(CFLAGS) -o $@ $^ $(LDFLAGS) calibrate.c redist/XDriver.c redist/os_generic.c redist/DrawFunctions.c redist/symbol_enumerator.c
+ tcc -DRUNTIME_SYMNUM $(CFLAGS) -o $@ $^ $(LDFLAGS) calibrate.c redist/os_generic.c $(DRAWFUNCTIONS) redist/symbol_enumerator.c
clean :
rm -rf *.o src/*.o *~ src/*~ test data_recorder lib/libsurvive.so redist/*.o redist/*~
diff --git a/README.md b/README.md
index 6e097f8..45ac38f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# libsurvive
-**WARNING PROJECT NOT YET IN EXPERIMENTAL PHASE**
+**WARNING PROJECT IN EXPERIMENTAL PHASE**
Discord: https://discordapp.com/invite/7QbCAGS
@@ -40,8 +40,7 @@ I say "high-performance" really this project is based tightly off of OSVR-Vive-L
2. Put it under an open-source instead of a force-source license. (GPL to MIT/X11)
3. Write it in C.
4. Avoid extra layers where convenient.
-5. (long shot) Make the vive vivable for use with Intel Integrated Graphics systems.
-
+5. (long shot) Make the vive vivable for use with Intel Integrated Graphics systems. [It works with HD4000 using DisplayPort. See "Intel Integrated Graphics" section below.]
Will ~~I~~ we succeed? Probably not.
@@ -50,7 +49,7 @@ Definitely going to try!
## External dependencies
-* libUSB
+* libUSB (hidapi ???)
* pthread
* libX11 (where applicable)
* zlib (may use puff.c if needed)
@@ -71,7 +70,10 @@ It is written in some fairly stout "layers" which are basically just function ca
I may or may not read data from the Vive regarding configuration. If I do, it would be added to the survive_usb.c
+## Intel Integrated Graphics
+The limiting factor for Vive viability on a given computer is the maximum available pixel clock frequency, and frequency limitations of the HDMI port, and HDMI and DisplayPort video cables. DisplayPort can support higher frequencies than HDMI, on Ivy Bridge HD4000 graphics. In fact, the vive works with HD4000 graphics using DisplayPort, with native EDID resolution (2160x1200@90Hz).
+To support the Vive on HDMI, you either need a newer version of HDMI, or you need to define a custom resolution that respects pixel clock and video port limits, and is also accepted and displayed by the Vive. So far, we have not had success using custom resolutions on linux or on Windows. Windows imposes additional limitations in the form of restriction of WHQL certified drivers forbidden from using custom display resolutions (only allowing those defined by EDID in the monitor). Intel has released uncertified beta drivers for Haswell and newer processors, which should be able to support custom resolutions for the Vive (untested at this time).
-
+but HDMI will require non-certified drivers to allow custom resolutions (due to WHQL restrictions). Haswell (Iris) graphics and later can use the new intel beta drivers to allow custom resolutions.]
diff --git a/calibrate.c b/calibrate.c
index 9633a77..726a8cc 100644
--- a/calibrate.c
+++ b/calibrate.c
@@ -7,7 +7,7 @@
#include <string.h>
#include <os_generic.h>
#include "src/survive_cal.h"
-#include <DrawFunctions.h>
+#include <CNFGFunctions.h>
#include "src/survive_config.h"
@@ -40,6 +40,10 @@ void HandleMotion( int x, int y, int mask )
{
}
+void HandleDestroy()
+{
+}
+
//int bufferpts[32*2*3][2];
int bufferpts[32*2*3][2];
diff --git a/calibrate_client.c b/calibrate_client.c
index f28520b..1a2ee41 100644
--- a/calibrate_client.c
+++ b/calibrate_client.c
@@ -8,7 +8,7 @@
#include <string.h>
#include <os_generic.h>
#include "src/survive_cal.h"
-#include <DrawFunctions.h>
+#include <CNFGFunctions.h>
#include "src/survive_config.h"
@@ -35,6 +35,9 @@ void HandleButton( int x, int y, int button, int bDown )
void HandleMotion( int x, int y, int mask )
{
}
+void HandleDestroy()
+{
+}
int bufferpts[32*2*3];
char buffermts[32*128*3];
diff --git a/data_recorder.c b/data_recorder.c
index 206c6c3..46f3427 100644
--- a/data_recorder.c
+++ b/data_recorder.c
@@ -9,7 +9,7 @@
#include <survive.h>
#include <string.h>
#include <os_generic.h>
-#include <DrawFunctions.h>
+#include <CNFGFunctions.h>
struct SurviveContext * ctx;
@@ -35,6 +35,10 @@ void HandleMotion( int x, int y, int mask )
{
}
+void HandleDestroy()
+{
+}
+
int bufferpts[32*2*3];
char buffermts[32*128*3];
int buffertimeto[32*3];
diff --git a/include/libsurvive/survive.h b/include/libsurvive/survive.h
index e3e167a..e04586c 100644
--- a/include/libsurvive/survive.h
+++ b/include/libsurvive/survive.h
@@ -136,10 +136,12 @@ void survive_default_angle_process( SurviveObject * so, int sensor_id, int acode
////////////////////// Survive Drivers ////////////////////////////
-void RegisterDriver( const char * name, void * data );
+void RegisterDriver(const char * name, void * data);
-#ifdef _WIN32
-#define REGISTER_LINKTIME( func )
+#ifdef _MSC_VER
+#define REGISTER_LINKTIME( func ) \
+ __pragma(comment(linker,"/export:REGISTER"#func));\
+ void REGISTER##func() { RegisterDriver(#func, &func); }
#else
#define REGISTER_LINKTIME( func ) \
void __attribute__((constructor)) REGISTER##func() { RegisterDriver(#func, &func); }
@@ -155,22 +157,14 @@ void survive_add_driver( SurviveContext * ctx, void * payload, DeviceDriverCb po
//For lightcap, etc. Don't change this structure at all. Regular vive is dependent on it being exactly as-is.
//When you write drivers, you can use this to send survive lightcap data.
-#ifdef _WIN32
-#pragma pack(push,1)
-#endif
typedef struct
{
uint8_t sensor_id;
uint16_t length;
uint32_t timestamp;
}
-#ifdef __linux__
-__attribute__((packed))
-#endif
LightcapElement;
-#ifdef _WIN32
-#pragma pack(pop)
-#endif
+
//This is the disambiguator function, for taking light timing and figuring out place-in-sweep for a given photodiode.
void handle_lightcap( SurviveObject * so, LightcapElement * le );
diff --git a/redist/DrawFunctions.c b/redist/CNFGFunctions.c
index f4f27d2..947456f 100644
--- a/redist/DrawFunctions.c
+++ b/redist/CNFGFunctions.c
@@ -21,14 +21,13 @@ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "DrawFunctions.h"
+#include "CNFGFunctions.h"
#include <stdio.h>
int CNFGPenX, CNFGPenY;
uint32_t CNFGBGColor;
uint32_t CNFGLastColor;
uint32_t CNFGDialogColor; //background for boxes
-
const unsigned short FontCharMap[256] = {
65535, 0, 10, 20, 32, 44, 56, 68, 70, 65535, 65535, 80, 92, 65535, 104, 114,
126, 132, 138, 148, 156, 166, 180, 188, 200, 206, 212, 218, 224, 228, 238, 244,
@@ -68,7 +67,7 @@ const unsigned char FontCharData[1902] = {
0x23, 0x14, 0x14, 0x03, 0x10, 0x94, 0x00, 0x01, 0x23, 0x24, 0x04, 0x03, 0x03, 0x21, 0x21, 0xa0,
0x21, 0x10, 0x10, 0x01, 0x01, 0x12, 0x12, 0x03, 0x03, 0x14, 0x14, 0x23, 0x02, 0xa4, 0x10, 0x91,
0x10, 0x01, 0x01, 0x03, 0x03, 0x94, 0x10, 0x21, 0x21, 0x23, 0x23, 0x94, 0x01, 0x23, 0x11, 0x13,
- 0x21, 0x03, 0x02, 0xa2, 0x02, 0x22, 0x11, 0x93, 0x31, 0xc0, 0x03, 0xa1, 0x00, 0x20, 0x20, 0x24,
+ 0x21, 0x03, 0x02, 0xa2, 0x02, 0x22, 0x11, 0x93, 0x04, 0x93, 0x03, 0xa1, 0x00, 0x20, 0x20, 0x24,
0x24, 0x04, 0x04, 0x00, 0x12, 0x92, 0x01, 0x10, 0x10, 0x14, 0x04, 0xa4, 0x01, 0x10, 0x10, 0x21,
0x21, 0x22, 0x22, 0x04, 0x04, 0xa4, 0x00, 0x20, 0x20, 0x24, 0x24, 0x04, 0x12, 0xa2, 0x00, 0x02,
0x02, 0x22, 0x20, 0xa4, 0x20, 0x00, 0x00, 0x02, 0x02, 0x22, 0x22, 0x24, 0x24, 0x84, 0x20, 0x02,
@@ -208,11 +207,7 @@ void CNFGDrawText( const char * text, int scale )
int x2 = (int)((((*(lmap+1)) & 0x70)>>4)*scale + iox);
int y2 = (int)(((*(lmap+1)) & 0x0f)*scale + ioy);
lmap++;
- if(x1 == x2 && y1 == y2){
- CNFGTackPixel( x1, y1 );
- } else {
- CNFGTackSegment( x1, y1, x2, y2 );
- }
+ CNFGTackSegment( x1, y1, x2, y2 );
bQuit = *lmap & 0x80;
lmap++;
} while( !bQuit );
diff --git a/redist/DrawFunctions.h b/redist/CNFGFunctions.h
index 542fcf9..9ecb1bd 100644
--- a/redist/DrawFunctions.h
+++ b/redist/CNFGFunctions.h
@@ -34,7 +34,6 @@ void CNFGClearFrame();
void CNFGSwapBuffers();
void CNFGGetDimensions( short * x, short * y );
-void CNFGTearDown();
void CNFGSetup( const char * WindowName, int w, int h );
void CNFGSetupFullscreen( const char * WindowName, int screen_number );
void CNFGHandleInput();
@@ -44,6 +43,11 @@ void CNFGHandleInput();
void HandleKey( int keycode, int bDown );
void HandleButton( int x, int y, int button, int bDown );
void HandleMotion( int x, int y, int mask );
+void HandleDestroy();
+
+
+//Internal function for resizing rasterizer for rasterizer-mode.
+void CNFGInternalResize( short x, short y ); //don't call this.
#ifdef __cplusplus
diff --git a/redist/CNFGNullDriver.c b/redist/CNFGNullDriver.c
new file mode 100644
index 0000000..34346cc
--- /dev/null
+++ b/redist/CNFGNullDriver.c
@@ -0,0 +1,74 @@
+//Copyright (c) 2017 <>< Charles Lohr - Under the MIT/x11 or NewBSD License you choose.
+
+#include "DrawFunctions.h"
+
+static int w, h;
+void CNFGGetDimensions( short * x, short * y )
+{
+ *x = w;
+ *y = h;
+}
+
+static void InternalLinkScreenAndGo( const char * WindowName )
+{
+}
+
+void CNFGSetupFullscreen( const char * WindowName, int screen_no )
+{
+ CNFGSetup( WindowName, 640, 480 );
+}
+
+
+void CNFGTearDown()
+{
+}
+
+void CNFGSetup( const char * WindowName, int sw, int sh )
+{
+ w = sw;
+ h = sh;
+}
+
+void CNFGHandleInput()
+{
+}
+
+
+void CNFGUpdateScreenWithBitmap( unsigned long * data, int w, int h )
+{
+}
+
+
+#ifndef RASTERIZER
+
+
+uint32_t CNFGColor( uint32_t RGB )
+{
+}
+
+void CNFGClearFrame()
+{
+}
+
+void CNFGSwapBuffers()
+{
+}
+
+void CNFGTackSegment( short x1, short y1, short x2, short y2 )
+{
+}
+
+void CNFGTackPixel( short x1, short y1 )
+{
+}
+
+void CNFGTackRectangle( short x1, short y1, short x2, short y2 )
+{
+}
+
+void CNFGTackPoly( RDPoint * points, int verts )
+{
+}
+
+#endif
+
diff --git a/redist/CNFGRasterizer.h b/redist/CNFGRasterizer.h
new file mode 100644
index 0000000..1b8e2dd
--- /dev/null
+++ b/redist/CNFGRasterizer.h
@@ -0,0 +1,247 @@
+//Don't call this file yourself. It is intended to be included in any drivers which want to support the rasterizer plugin.
+
+#ifdef RASTERIZER
+#include "CNFGFunctions.h"
+#include <stdlib.h>
+#include <stdint.h>
+
+static uint32_t * buffer = 0;
+static short bufferx;
+static short buffery;
+
+
+void CNFGInternalResize( short x, short y )
+{
+ bufferx = x;
+ buffery = y;
+ if( buffer ) free( buffer );
+ buffer = malloc( bufferx * buffery * 4 );
+}
+
+static uint32_t SWAPS( uint32_t r )
+{
+ uint32_t ret = (r&0xFF)<<16;
+ r>>=8;
+ ret |= (r&0xff)<<8;
+ r>>=8;
+ ret |= r;
+ return ret;
+}
+
+uint32_t CNFGColor( uint32_t RGB )
+{
+ CNFGLastColor = SWAPS(RGB);
+ return CNFGLastColor;
+}
+
+void CNFGTackSegment( short x1, short y1, short x2, short y2 )
+{
+ short tx, ty;
+ float slope, lp;
+
+ short dx = x2 - x1;
+ short dy = y2 - y1;
+
+ if( !buffer ) return;
+
+ if( dx < 0 ) dx = -dx;
+ if( dy < 0 ) dy = -dy;
+
+ if( dx > dy )
+ {
+ short minx = (x1 < x2)?x1:x2;
+ short maxx = (x1 < x2)?x2:x1;
+ short miny = (x1 < x2)?y1:y2;
+ short maxy = (x1 < x2)?y2:y1;
+ float thisy = miny;
+ slope = (float)(maxy-miny) / (float)(maxx-minx);
+
+ for( tx = minx; tx <= maxx; tx++ )
+ {
+ ty = thisy;
+ if( tx < 0 || ty < 0 || ty >= buffery ) continue;
+ if( tx >= bufferx ) break;
+ buffer[ty * bufferx + tx] = CNFGLastColor;
+ thisy += slope;
+ }
+ }
+ else
+ {
+ short minx = (y1 < y2)?x1:x2;
+ short maxx = (y1 < y2)?x2:x1;
+ short miny = (y1 < y2)?y1:y2;
+ short maxy = (y1 < y2)?y2:y1;
+ float thisx = minx;
+ slope = (float)(maxx-minx) / (float)(maxy-miny);
+
+ for( ty = miny; ty <= maxy; ty++ )
+ {
+ tx = thisx;
+ if( ty < 0 || tx < 0 || tx >= bufferx ) continue;
+ if( ty >= buffery ) break;
+ buffer[ty * bufferx + tx] = CNFGLastColor;
+ thisx += slope;
+ }
+ }
+}
+void CNFGTackRectangle( short x1, short y1, short x2, short y2 )
+{
+ short minx = (x1<x2)?x1:x2;
+ short miny = (y1<y2)?y1:y2;
+ short maxx = (x1>=x2)?x1:x2;
+ short maxy = (y1>=y2)?y1:y2;
+
+ short x, y;
+
+ if( minx < 0 ) minx = 0;
+ if( miny < 0 ) miny = 0;
+ if( maxx >= bufferx ) maxx = bufferx-1;
+ if( maxy >= buffery ) maxy = buffery-1;
+
+ for( y = miny; y <= maxy; y++ )
+ {
+ uint32_t * bufferstart = &buffer[y * bufferx + minx];
+ for( x = minx; x <= maxx; x++ )
+ {
+ (*bufferstart++) = CNFGLastColor;
+ }
+ }
+}
+
+void CNFGTackPoly( RDPoint * points, int verts )
+{
+ short minx = 10000, miny = 10000;
+ short maxx =-10000, maxy =-10000;
+ short i, x, y;
+
+ //Just in case...
+ if( verts > 32767 ) return;
+
+ for( i = 0; i < verts; i++ )
+ {
+ RDPoint * p = &points[i];
+ if( p->x < minx ) minx = p->x;
+ if( p->y < miny ) miny = p->y;
+ if( p->x > maxx ) maxx = p->x;
+ if( p->y > maxy ) maxy = p->y;
+ }
+
+ if( miny < 0 ) miny = 0;
+ if( maxy >= buffery ) maxy = buffery-1;
+
+ for( y = miny; y <= maxy; y++ )
+ {
+ short startfillx = maxx;
+ short endfillx = minx;
+
+ //Figure out what line segments intersect this line.
+ for( i = 0; i < verts; i++ )
+ {
+ short pl = i + 1;
+ if( pl == verts ) pl = 0;
+
+ RDPoint ptop;
+ RDPoint pbot;
+
+ ptop.x = points[i].x;
+ ptop.y = points[i].y;
+ pbot.x = points[pl].x;
+ pbot.y = points[pl].y;
+//printf( "Poly: %d %d\n", pbot.y, ptop.y );
+
+ if( pbot.y < ptop.y )
+ {
+ RDPoint ptmp;
+ ptmp.x = pbot.x;
+ ptmp.y = pbot.y;
+ pbot.x = ptop.x;
+ pbot.y = ptop.y;
+ ptop.x = ptmp.x;
+ ptop.y = ptmp.y;
+ }
+
+ //Make sure this line segment is within our range.
+//printf( "PT: %d %d %d\n", y, ptop.y, pbot.y );
+ if( ptop.y <= y && pbot.y >= y )
+ {
+ short diffy = pbot.y - ptop.y;
+ uint32_t placey = (uint32_t)(y - ptop.y)<<16; //Scale by 16 so we can do integer math.
+ short diffx = pbot.x - ptop.x;
+ short isectx;
+
+ if( diffy == 0 )
+ {
+ if( pbot.x < ptop.x )
+ {
+ if( startfillx > pbot.x ) startfillx = pbot.x;
+ if( endfillx < ptop.x ) endfillx = ptop.x;
+ }
+ else
+ {
+ if( startfillx > ptop.x ) startfillx = ptop.x;
+ if( endfillx < pbot.x ) endfillx = pbot.x;
+ }
+ }
+ else
+ {
+ //Inner part is scaled by 65536, outer part must be scaled back.
+ isectx = (( (placey / diffy) * diffx + 32768 )>>16) + ptop.x;
+ if( isectx < startfillx ) startfillx = isectx;
+ if( isectx > endfillx ) endfillx = isectx;
+ }
+//printf( "R: %d %d %d\n", pbot.x, ptop.x, isectx );
+ }
+ }
+
+//printf( "%d %d %d\n", y, startfillx, endfillx );
+
+ if( endfillx >= bufferx ) endfillx = bufferx - 1;
+ if( endfillx >= bufferx ) endfillx = buffery - 1;
+ if( startfillx < 0 ) startfillx = 0;
+ if( startfillx < 0 ) startfillx = 0;
+
+ unsigned int * bufferstart = &buffer[y * bufferx + startfillx];
+ for( x = startfillx; x <= endfillx; x++ )
+ {
+ (*bufferstart++) = CNFGLastColor;
+ }
+ }
+//exit(1);
+}
+
+
+void CNFGClearFrame()
+{
+ int i, m;
+ uint32_t col = 0;
+ short x, y;
+ CNFGGetDimensions( &x, &y );
+ if( x != bufferx || y != buffery || !buffer )
+ {
+ bufferx = x;
+ buffery = y;
+ buffer = malloc( x * y * 8 );
+ }
+
+ m = x * y;
+ col = CNFGColor( CNFGBGColor );
+ for( i = 0; i < m; i++ )
+ {
+//printf( "Got: %d %p %d\n", m, buffer, i );
+ buffer[i] = col;
+ }
+}
+
+void CNFGTackPixel( short x, short y )
+{
+ if( x < 0 || y < 0 || x >= bufferx || y >= buffery ) return;
+ buffer[x+bufferx*y] = CNFGLastColor;
+}
+
+void CNFGSwapBuffers()
+{
+ CNFGUpdateScreenWithBitmap( (long unsigned int*)buffer, bufferx, buffery );
+}
+
+
+#endif
diff --git a/redist/WinDriver.c b/redist/CNFGWinDriver.c
index a6dd1e6..a029419 100644
--- a/redist/WinDriver.c
+++ b/redist/CNFGWinDriver.c
@@ -2,80 +2,54 @@
//Portion from: http://en.wikibooks.org/wiki/Windows_Programming/Window_Creation
-#include "DrawFunctions.h"
+#include "CNFGFunctions.h"
#include <windows.h>
#include <stdlib.h>
#include <malloc.h> //for alloca
+static HBITMAP lsBitmap;
static HINSTANCE lhInstance;
static HWND lsHWND;
-static HDC lsHDC;
-static HBITMAP lsBackBitmap;
static HDC lsWindowHDC;
-static HBRUSH lsHBR;
-static HPEN lsHPEN;
-static HBRUSH lsClearBrush;
-static unsigned int lsLastWidth;
-static unsigned int lsLastHeight;
+static HDC lsHDC;
-static void InternalHandleResize()
-{
- DeleteObject( lsBackBitmap );
- lsBackBitmap = CreateCompatibleBitmap( lsHDC, lsLastWidth, lsLastHeight );
- SelectObject( lsHDC, lsBackBitmap );
-}
+#ifdef RASTERIZER
+#include "CNFGRasterizer.h"
-uint32_t CNFGColor( uint32_t RGB )
+void InternalHandleResize()
{
- CNFGLastColor = RGB;
-
- DeleteObject( lsHBR );
- lsHBR = CreateSolidBrush( RGB );
- SelectObject( lsHDC, lsHBR );
+ if( lsBitmap ) DeleteObject( lsBitmap );
- DeleteObject( lsHPEN );
- lsHPEN = CreatePen( PS_SOLID, 0, RGB );
- SelectObject( lsHDC, lsHPEN );
-
- return RGB;
+ CNFGInternalResize( bufferx, buffery );
+ lsBitmap = CreateBitmap( bufferx, buffery, 1, 32, buffer );
+ SelectObject( lsHDC, lsBitmap );
}
+#else
+static int bufferx, buffery;
+static int bufferx, buffery;
+static void InternalHandleResize();
+#endif
-void CNFGTackSegment( short x1, short y1, short x2, short y2 )
-{
- POINT pt[2] = { {x1, y1}, {x2, y2} };
- Polyline( lsHDC, pt, 2 );
- SetPixel( lsHDC, x1, y1, CNFGLastColor );
- SetPixel( lsHDC, x2, y2, CNFGLastColor );
-}
-void CNFGTackRectangle( short x1, short y1, short x2, short y2 )
+void CNFGGetDimensions( short * x, short * y )
{
- RECT r;
- if( x1 < x2 ) { r.left = x1; r.right = x2; }
- else { r.left = x2; r.right = x1; }
- if( y1 < y2 ) { r.top = y1; r.bottom = y2; }
- else { r.top = y2; r.bottom = y1; }
- FillRect( lsHDC, &r, lsHBR );
+ *x = bufferx;
+ *y = buffery;
}
-void CNFGClearFrame()
-{
- RECT r = { 0, 0, lsLastWidth, lsLastHeight };
- DeleteObject( lsClearBrush );
- lsClearBrush = CreateSolidBrush( CNFGBGColor );
- SelectObject( lsHDC, lsClearBrush );
- FillRect( lsHDC, &r, lsClearBrush );
-}
-void CNFGSwapBuffers()
+void CNFGUpdateScreenWithBitmap( unsigned long * data, int w, int h )
{
- int thisw, thish;
RECT r;
- BitBlt( lsWindowHDC, 0, 0, lsLastWidth, lsLastHeight, lsHDC, 0, 0, SRCCOPY );
+
+ int a = SetBitmapBits(lsBitmap,w*h*4,data);
+ a = BitBlt(lsWindowHDC, 0, 0, w, h, lsHDC, 0, 0, SRCCOPY);
UpdateWindow( lsHWND );
+ int thisw, thish;
+
//Check to see if the window is closed.
if( !IsWindow( lsHWND ) )
{
@@ -85,36 +59,18 @@ void CNFGSwapBuffers()
GetClientRect( lsHWND, &r );
thisw = r.right - r.left;
thish = r.bottom - r.top;
- if( thisw != lsLastWidth || thish != lsLastHeight )
+ if( thisw != bufferx || thish != buffery )
{
- lsLastWidth = thisw;
- lsLastHeight = thish;
+ bufferx = thisw;
+ buffery = thish;
InternalHandleResize();
}
}
-void CNFGTackPoly( RDPoint * points, int verts )
-{
- int i;
- POINT * t = (POINT*)alloca( sizeof( POINT ) * verts );
- for( i = 0; i < verts; i++ )
- {
- t[i].x = points[i].x;
- t[i].y = points[i].y;
- }
- Polygon( lsHDC, t, verts );
-}
-
-
-void CNFGTackPixel( short x1, short y1 )
-{
- SetPixel( lsHDC, x1, y1, CNFGLastColor );
-}
-void CNFGGetDimensions( short * x, short * y )
+void CNFGTearDown()
{
- *x = lsLastWidth;
- *y = lsLastHeight;
+ PostQuitMessage(0);
}
//This was from the article
@@ -123,17 +79,13 @@ LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
switch(msg)
{
case WM_DESTROY:
+ HandleDestroy();
CNFGTearDown();
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
-void CNFGTearDown()
-{
- PostQuitMessage(0);
-}
-
//This was from the article, too... well, mostly.
void CNFGSetup( const char * name_of_window, int width, int height )
{
@@ -143,8 +95,8 @@ void CNFGSetup( const char * name_of_window, int width, int height )
int w, h, wd, hd;
HINSTANCE hInstance = GetModuleHandle(NULL);
- lsLastWidth = width;
- lsLastHeight = height;
+ bufferx = width;
+ buffery = height;
wnd.style = CS_HREDRAW | CS_VREDRAW; //we will explain this later
wnd.lpfnWndProc = MyWndProc;
@@ -167,8 +119,8 @@ void CNFGSetup( const char * name_of_window, int width, int height )
WS_OVERLAPPEDWINDOW, //basic window style
CW_USEDEFAULT,
CW_USEDEFAULT, //set starting point to default value
- lsLastWidth,
- lsLastHeight, //set all the dimensions to default value
+ bufferx,
+ buffery, //set all the dimensions to default value
NULL, //no parent window
NULL, //no menu
hInstance,
@@ -176,13 +128,14 @@ void CNFGSetup( const char * name_of_window, int width, int height )
lsWindowHDC = GetDC( lsHWND );
+
lsHDC = CreateCompatibleDC( lsWindowHDC );
- lsBackBitmap = CreateCompatibleBitmap( lsWindowHDC, lsLastWidth, lsLastHeight );
- SelectObject( lsHDC, lsBackBitmap );
+ lsBitmap = CreateCompatibleBitmap( lsWindowHDC, bufferx, buffery );
+ SelectObject( lsHDC, lsBitmap );
- lsClearBrush = CreateSolidBrush( CNFGBGColor );
- lsHBR = CreateSolidBrush( 0xFFFFFF );
- lsHPEN = CreatePen( PS_SOLID, 0, 0xFFFFFF );
+ //lsClearBrush = CreateSolidBrush( CNFGBGColor );
+ //lsHBR = CreateSolidBrush( 0xFFFFFF );
+ //lsHPEN = CreatePen( PS_SOLID, 0, 0xFFFFFF );
ShowWindow(lsHWND, 1); //display the window on the screen
@@ -193,7 +146,7 @@ void CNFGSetup( const char * name_of_window, int width, int height )
h = ( window.bottom - window.top);
wd = w - client.right;
hd = h - client.bottom;
- MoveWindow( lsHWND, window.left, window.top, lsLastWidth + wd, lsLastHeight + hd, 1 );
+ MoveWindow( lsHWND, window.left, window.top, bufferx + wd, buffery + hd, 1 );
InternalHandleResize();
}
@@ -229,3 +182,108 @@ void CNFGHandleInput()
}
}
+
+#ifndef RASTERIZER
+
+static HBITMAP lsBackBitmap;
+static HDC lsWindowHDC;
+static HBRUSH lsHBR;
+static HPEN lsHPEN;
+static HBRUSH lsClearBrush;
+
+static void InternalHandleResize()
+{
+ DeleteObject( lsBackBitmap );
+ lsBackBitmap = CreateCompatibleBitmap( lsHDC, bufferx, buffery );
+ SelectObject( lsHDC, lsBackBitmap );
+}
+
+uint32_t CNFGColor( uint32_t RGB )
+{
+ CNFGLastColor = RGB;
+
+ DeleteObject( lsHBR );
+ lsHBR = CreateSolidBrush( RGB );
+ SelectObject( lsHDC, lsHBR );
+
+ DeleteObject( lsHPEN );
+ lsHPEN = CreatePen( PS_SOLID, 0, RGB );
+ SelectObject( lsHDC, lsHPEN );
+
+ return RGB;
+}
+
+void CNFGTackSegment( short x1, short y1, short x2, short y2 )
+{
+ POINT pt[2] = { {x1, y1}, {x2, y2} };
+ Polyline( lsHDC, pt, 2 );
+ SetPixel( lsHDC, x1, y1, CNFGLastColor );
+ SetPixel( lsHDC, x2, y2, CNFGLastColor );
+}
+
+void CNFGTackRectangle( short x1, short y1, short x2, short y2 )
+{
+ RECT r;
+ if( x1 < x2 ) { r.left = x1; r.right = x2; }
+ else { r.left = x2; r.right = x1; }
+ if( y1 < y2 ) { r.top = y1; r.bottom = y2; }
+ else { r.top = y2; r.bottom = y1; }
+ FillRect( lsHDC, &r, lsHBR );
+}
+
+void CNFGClearFrame()
+{
+ RECT r = { 0, 0, bufferx, buffery };
+ DeleteObject( lsClearBrush );
+ lsClearBrush = CreateSolidBrush( CNFGBGColor );
+ SelectObject( lsHDC, lsClearBrush );
+
+ FillRect( lsHDC, &r, lsClearBrush );
+}
+
+void CNFGTackPoly( RDPoint * points, int verts )
+{
+ int i;
+ POINT * t = (POINT*)alloca( sizeof( POINT ) * verts );
+ for( i = 0; i < verts; i++ )
+ {
+ t[i].x = points[i].x;
+ t[i].y = points[i].y;
+ }
+ Polygon( lsHDC, t, verts );
+}
+
+
+void CNFGTackPixel( short x1, short y1 )
+{
+ SetPixel( lsHDC, x1, y1, CNFGLastColor );
+}
+
+void CNFGSwapBuffers()
+{
+ int thisw, thish;
+
+ RECT r;
+ BitBlt( lsWindowHDC, 0, 0, bufferx, buffery, lsHDC, 0, 0, SRCCOPY );
+ UpdateWindow( lsHWND );
+ //Check to see if the window is closed.
+ if( !IsWindow( lsHWND ) )
+ {
+ exit( 0 );
+ }
+
+ GetClientRect( lsHWND, &r );
+ thisw = r.right - r.left;
+ thish = r.bottom - r.top;
+
+ if( thisw != bufferx || thish != buffery )
+ {
+ bufferx = thisw;
+ buffery = thish;
+ InternalHandleResize();
+ }
+}
+
+void CNFGInternalResize( short bufferx, short buffery ) { }
+#endif
+
diff --git a/redist/XDriver.c b/redist/CNFGXDriver.c
index 507ca95..8a8904a 100644
--- a/redist/XDriver.c
+++ b/redist/CNFGXDriver.c
@@ -4,7 +4,7 @@
//#define HAS_XINERAMA
-#include "DrawFunctions.h"
+#include "CNFGFunctions.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -29,8 +29,18 @@ int FullScreen = 0;
void CNFGGetDimensions( short * x, short * y )
{
+ static int lastx;
+ static int lasty;
+
*x = CNFGWinAtt.width;
*y = CNFGWinAtt.height;
+
+ if( lastx != *x || lasty != *y )
+ {
+ lastx = *x;
+ lasty = *y;
+ CNFGInternalResize( lastx, lasty );
+ }
}
static void InternalLinkScreenAndGo( const char * WindowName )
@@ -286,5 +296,9 @@ void CNFGTackPoly( RDPoint * points, int verts )
XFillPolygon(CNFGDisplay, CNFGPixmap, CNFGGC, (XPoint *)points, 3, Convex, CoordModeOrigin );
}
+void CNFGInternalResize( short x, short y ) { }
+
+#else
+#include "CNFGRasterizer.h"
#endif
diff --git a/redist/hid-osx.c b/redist/hid-osx.c
new file mode 100644
index 0000000..57a337c
--- /dev/null
+++ b/redist/hid-osx.c
@@ -0,0 +1,1111 @@
+/*******************************************************
+ HIDAPI - Multi-Platform library for
+ communication with HID devices.
+
+ Alan Ott
+ Signal 11 Software
+
+ 2010-07-03
+
+ Copyright 2010, All Rights Reserved.
+
+ At the discretion of the user of this library,
+ this software may be licensed under the terms of the
+ GNU General Public License v3, a BSD-Style license, or the
+ original HIDAPI license as outlined in the LICENSE.txt,
+ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
+ files located at the root of the source distribution.
+ These files may also be found in the public source
+ code repository located at:
+ http://github.com/signal11/hidapi .
+********************************************************/
+
+/* See Apple Technical Note TN2187 for details on IOHidManager. */
+
+#include <IOKit/hid/IOHIDManager.h>
+#include <IOKit/hid/IOHIDKeys.h>
+#include <IOKit/IOKitLib.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <wchar.h>
+#include <locale.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <dlfcn.h>
+
+#include "hidapi.h"
+
+/* Barrier implementation because Mac OSX doesn't have pthread_barrier.
+ It also doesn't have clock_gettime(). So much for POSIX and SUSv2.
+ This implementation came from Brent Priddy and was posted on
+ StackOverflow. It is used with his permission. */
+typedef int pthread_barrierattr_t;
+typedef struct pthread_barrier {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int count;
+ int trip_count;
+} pthread_barrier_t;
+
+static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
+{
+ if(count == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
+ return -1;
+ }
+ if(pthread_cond_init(&barrier->cond, 0) < 0) {
+ pthread_mutex_destroy(&barrier->mutex);
+ return -1;
+ }
+ barrier->trip_count = count;
+ barrier->count = 0;
+
+ return 0;
+}
+
+static int pthread_barrier_destroy(pthread_barrier_t *barrier)
+{
+ pthread_cond_destroy(&barrier->cond);
+ pthread_mutex_destroy(&barrier->mutex);
+ return 0;
+}
+
+static int pthread_barrier_wait(pthread_barrier_t *barrier)
+{
+ pthread_mutex_lock(&barrier->mutex);
+ ++(barrier->count);
+ if(barrier->count >= barrier->trip_count)
+ {
+ barrier->count = 0;
+ pthread_cond_broadcast(&barrier->cond);
+ pthread_mutex_unlock(&barrier->mutex);
+ return 1;
+ }
+ else
+ {
+ pthread_cond_wait(&barrier->cond, &(barrier->mutex));
+ pthread_mutex_unlock(&barrier->mutex);
+ return 0;
+ }
+}
+
+static int return_data(hid_device *dev, unsigned char *data, size_t length);
+
+/* Linked List of input reports received from the device. */
+struct input_report {
+ uint8_t *data;
+ size_t len;
+ struct input_report *next;
+};
+
+struct hid_device_ {
+ IOHIDDeviceRef device_handle;
+ int blocking;
+ int uses_numbered_reports;
+ int disconnected;
+ CFStringRef run_loop_mode;
+ CFRunLoopRef run_loop;
+ CFRunLoopSourceRef source;
+ uint8_t *input_report_buf;
+ CFIndex max_input_report_len;
+ struct input_report *input_reports;
+
+ pthread_t thread;
+ pthread_mutex_t mutex; /* Protects input_reports */
+ pthread_cond_t condition;
+ pthread_barrier_t barrier; /* Ensures correct startup sequence */
+ pthread_barrier_t shutdown_barrier; /* Ensures correct shutdown sequence */
+ int shutdown_thread;
+};
+
+static hid_device *new_hid_device(void)
+{
+ hid_device *dev = calloc(1, sizeof(hid_device));
+ dev->device_handle = NULL;
+ dev->blocking = 1;
+ dev->uses_numbered_reports = 0;
+ dev->disconnected = 0;
+ dev->run_loop_mode = NULL;
+ dev->run_loop = NULL;
+ dev->source = NULL;
+ dev->input_report_buf = NULL;
+ dev->input_reports = NULL;
+ dev->shutdown_thread = 0;
+
+ /* Thread objects */
+ pthread_mutex_init(&dev->mutex, NULL);
+ pthread_cond_init(&dev->condition, NULL);
+ pthread_barrier_init(&dev->barrier, NULL, 2);
+ pthread_barrier_init(&dev->shutdown_barrier, NULL, 2);
+
+ return dev;
+}
+
+static void free_hid_device(hid_device *dev)
+{
+ if (!dev)
+ return;
+
+ /* Delete any input reports still left over. */
+ struct input_report *rpt = dev->input_reports;
+ while (rpt) {
+ struct input_report *next = rpt->next;
+ free(rpt->data);
+ free(rpt);
+ rpt = next;
+ }
+
+ /* Free the string and the report buffer. The check for NULL
+ is necessary here as CFRelease() doesn't handle NULL like
+ free() and others do. */
+ if (dev->run_loop_mode)
+ CFRelease(dev->run_loop_mode);
+ if (dev->source)
+ CFRelease(dev->source);
+ free(dev->input_report_buf);
+
+ /* Clean up the thread objects */
+ pthread_barrier_destroy(&dev->shutdown_barrier);
+ pthread_barrier_destroy(&dev->barrier);
+ pthread_cond_destroy(&dev->condition);
+ pthread_mutex_destroy(&dev->mutex);
+
+ /* Free the structure itself. */
+ free(dev);
+}
+
+static IOHIDManagerRef hid_mgr = 0x0;
+
+
+#if 0
+static void register_error(hid_device *device, const char *op)
+{
+
+}
+#endif
+
+
+static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key)
+{
+ CFTypeRef ref;
+ int32_t value;
+
+ ref = IOHIDDeviceGetProperty(device, key);
+ if (ref) {
+ if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
+ CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &value);
+ return value;
+ }
+ }
+ return 0;
+}
+
+static unsigned short get_vendor_id(IOHIDDeviceRef device)
+{
+ return get_int_property(device, CFSTR(kIOHIDVendorIDKey));
+}
+
+static unsigned short get_product_id(IOHIDDeviceRef device)
+{
+ return get_int_property(device, CFSTR(kIOHIDProductIDKey));
+}
+
+static int32_t get_max_report_length(IOHIDDeviceRef device)
+{
+ return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey));
+}
+
+static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t *buf, size_t len)
+{
+ CFStringRef str;
+
+ if (!len)
+ return 0;
+
+ str = IOHIDDeviceGetProperty(device, prop);
+
+ buf[0] = 0;
+
+ if (str) {
+ CFIndex str_len = CFStringGetLength(str);
+ CFRange range;
+ CFIndex used_buf_len;
+ CFIndex chars_copied;
+
+ len --;
+
+ range.location = 0;
+ range.length = ((size_t)str_len > len)? len: (size_t)str_len;
+ chars_copied = CFStringGetBytes(str,
+ range,
+ kCFStringEncodingUTF32LE,
+ (char)'?',
+ FALSE,
+ (UInt8*)buf,
+ len * sizeof(wchar_t),
+ &used_buf_len);
+
+ if (chars_copied == len)
+ buf[len] = 0; /* len is decremented above */
+ else
+ buf[chars_copied] = 0;
+
+ return 0;
+ }
+ else
+ return -1;
+
+}
+
+static int get_serial_number(IOHIDDeviceRef device, wchar_t *buf, size_t len)
+{
+ return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len);
+}
+
+static int get_manufacturer_string(IOHIDDeviceRef device, wchar_t *buf, size_t len)
+{
+ return get_string_property(device, CFSTR(kIOHIDManufacturerKey), buf, len);
+}
+
+static int get_product_string(IOHIDDeviceRef device, wchar_t *buf, size_t len)
+{
+ return get_string_property(device, CFSTR(kIOHIDProductKey), buf, len);
+}
+
+
+/* Implementation of wcsdup() for Mac. */
+static wchar_t *dup_wcs(const wchar_t *s)
+{
+ size_t len = wcslen(s);
+ wchar_t *ret = malloc((len+1)*sizeof(wchar_t));
+ wcscpy(ret, s);
+
+ return ret;
+}
+
+/* hidapi_IOHIDDeviceGetService()
+ *
+ * Return the io_service_t corresponding to a given IOHIDDeviceRef, either by:
+ * - on OS X 10.6 and above, calling IOHIDDeviceGetService()
+ * - on OS X 10.5, extract it from the IOHIDDevice struct
+ */
+static io_service_t hidapi_IOHIDDeviceGetService(IOHIDDeviceRef device)
+{
+ static void *iokit_framework = NULL;
+ static io_service_t (*dynamic_IOHIDDeviceGetService)(IOHIDDeviceRef device) = NULL;
+
+ /* Use dlopen()/dlsym() to get a pointer to IOHIDDeviceGetService() if it exists.
+ * If any of these steps fail, dynamic_IOHIDDeviceGetService will be left NULL
+ * and the fallback method will be used.
+ */
+ if (iokit_framework == NULL) {
+ iokit_framework = dlopen("/System/Library/IOKit.framework/IOKit", RTLD_LAZY);
+
+ if (iokit_framework != NULL)
+ dynamic_IOHIDDeviceGetService = dlsym(iokit_framework, "IOHIDDeviceGetService");
+ }
+
+ if (dynamic_IOHIDDeviceGetService != NULL) {
+ /* Running on OS X 10.6 and above: IOHIDDeviceGetService() exists */
+ return dynamic_IOHIDDeviceGetService(device);
+ }
+ else
+ {
+ /* Running on OS X 10.5: IOHIDDeviceGetService() doesn't exist.
+ *
+ * Be naughty and pull the service out of the IOHIDDevice.
+ * IOHIDDevice is an opaque struct not exposed to applications, but its
+ * layout is stable through all available versions of OS X.
+ * Tested and working on OS X 10.5.8 i386, x86_64, and ppc.
+ */
+ struct IOHIDDevice_internal {
+ /* The first field of the IOHIDDevice struct is a
+ * CFRuntimeBase (which is a private CF struct).
+ *
+ * a, b, and c are the 3 fields that make up a CFRuntimeBase.
+ * See http://opensource.apple.com/source/CF/CF-476.18/CFRuntime.h
+ *
+ * The second field of the IOHIDDevice is the io_service_t we're looking for.
+ */
+ uintptr_t a;
+ uint8_t b[4];
+#if __LP64__
+ uint32_t c;
+#endif
+ io_service_t service;
+ };
+ struct IOHIDDevice_internal *tmp = (struct IOHIDDevice_internal *)device;
+
+ return tmp->service;
+ }
+}
+
+/* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */
+static int init_hid_manager(void)
+{
+ /* Initialize all the HID Manager Objects */
+ hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
+ if (hid_mgr) {
+ IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
+ IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ return 0;
+ }
+
+ return -1;
+}
+
+/* Initialize the IOHIDManager if necessary. This is the public function, and
+ it is safe to call this function repeatedly. Return 0 for success and -1
+ for failure. */
+int HID_API_EXPORT hid_init(void)
+{
+ if (!hid_mgr) {
+ return init_hid_manager();
+ }
+
+ /* Already initialized. */
+ return 0;
+}
+
+int HID_API_EXPORT hid_exit(void)
+{
+ if (hid_mgr) {
+ /* Close the HID manager. */
+ IOHIDManagerClose(hid_mgr, kIOHIDOptionsTypeNone);
+ CFRelease(hid_mgr);
+ hid_mgr = NULL;
+ }
+
+ return 0;
+}
+
+static void process_pending_events(void) {
+ SInt32 res;
+ do {
+ res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, FALSE);
+ } while(res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut);
+}
+
+struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
+{
+ struct hid_device_info *root = NULL; /* return object */
+ struct hid_device_info *cur_dev = NULL;
+ CFIndex num_devices;
+ int i;
+
+ /* Set up the HID Manager if it hasn't been done */
+ if (hid_init() < 0)
+ return NULL;
+
+ /* give the IOHIDManager a chance to update itself */
+ process_pending_events();
+
+ /* Get a list of the Devices */
+ IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
+ CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
+
+ /* Convert the list into a C array so we can iterate easily. */
+ num_devices = CFSetGetCount(device_set);
+ IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef));
+ CFSetGetValues(device_set, (const void **) device_array);
+
+ /* Iterate over each device, making an entry for it. */
+ for (i = 0; i < num_devices; i++) {
+ unsigned short dev_vid;
+ unsigned short dev_pid;
+ #define BUF_LEN 256
+ wchar_t buf[BUF_LEN];
+
+ IOHIDDeviceRef dev = device_array[i];
+
+ if (!dev) {
+ continue;
+ }
+ dev_vid = get_vendor_id(dev);
+ dev_pid = get_product_id(dev);
+
+ /* Check the VID/PID against the arguments */
+ if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
+ (product_id == 0x0 || product_id == dev_pid)) {
+ struct hid_device_info *tmp;
+ io_object_t iokit_dev;
+ kern_return_t res;
+ io_string_t path;
+
+ /* VID/PID match. Create the record. */
+ tmp = malloc(sizeof(struct hid_device_info));
+ if (cur_dev) {
+ cur_dev->next = tmp;
+ }
+ else {
+ root = tmp;
+ }
+ cur_dev = tmp;
+
+ /* Get the Usage Page and Usage for this device. */
+ cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey));
+ cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey));
+
+ /* Fill out the record */
+ cur_dev->next = NULL;
+
+ /* Fill in the path (IOService plane) */
+ iokit_dev = hidapi_IOHIDDeviceGetService(dev);
+ res = IORegistryEntryGetPath(iokit_dev, kIOServicePlane, path);
+ if (res == KERN_SUCCESS)
+ cur_dev->path = strdup(path);
+ else
+ cur_dev->path = strdup("");
+
+ /* Serial Number */
+ get_serial_number(dev, buf, BUF_LEN);
+ cur_dev->serial_number = dup_wcs(buf);
+
+ /* Manufacturer and Product strings */
+ get_manufacturer_string(dev, buf, BUF_LEN);
+ cur_dev->manufacturer_string = dup_wcs(buf);
+ get_product_string(dev, buf, BUF_LEN);
+ cur_dev->product_string = dup_wcs(buf);
+
+ /* VID/PID */
+ cur_dev->vendor_id = dev_vid;
+ cur_dev->product_id = dev_pid;
+
+ /* Release Number */
+ cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey));
+
+ /* Interface Number (Unsupported on Mac)*/
+ cur_dev->interface_number = -1;
+ }
+ }
+
+ free(device_array);
+ CFRelease(device_set);
+
+ return root;
+}
+
+void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
+{
+ /* This function is identical to the Linux version. Platform independent. */
+ struct hid_device_info *d = devs;
+ while (d) {
+ struct hid_device_info *next = d->next;
+ free(d->path);
+ free(d->serial_number);
+ free(d->manufacturer_string);
+ free(d->product_string);
+ free(d);
+ d = next;
+ }
+}
+
+hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
+{
+ /* This function is identical to the Linux version. Platform independent. */
+ struct hid_device_info *devs, *cur_dev;
+ const char *path_to_open = NULL;
+ hid_device * handle = NULL;
+
+ devs = hid_enumerate(vendor_id, product_id);
+ cur_dev = devs;
+ while (cur_dev) {
+ if (cur_dev->vendor_id == vendor_id &&
+ cur_dev->product_id == product_id) {
+ if (serial_number) {
+ if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
+ path_to_open = cur_dev->path;
+ break;
+ }
+ }
+ else {
+ path_to_open = cur_dev->path;
+ break;
+ }
+ }
+ cur_dev = cur_dev->next;
+ }
+
+ if (path_to_open) {
+ /* Open the device */
+ handle = hid_open_path(path_to_open);
+ }
+
+ hid_free_enumeration(devs);
+
+ return handle;
+}
+
+static void hid_device_removal_callback(void *context, IOReturn result,
+ void *sender)
+{
+ /* Stop the Run Loop for this device. */
+ hid_device *d = context;
+
+ d->disconnected = 1;
+ CFRunLoopStop(d->run_loop);
+}
+
+/* The Run Loop calls this function for each input report received.
+ This function puts the data into a linked list to be picked up by
+ hid_read(). */
+static void hid_report_callback(void *context, IOReturn result, void *sender,
+ IOHIDReportType report_type, uint32_t report_id,
+ uint8_t *report, CFIndex report_length)
+{
+ struct input_report *rpt;
+ hid_device *dev = context;
+
+ /* Make a new Input Report object */
+ rpt = calloc(1, sizeof(struct input_report));
+ rpt->data = calloc(1, report_length);
+ memcpy(rpt->data, report, report_length);
+ rpt->len = report_length;
+ rpt->next = NULL;
+
+ /* Lock this section */
+ pthread_mutex_lock(&dev->mutex);
+
+ /* Attach the new report object to the end of the list. */
+ if (dev->input_reports == NULL) {
+ /* The list is empty. Put it at the root. */
+ dev->input_reports = rpt;
+ }
+ else {
+ /* Find the end of the list and attach. */
+ struct input_report *cur = dev->input_reports;
+ int num_queued = 0;
+ while (cur->next != NULL) {
+ cur = cur->next;
+ num_queued++;
+ }
+ cur->next = rpt;
+
+ /* Pop one off if we've reached 30 in the queue. This
+ way we don't grow forever if the user never reads
+ anything from the device. */
+ if (num_queued > 30) {
+ return_data(dev, NULL, 0);
+ }
+ }
+
+ /* Signal a waiting thread that there is data. */
+ pthread_cond_signal(&dev->condition);
+
+ /* Unlock */
+ pthread_mutex_unlock(&dev->mutex);
+
+}
+
+/* This gets called when the read_thread's run loop gets signaled by
+ hid_close(), and serves to stop the read_thread's run loop. */
+static void perform_signal_callback(void *context)
+{
+ hid_device *dev = context;
+ CFRunLoopStop(dev->run_loop); /*TODO: CFRunLoopGetCurrent()*/
+}
+
+static void *read_thread(void *param)
+{
+ hid_device *dev = param;
+ SInt32 code;
+
+ /* Move the device's run loop to this thread. */
+ IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode);
+
+ /* Create the RunLoopSource which is used to signal the
+ event loop to stop when hid_close() is called. */
+ CFRunLoopSourceContext ctx;
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.version = 0;
+ ctx.info = dev;
+ ctx.perform = &perform_signal_callback;
+ dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode);
+
+ /* Store off the Run Loop so it can be stopped from hid_close()
+ and on device disconnection. */
+ dev->run_loop = CFRunLoopGetCurrent();
+
+ /* Notify the main thread that the read thread is up and running. */
+ pthread_barrier_wait(&dev->barrier);
+
+ /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input
+ reports into the hid_report_callback(). */
+ while (!dev->shutdown_thread && !dev->disconnected) {
+ code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE);
+ /* Return if the device has been disconnected */
+ if (code == kCFRunLoopRunFinished) {
+ dev->disconnected = 1;
+ break;
+ }
+
+
+ /* Break if The Run Loop returns Finished or Stopped. */
+ if (code != kCFRunLoopRunTimedOut &&
+ code != kCFRunLoopRunHandledSource) {
+ /* There was some kind of error. Setting
+ shutdown seems to make sense, but
+ there may be something else more appropriate */
+ dev->shutdown_thread = 1;
+ break;
+ }
+ }
+
+ /* Now that the read thread is stopping, Wake any threads which are
+ waiting on data (in hid_read_timeout()). Do this under a mutex to
+ make sure that a thread which is about to go to sleep waiting on
+ the condition actually will go to sleep before the condition is
+ signaled. */
+ pthread_mutex_lock(&dev->mutex);
+ pthread_cond_broadcast(&dev->condition);
+ pthread_mutex_unlock(&dev->mutex);
+
+ /* Wait here until hid_close() is called and makes it past
+ the call to CFRunLoopWakeUp(). This thread still needs to
+ be valid when that function is called on the other thread. */
+ pthread_barrier_wait(&dev->shutdown_barrier);
+
+ return NULL;
+}
+
+/* hid_open_path()
+ *
+ * path must be a valid path to an IOHIDDevice in the IOService plane
+ * Example: "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/EHC1@1D,7/AppleUSBEHCI/PLAYSTATION(R)3 Controller@fd120000/IOUSBInterface@0/IOUSBHIDDriver"
+ */
+hid_device * HID_API_EXPORT hid_open_path(const char *path)
+{
+ hid_device *dev = NULL;
+ io_registry_entry_t entry = MACH_PORT_NULL;
+
+ dev = new_hid_device();
+
+ /* Set up the HID Manager if it hasn't been done */
+ if (hid_init() < 0)
+ return NULL;
+
+ /* Get the IORegistry entry for the given path */
+ entry = IORegistryEntryFromPath(kIOMasterPortDefault, path);
+ if (entry == MACH_PORT_NULL) {
+ /* Path wasn't valid (maybe device was removed?) */
+ goto return_error;
+ }
+
+ /* Create an IOHIDDevice for the entry */
+ dev->device_handle = IOHIDDeviceCreate(kCFAllocatorDefault, entry);
+ if (dev->device_handle == NULL) {
+ /* Error creating the HID device */
+ goto return_error;
+ }
+
+ /* Open the IOHIDDevice */
+ IOReturn ret = IOHIDDeviceOpen(dev->device_handle, kIOHIDOptionsTypeSeizeDevice);
+ if (ret == kIOReturnSuccess) {
+ char str[32];
+
+ /* Create the buffers for receiving data */
+ dev->max_input_report_len = (CFIndex) get_max_report_length(dev->device_handle);
+ dev->input_report_buf = calloc(dev->max_input_report_len, sizeof(uint8_t));
+
+ /* Create the Run Loop Mode for this device.
+ printing the reference seems to work. */
+ sprintf(str, "HIDAPI_%p", dev->device_handle);
+ dev->run_loop_mode =
+ CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII);
+
+ /* Attach the device to a Run Loop */
+ IOHIDDeviceRegisterInputReportCallback(
+ dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
+ &hid_report_callback, dev);
+ IOHIDDeviceRegisterRemovalCallback(dev->device_handle, hid_device_removal_callback, dev);
+
+ /* Start the read thread */
+ pthread_create(&dev->thread, NULL, read_thread, dev);
+
+ /* Wait here for the read thread to be initialized. */
+ pthread_barrier_wait(&dev->barrier);
+
+ IOObjectRelease(entry);
+ return dev;
+ }
+ else {
+ goto return_error;
+ }
+
+return_error:
+ if (dev->device_handle != NULL)
+ CFRelease(dev->device_handle);
+
+ if (entry != MACH_PORT_NULL)
+ IOObjectRelease(entry);
+
+ free_hid_device(dev);
+ return NULL;
+}
+
+static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char *data, size_t length)
+{
+ const unsigned char *data_to_send;
+ size_t length_to_send;
+ IOReturn res;
+
+ /* Return if the device has been disconnected. */
+ if (dev->disconnected)
+ return -1;
+
+ if (data[0] == 0x0) {
+ /* Not using numbered Reports.
+ Don't send the report number. */
+ data_to_send = data+1;
+ length_to_send = length-1;
+ }
+ else {
+ /* Using numbered Reports.
+ Send the Report Number */
+ data_to_send = data;
+ length_to_send = length;
+ }
+
+ if (!dev->disconnected) {
+ res = IOHIDDeviceSetReport(dev->device_handle,
+ type,
+ data[0], /* Report ID*/
+ data_to_send, length_to_send);
+
+ if (res == kIOReturnSuccess) {
+ return length;
+ }
+ else
+ return -1;
+ }
+
+ return -1;
+}
+
+int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
+{
+ return set_report(dev, kIOHIDReportTypeOutput, data, length);
+}
+
+/* Helper function, so that this isn't duplicated in hid_read(). */
+static int return_data(hid_device *dev, unsigned char *data, size_t length)
+{
+ /* Copy the data out of the linked list item (rpt) into the
+ return buffer (data), and delete the liked list item. */
+ struct input_report *rpt = dev->input_reports;
+ size_t len = (length < rpt->len)? length: rpt->len;
+ memcpy(data, rpt->data, len);
+ dev->input_reports = rpt->next;
+ free(rpt->data);
+ free(rpt);
+ return len;
+}
+
+static int cond_wait(const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ while (!dev->input_reports) {
+ int res = pthread_cond_wait(cond, mutex);
+ if (res != 0)
+ return res;
+
+ /* A res of 0 means we may have been signaled or it may
+ be a spurious wakeup. Check to see that there's acutally
+ data in the queue before returning, and if not, go back
+ to sleep. See the pthread_cond_timedwait() man page for
+ details. */
+
+ if (dev->shutdown_thread || dev->disconnected)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int cond_timedwait(const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
+{
+ while (!dev->input_reports) {
+ int res = pthread_cond_timedwait(cond, mutex, abstime);
+ if (res != 0)
+ return res;
+
+ /* A res of 0 means we may have been signaled or it may
+ be a spurious wakeup. Check to see that there's acutally
+ data in the queue before returning, and if not, go back
+ to sleep. See the pthread_cond_timedwait() man page for
+ details. */
+
+ if (dev->shutdown_thread || dev->disconnected)
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
+{
+ int bytes_read = -1;
+
+ /* Lock the access to the report list. */
+ pthread_mutex_lock(&dev->mutex);
+
+ /* There's an input report queued up. Return it. */
+ if (dev->input_reports) {
+ /* Return the first one */
+ bytes_read = return_data(dev, data, length);
+ goto ret;
+ }
+
+ /* Return if the device has been disconnected. */
+ if (dev->disconnected) {
+ bytes_read = -1;
+ goto ret;
+ }
+
+ if (dev->shutdown_thread) {
+ /* This means the device has been closed (or there
+ has been an error. An error code of -1 should
+ be returned. */
+ bytes_read = -1;
+ goto ret;
+ }
+
+ /* There is no data. Go to sleep and wait for data. */
+
+ if (milliseconds == -1) {
+ /* Blocking */
+ int res;
+ res = cond_wait(dev, &dev->condition, &dev->mutex);
+ if (res == 0)
+ bytes_read = return_data(dev, data, length);
+ else {
+ /* There was an error, or a device disconnection. */
+ bytes_read = -1;
+ }
+ }
+ else if (milliseconds > 0) {
+ /* Non-blocking, but called with timeout. */
+ int res;
+ struct timespec ts;
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+ ts.tv_sec += milliseconds / 1000;
+ ts.tv_nsec += (milliseconds % 1000) * 1000000;
+ if (ts.tv_nsec >= 1000000000L) {
+ ts.tv_sec++;
+ ts.tv_nsec -= 1000000000L;
+ }
+
+ res = cond_timedwait(dev, &dev->condition, &dev->mutex, &ts);
+ if (res == 0)
+ bytes_read = return_data(dev, data, length);
+ else if (res == ETIMEDOUT)
+ bytes_read = 0;
+ else
+ bytes_read = -1;
+ }
+ else {
+ /* Purely non-blocking */
+ bytes_read = 0;
+ }
+
+ret:
+ /* Unlock */
+ pthread_mutex_unlock(&dev->mutex);
+ return bytes_read;
+}
+
+int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
+{
+ return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
+}
+
+int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
+{
+ /* All Nonblocking operation is handled by the library. */
+ dev->blocking = !nonblock;
+
+ return 0;
+}
+
+int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
+{
+ return set_report(dev, kIOHIDReportTypeFeature, data, length);
+}
+
+int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
+{
+ CFIndex len = length;
+ IOReturn res;
+
+ /* Return if the device has been unplugged. */
+ if (dev->disconnected)
+ return -1;
+
+ res = IOHIDDeviceGetReport(dev->device_handle,
+ kIOHIDReportTypeFeature,
+ data[0], /* Report ID */
+ data, &len);
+ if (res == kIOReturnSuccess)
+ return len;
+ else
+ return -1;
+}
+
+
+void HID_API_EXPORT hid_close(hid_device *dev)
+{
+ if (!dev)
+ return;
+
+ /* Disconnect the report callback before close. */
+ if (!dev->disconnected) {
+ IOHIDDeviceRegisterInputReportCallback(
+ dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
+ NULL, dev);
+ IOHIDDeviceRegisterRemovalCallback(dev->device_handle, NULL, dev);
+ IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, dev->run_loop, dev->run_loop_mode);
+ IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
+ }
+
+ /* Cause read_thread() to stop. */
+ dev->shutdown_thread = 1;
+
+ /* Wake up the run thread's event loop so that the thread can exit. */
+ CFRunLoopSourceSignal(dev->source);
+ CFRunLoopWakeUp(dev->run_loop);
+
+ /* Notify the read thread that it can shut down now. */
+ pthread_barrier_wait(&dev->shutdown_barrier);
+
+ /* Wait for read_thread() to end. */
+ pthread_join(dev->thread, NULL);
+
+ /* Close the OS handle to the device, but only if it's not
+ been unplugged. If it's been unplugged, then calling
+ IOHIDDeviceClose() will crash. */
+ if (!dev->disconnected) {
+ IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeSeizeDevice);
+ }
+
+ /* Clear out the queue of received reports. */
+ pthread_mutex_lock(&dev->mutex);
+ while (dev->input_reports) {
+ return_data(dev, NULL, 0);
+ }
+ pthread_mutex_unlock(&dev->mutex);
+ CFRelease(dev->device_handle);
+
+ free_hid_device(dev);
+}
+
+int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
+{
+ return get_manufacturer_string(dev->device_handle, string, maxlen);
+}
+
+int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
+{
+ return get_product_string(dev->device_handle, string, maxlen);
+}
+
+int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
+{
+ return get_serial_number(dev->device_handle, string, maxlen);
+}
+
+int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
+{
+ /* TODO: */
+
+ return 0;
+}
+
+
+HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
+{
+ /* TODO: */
+
+ return NULL;
+}
+
+
+
+
+
+
+
+#if 0
+static int32_t get_location_id(IOHIDDeviceRef device)
+{
+ return get_int_property(device, CFSTR(kIOHIDLocationIDKey));
+}
+
+static int32_t get_usage(IOHIDDeviceRef device)
+{
+ int32_t res;
+ res = get_int_property(device, CFSTR(kIOHIDDeviceUsageKey));
+ if (!res)
+ res = get_int_property(device, CFSTR(kIOHIDPrimaryUsageKey));
+ return res;
+}
+
+static int32_t get_usage_page(IOHIDDeviceRef device)
+{
+ int32_t res;
+ res = get_int_property(device, CFSTR(kIOHIDDeviceUsagePageKey));
+ if (!res)
+ res = get_int_property(device, CFSTR(kIOHIDPrimaryUsagePageKey));
+ return res;
+}
+
+static int get_transport(IOHIDDeviceRef device, wchar_t *buf, size_t len)
+{
+ return get_string_property(device, CFSTR(kIOHIDTransportKey), buf, len);
+}
+
+
+int main(void)
+{
+ IOHIDManagerRef mgr;
+ int i;
+
+ mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
+ IOHIDManagerSetDeviceMatching(mgr, NULL);
+ IOHIDManagerOpen(mgr, kIOHIDOptionsTypeNone);
+
+ CFSetRef device_set = IOHIDManagerCopyDevices(mgr);
+
+ CFIndex num_devices = CFSetGetCount(device_set);
+ IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef));
+ CFSetGetValues(device_set, (const void **) device_array);
+
+ for (i = 0; i < num_devices; i++) {
+ IOHIDDeviceRef dev = device_array[i];
+ printf("Device: %p\n", dev);
+ printf(" %04hx %04hx\n", get_vendor_id(dev), get_product_id(dev));
+
+ wchar_t serial[256], buf[256];
+ char cbuf[256];
+ get_serial_number(dev, serial, 256);
+
+
+ printf(" Serial: %ls\n", serial);
+ printf(" Loc: %ld\n", get_location_id(dev));
+ get_transport(dev, buf, 256);
+ printf(" Trans: %ls\n", buf);
+ make_path(dev, cbuf, 256);
+ printf(" Path: %s\n", cbuf);
+
+ }
+
+ return 0;
+}
+#endif
+
diff --git a/windows/hid.c b/redist/hid-windows.c
index 8f80071..6c379b5 100644
--- a/windows/hid.c
+++ b/redist/hid-windows.c
@@ -687,7 +687,7 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *
length = dev->output_report_length;
}
- res = WriteFile(dev->device_handle, buf, length, NULL, &ol);
+ res = WriteFile(dev->device_handle, buf, (DWORD)length, NULL, &ol);
if (!res) {
if (GetLastError() != ERROR_IO_PENDING) {
@@ -730,7 +730,7 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char
dev->read_pending = TRUE;
memset(dev->read_buf, 0, dev->input_report_length);
ResetEvent(ev);
- res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol);
+ res = ReadFile(dev->device_handle, dev->read_buf, (DWORD)dev->input_report_length, &bytes_read, &dev->ol);
if (!res) {
if (GetLastError() != ERROR_IO_PENDING) {
@@ -784,7 +784,7 @@ end_of_function:
return -1;
}
- return copy_len;
+ return (int)copy_len;
}
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
@@ -800,13 +800,13 @@ int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonbloc
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
{
- BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, length);
+ BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, (ULONG)length);
if (!res) {
register_error(dev, "HidD_SetFeature");
return -1;
}
- return length;
+ return (int)length;
}
@@ -828,8 +828,8 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned
res = DeviceIoControl(dev->device_handle,
IOCTL_HID_GET_FEATURE,
- data, length,
- data, length,
+ data, (DWORD)length,
+ data, (DWORD)length,
&bytes_returned, &ol);
if (!res) {
@@ -870,7 +870,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev
{
BOOL res;
- res = HidD_GetManufacturerString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
+ res = HidD_GetManufacturerString(dev->device_handle, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)));
if (!res) {
register_error(dev, "HidD_GetManufacturerString");
return -1;
@@ -883,7 +883,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wch
{
BOOL res;
- res = HidD_GetProductString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
+ res = HidD_GetProductString(dev->device_handle, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)));
if (!res) {
register_error(dev, "HidD_GetProductString");
return -1;
@@ -896,7 +896,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *de
{
BOOL res;
- res = HidD_GetSerialNumberString(dev->device_handle, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
+ res = HidD_GetSerialNumberString(dev->device_handle, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)));
if (!res) {
register_error(dev, "HidD_GetSerialNumberString");
return -1;
@@ -909,7 +909,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int
{
BOOL res;
- res = HidD_GetIndexedString(dev->device_handle, string_index, string, sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS));
+ res = HidD_GetIndexedString(dev->device_handle, string_index, string, (ULONG)(sizeof(wchar_t) * MIN(maxlen, MAX_STRING_WCHARS)));
if (!res) {
register_error(dev, "HidD_GetIndexedString");
return -1;
diff --git a/windows/hidapi.h b/redist/hidapi.h
index 43b8e7a..43b8e7a 100644
--- a/windows/hidapi.h
+++ b/redist/hidapi.h
diff --git a/redist/json_helpers.c b/redist/json_helpers.c
index 7690318..0267932 100644
--- a/redist/json_helpers.c
+++ b/redist/json_helpers.c
@@ -7,11 +7,11 @@
#include <string.h>
#include "json_helpers.h"
#include <jsmn.h>
-#ifndef __FreeBSD__
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
#include <malloc.h>
#endif
-#ifdef _WIN32
+#ifdef _MSC_VER
#include <stdarg.h>
// Windows doesn't provide asprintf, so we need to make it.
@@ -107,7 +107,7 @@ void json_write_str(FILE* f, const char* tag, const char* v) {
void (*json_begin_object)(char* tag) = NULL;
void (*json_end_object)() = NULL;
-void (*json_tag_value)(char* tag, char** values, uint16_t count) = NULL;
+void (*json_tag_value)(char* tag, char** values, uint8_t count) = NULL;
uint32_t JSON_STRING_LEN;
@@ -146,7 +146,7 @@ static uint16_t json_load_array(const char* JSON_STRING, jsmntok_t* tokens, uint
values[i] = substr(JSON_STRING, t->start, t->end, JSON_STRING_LEN);
}
- if (json_tag_value != NULL) json_tag_value(tag, values, i);
+ if (json_tag_value != NULL) json_tag_value(tag, values, (uint8_t)i);
for (i=0;i<size;++i) free(values[i]);
@@ -159,12 +159,13 @@ void json_load_file(const char* path) {
char* JSON_STRING = load_file_to_mem(path);
if (JSON_STRING==NULL) return;
- JSON_STRING_LEN = strlen(JSON_STRING);
+ JSON_STRING_LEN = (uint32_t)strlen(JSON_STRING);
jsmn_parser parser;
jsmn_init(&parser);
- uint32_t items = jsmn_parse(&parser, JSON_STRING, JSON_STRING_LEN, NULL, 0);
+ int32_t items = jsmn_parse(&parser, JSON_STRING, JSON_STRING_LEN, NULL, 0);
+ if (items < 0) return;
jsmntok_t* tokens = malloc(items * sizeof(jsmntok_t));
jsmn_init(&parser);
@@ -172,7 +173,7 @@ void json_load_file(const char* path) {
int16_t children = -1;
- for (i=0; i<items; i+=2)
+ for (i=0; i<(int)items; i+=2)
{
//increment i on each successful tag + values combination, not individual tokens
jsmntok_t* tag_t = tokens+i;
diff --git a/redist/json_helpers.h b/redist/json_helpers.h
index 1670058..1cccfe3 100644
--- a/redist/json_helpers.h
+++ b/redist/json_helpers.h
@@ -14,7 +14,7 @@ void json_write_str(FILE* f, const char* tag, const char* v);
void json_load_file(const char* path);
extern void (*json_begin_object)(char* tag);
extern void (*json_end_object)();
-extern void (*json_tag_value)(char* tag, char** values, uint16_t count);
+extern void (*json_tag_value)(char* tag, char** values, uint8_t count);
#endif \ No newline at end of file
diff --git a/redist/linmath.c b/redist/linmath.c
index dd6bd15..eefcd5f 100644
--- a/redist/linmath.c
+++ b/redist/linmath.c
@@ -207,28 +207,28 @@ void quattomatrix(FLT * matrix44, const FLT * qin)
void quatfrommatrix( FLT * q, const FLT * matrix44 )
{
//Algorithm from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
- float tr = matrix44[0] + matrix44[5] + matrix44[10];
+ FLT tr = matrix44[0] + matrix44[5] + matrix44[10];
if (tr > 0) {
- float S = sqrt(tr+1.0) * 2; // S=4*qw
- q[0] = 0.25 * S;
+ FLT S = FLT_SQRT(tr+1.0) * 2.; // S=4*qw
+ q[0] = 0.25f * S;
q[1] = (matrix44[9] - matrix44[6]) / S;
q[2] = (matrix44[2] - matrix44[8]) / S;
q[3] = (matrix44[4] - matrix44[1]) / S;
} else if ((matrix44[0] > matrix44[5])&(matrix44[0] > matrix44[10])) {
- float S = sqrt(1.0 + matrix44[0] - matrix44[5] - matrix44[10]) * 2; // S=4*qx
+ FLT S = FLT_SQRT(1.0 + matrix44[0] - matrix44[5] - matrix44[10]) * 2.; // S=4*qx
q[0] = (matrix44[9] - matrix44[6]) / S;
- q[1] = 0.25 * S;
+ q[1] = 0.25f * S;
q[2] = (matrix44[1] + matrix44[4]) / S;
q[3] = (matrix44[2] + matrix44[8]) / S;
} else if (matrix44[5] > matrix44[10]) {
- float S = sqrt(1.0 + matrix44[5] - matrix44[0] - matrix44[10]) * 2; // S=4*qy
+ FLT S = FLT_SQRT(1.0 + matrix44[5] - matrix44[0] - matrix44[10]) * 2.; // S=4*qy
q[0] = (matrix44[2] - matrix44[8]) / S;
q[1] = (matrix44[1] + matrix44[4]) / S;
- q[2] = 0.25 * S;
+ q[2] = 0.25f * S;
q[3] = (matrix44[6] + matrix44[9]) / S;
} else {
- float S = sqrt(1.0 + matrix44[10] - matrix44[0] - matrix44[5]) * 2; // S=4*qz
+ FLT S = FLT_SQRT(1.0 + matrix44[10] - matrix44[0] - matrix44[5]) * 2.; // S=4*qz
q[0] = (matrix44[4] - matrix44[1]) / S;
q[1] = (matrix44[2] + matrix44[8]) / S;
q[2] = (matrix44[6] + matrix44[9]) / S;
diff --git a/redist/os_generic.c b/redist/os_generic.c
index 0993d7a..1ab4863 100644
--- a/redist/os_generic.c
+++ b/redist/os_generic.c
@@ -55,6 +55,7 @@ void * OGJoinThread( og_thread_t ot )
{
WaitForSingleObject( ot, INFINITE );
CloseHandle( ot );
+ return 0;
}
void OGCancelThread( og_thread_t ot )
diff --git a/redist/symbol_enumerator.c b/redist/symbol_enumerator.c
index 7d33900..fcb3727 100644
--- a/redist/symbol_enumerator.c
+++ b/redist/symbol_enumerator.c
@@ -51,9 +51,13 @@ BOOL WINAPI SymEnumSymbols(
);
BOOL WINAPI SymInitialize(
- HANDLE hProcess,
- PCTSTR UserSearchPath,
- BOOL fInvadeProcess
+ HANDLE hProcess,
+ PCTSTR UserSearchPath,
+ BOOL fInvadeProcess
+);
+
+BOOL WINAPI SymCleanup(
+ HANDLE hProcess
);
BOOL CALLBACK __cdecl mycb(
diff --git a/src/poser_charlesslow.c b/src/poser_charlesslow.c
index def8323..080ad6a 100644
--- a/src/poser_charlesslow.c
+++ b/src/poser_charlesslow.c
@@ -123,9 +123,9 @@ int PoserCharlesSlow( SurviveObject * so, PoserData * pd )
ft = RunOpti(so, fs, lh, 0, LighthousePos, LighthouseQuat);
if( cycle == 0 )
{
- float sk = ft*10.;
+ FLT sk = ft*10.;
if( sk > 1 ) sk = 1;
- uint8_t cell = (1.0 - sk) * 255;
+ uint8_t cell = (uint8_t)((1.0 - sk) * 255);
FLT epsilon = 0.1;
if( dz == 0 ) { /* Why is dz special? ? */
@@ -231,7 +231,7 @@ static FLT RunOpti( SurviveObject * hmd, PoserDataFullScene * fs, int lh, int pr
if( fs->lengths[p][lh][0] < 0 || fs->lengths[p][lh][1] < 0 ) continue;
FLT me_to_dot[3];
sub3d( me_to_dot, LighthousePos, &hmd_points[p*3] );
- float dot = dot3d( &hmd_normals[p*3], me_to_dot );
+ FLT dot = dot3d( &hmd_normals[p*3], me_to_dot );
if( dot < -.01 ) { return 1000; }
}
int iters = 6;
@@ -321,7 +321,7 @@ static FLT RunOpti( SurviveObject * hmd, PoserDataFullScene * fs, int lh, int pr
}
//Step 2: Determine error.
- float errorsq = 0.0;
+ FLT errorsq = 0.0;
int count = 0;
for( p = 0; p < dpts; p++ )
{
diff --git a/src/poser_daveortho.c b/src/poser_daveortho.c
index 9f3b55a..e81e154 100644
--- a/src/poser_daveortho.c
+++ b/src/poser_daveortho.c
@@ -120,7 +120,7 @@ int PoserDaveOrtho( SurviveObject * so, PoserData * pd )
break;
}
}
-
+ return 0;
}
diff --git a/src/survive.c b/src/survive.c
index 81c45c3..f637bd8 100755
--- a/src/survive.c
+++ b/src/survive.c
@@ -9,6 +9,10 @@
#include "survive_config.h"
+#ifdef __APPLE__
+#define z_const const
+#endif
+
#ifdef RUNTIME_SYMNUM
#include <symbol_enumerator.h>
static int did_runtime_symnum;
@@ -161,6 +165,7 @@ int survive_add_object( SurviveContext * ctx, SurviveObject * obj )
ctx->objs = realloc( ctx->objs, sizeof( SurviveObject * ) * (oldct+1) );
ctx->objs[oldct] = obj;
ctx->objs_ct = oldct+1;
+ return 0;
}
void survive_add_driver( SurviveContext * ctx, void * payload, DeviceDriverCb poll, DeviceDriverCb close, DeviceDriverMagicCb magic )
@@ -184,7 +189,8 @@ int survive_send_magic( SurviveContext * ctx, int magic_code, void * data, int d
for( i = 0; i < oldct; i++ )
{
ctx->drivermagics[i]( ctx, ctx->drivers[i], magic_code, data, datalen );
- }
+ }
+ return 0;
}
void survive_close( SurviveContext * ctx )
diff --git a/src/survive_cal.c b/src/survive_cal.c
index 985ab24..0eb9446 100755
--- a/src/survive_cal.c
+++ b/src/survive_cal.c
@@ -18,6 +18,10 @@
#include "survive_config.h"
+#ifdef WINDOWS
+int mkdir(const char *);
+#endif
+
#define PTS_BEFORE_COMMON 32
#define NEEDED_COMMON_POINTS 10
#define MIN_SENSORS_VISIBLE_PER_LH_FOR_CAL 4
@@ -455,7 +459,7 @@ static void handle_calibration( struct SurviveCalData *cd )
stddevang += Sdiff2;
stddevlen += Ldiff2;
- int llm = Sdiff / HISTOGRAMBINANG + (HISTOGRAMSIZE/2.0);
+ int llm = (int)( Sdiff / HISTOGRAMBINANG + (HISTOGRAMSIZE/2.0) );
if( llm < 0 ) llm = 0;
if( llm >= HISTOGRAMSIZE ) llm = HISTOGRAMSIZE-1;
diff --git a/src/survive_config.c b/src/survive_config.c
index 07b9326..0810280 100644
--- a/src/survive_config.c
+++ b/src/survive_config.c
@@ -3,7 +3,7 @@
#include <assert.h>
#include "survive_config.h"
#include <json_helpers.h>
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__APPLE__)
#include <stdlib.h>
#else
#include <malloc.h> //for alloca
@@ -33,7 +33,7 @@ void destroy_config_entry(config_entry* ce) {
if (ce->data!=NULL) { free(ce->data); ce->data=NULL; }
}
-void init_config_group(config_group *cg, uint16_t count) {
+void init_config_group(config_group *cg, uint8_t count) {
uint16_t i = 0;
cg->used_entries = 0;
cg->max_entries = count;
@@ -99,7 +99,7 @@ void config_set_lighthouse(config_group* lh_config, BaseStationData* bsd, uint8_
}
void sstrcpy(char** dest, const char *src) {
- uint32_t len = strlen(src)+1;
+ uint32_t len = (uint32_t)strlen(src)+1;
assert(dest!=NULL);
char* ptr = (char*)realloc(*dest, len); //acts like malloc if dest==NULL
@@ -143,7 +143,7 @@ FLT config_read_float(config_group *cg, const char *tag, const FLT def) {
return config_set_float(cg, tag, def);
}
-uint16_t config_read_float_array(config_group *cg, const char *tag, const FLT** values, const FLT* def, uint16_t count) {
+uint16_t config_read_float_array(config_group *cg, const char *tag, const FLT** values, const FLT* def, uint8_t count) {
config_entry *cv = find_config_entry(cg, tag);
if (cv != NULL) {
@@ -237,7 +237,7 @@ void write_config_group(FILE* f, config_group *cg, char *tag) {
for (i=0;i < cg->used_entries;++i) {
if (cg->config_entries[i].type == CONFIG_FLOAT) {
- json_write_float(f, cg->config_entries[i].tag, cg->config_entries[i].numeric.f);
+ json_write_float(f, cg->config_entries[i].tag, (float)cg->config_entries[i].numeric.f);
} else if (cg->config_entries[i].type == CONFIG_UINT32) {
json_write_uint32(f, cg->config_entries[i].tag, cg->config_entries[i].numeric.i);
} else if (cg->config_entries[i].type == CONFIG_STRING) {
@@ -295,7 +295,7 @@ void pop_config_group() {
}
-int parse_floats(char* tag, char** values, uint16_t count) {
+int parse_floats(char* tag, char** values, uint8_t count) {
uint16_t i = 0;
FLT *f;
f = alloca(sizeof(FLT) * count);
@@ -348,12 +348,12 @@ int parse_uint32(char* tag, char** values, uint16_t count) {
// if (count>1)
// config_set_uint32_array(cg, tag, f, count);
// else
- config_set_uint32(cg, tag, l[0]);
+ config_set_uint32(cg, tag, (uint32_t)l[0]);
return 1;
}
-void handle_tag_value(char* tag, char** values, uint16_t count) {
+void handle_tag_value(char* tag, char** values, uint8_t count) {
print_json_value(tag,values,count);
config_group* cg = cg_stack[cg_stack_head];
diff --git a/src/survive_config.h b/src/survive_config.h
index c8c7762..83db624 100644
--- a/src/survive_config.h
+++ b/src/survive_config.h
@@ -35,7 +35,7 @@ typedef struct config_group {
//extern config_group global_config_values;
//extern config_group lh_config[2]; //lighthouse configs
-void init_config_group(config_group *cg, uint16_t count);
+void init_config_group(config_group *cg, uint8_t count);
void destroy_config_group(config_group* cg);
//void config_init();
@@ -52,7 +52,7 @@ const uint32_t config_set_uint32(config_group *cg, const char *tag, const uint32
const char* config_set_str(config_group *cg, const char *tag, const char* value);
FLT config_read_float(config_group *cg, const char *tag, const FLT def);
-uint16_t config_read_float_array(config_group *cg, const char *tag, const FLT** values, const FLT* def, uint16_t count);
+uint16_t config_read_float_array(config_group *cg, const char *tag, const FLT** values, const FLT* def, uint8_t count);
uint32_t config_read_uint32(config_group *cg, const char *tag, const uint32_t def);
const char* config_read_str(config_group *cg, const char *tag, const char *def);
diff --git a/src/survive_data.c b/src/survive_data.c
index 60849e2..b9099ac 100644
--- a/src/survive_data.c
+++ b/src/survive_data.c
@@ -39,12 +39,13 @@ void handle_lightcap( SurviveObject * so, LightcapElement * le )
// return; //if we don't know what lighthouse this is we don't care to do much else
}
+ printf("m sync %d %d %d %d\n", le->sensor_id, so->last_sync_time[ssn], le->timestamp, delta);
if( le->length > so->pulselength_min_sync ) //Pulse longer indicates a sync pulse.
{
int is_new_pulse = delta > so->pulselength_min_sync /*1500*/ + last_sync_length;
- printf("m sync %d %d %d %d\n", le->sensor_id, so->last_sync_time[ssn], le->timestamp, delta);
+ //printf("m sync %d %d %d %d\n", le->sensor_id, so->last_sync_time[ssn], le->timestamp, delta);
so->did_handle_ootx = 0;
diff --git a/src/survive_driverman.c b/src/survive_driverman.c
index d694e64..2afaf65 100644
--- a/src/survive_driverman.c
+++ b/src/survive_driverman.c
@@ -31,7 +31,7 @@ void * GetDriver( const char * element )
const char * GetDriverNameMatching( const char * prefix, int place )
{
int i;
- int prefixlen = strlen( prefix );
+ int prefixlen = (int)strlen( prefix );
for( i = 0; i < NrDrivers; i++ )
{
diff --git a/src/survive_vive.c b/src/survive_vive.c
index d4a853d..a9b295f 100755
--- a/src/survive_vive.c
+++ b/src/survive_vive.c
@@ -18,7 +18,7 @@
#include <string.h>
#include <sys/stat.h>
#include <os_generic.h>
-#ifndef __FreeBSD__
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
#include <malloc.h> // for alloca
#endif
@@ -625,6 +625,7 @@ int survive_vive_usb_poll( struct SurviveContext * ctx, void * v )
}
return r;
#endif
+ return 0;
}
@@ -1113,9 +1114,12 @@ void survive_data_cb( SurviveUSBInterface * si )
}
case USB_IF_W_WATCHMAN1_LIGHTCAP:
{
- int i;
+ int i=0;
for( i = 0; i < 7; i++ )
{
+ unsigned short *sensorId = (unsigned short *)readdata;
+ unsigned short *length = (unsigned short *)(&(readdata[2]));
+ unsigned long *time = (unsigned long *)(&(readdata[4]));
LightcapElement le;
le.sensor_id = POP2;
le.length = POP2;
@@ -1282,7 +1286,6 @@ int survive_vive_close( SurviveContext * ctx, void * driver )
SurviveViveData * sv = driver;
survive_vive_usb_close( sv );
-
return 0;
}
diff --git a/test.c b/test.c
index e34a7a8..4909d50 100755
--- a/test.c
+++ b/test.c
@@ -7,10 +7,35 @@
#include <survive.h>
#include <os_generic.h>
-#include <DrawFunctions.h>
+#include <CNFGFunctions.h>
struct SurviveContext * ctx;
+void HandleKey( int keycode, int bDown )
+{
+ if( !bDown ) return;
+
+ if( keycode == 'O' || keycode == 'o' )
+ {
+ survive_send_magic(ctx,1,0,0);
+ }
+ if( keycode == 'F' || keycode == 'f' )
+ {
+ survive_send_magic(ctx,0,0,0);
+ }
+}
+
+void HandleButton( int x, int y, int button, int bDown )
+{
+}
+
+void HandleMotion( int x, int y, int mask )
+{
+}
+
+void HandleDestroy()
+{
+}
static void dump_iface( struct SurviveObject * so, const char * prefix )
diff --git a/windows/build_tcc.bat b/winbuild/build_tcc.bat
index 753ba7c..5be1361 100644
--- a/windows/build_tcc.bat
+++ b/winbuild/build_tcc.bat
@@ -7,8 +7,8 @@ set SR=..\src\
set RD=..\redist\
set SOURCES=%SR%ootx_decoder.c %SR%poser_charlesslow.c %SR%poser_daveortho.c %SR%poser_dummy.c %SR%survive.c %SR%survive_cal.c %SR%survive_config.c %SR%survive_data.c %SR%survive_driverman.c %SR%survive_process.c %SR%survive_vive.c
set REDIST=%RD%crc32.c %RD%linmath.c %RD%puff.c %RD%jsmn.c %RD%json_helpers.c %RD%symbol_enumerator.c
-set EXEC=..\calibrate.c %RD%WinDriver.c %RD%os_generic.c %RD%DrawFunctions.c
+set EXEC=..\calibrate.c %RD%CNFGWinDriver.c %RD%os_generic.c %RD%CNFGFunctions.c
set CFLAGS=-DNOZLIB -DTCC -DWINDOWS -DHIDAPI -DWIN32 -DRUNTIME_SYMNUM -O0 -g -rdynamic -I..\redist -I..\include\libsurvive -I..\src -I.
set LDFLAGS=-lkernel32 -lgdi32 -luser32 -lsetupapi -ldbghelp
@echo on
-%TCC% -v %CFLAGS% %SOURCES% %REDIST% %EXEC% %LDFLAGS% tcc_stubs.c hid.c -o calibrate.exe
+%TCC% -v %CFLAGS% %SOURCES% %REDIST% %EXEC% %LDFLAGS% tcc_stubs.c %RD%hid-windows.c -o calibrate.exe
diff --git a/winbuild/calibrate/calibrate.vcxproj b/winbuild/calibrate/calibrate.vcxproj
index 13fce78..7a62c14 100644
--- a/winbuild/calibrate/calibrate.vcxproj
+++ b/winbuild/calibrate/calibrate.vcxproj
@@ -30,27 +30,27 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
+ <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
+ <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
+ <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
+ <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -96,7 +96,12 @@
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>setupapi.lib;dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <LinkTimeCodeGeneration>UseFastLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
+ <ProjectReference>
+ <UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
+ </ProjectReference>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@@ -114,7 +119,12 @@
<AdditionalDependencies>setupapi.lib;dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ForceSymbolReferences>
</ForceSymbolReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <LinkTimeCodeGeneration>UseFastLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
+ <ProjectReference>
+ <UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
+ </ProjectReference>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@@ -134,7 +144,11 @@
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>setupapi.lib;dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
+ <ProjectReference>
+ <UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
+ </ProjectReference>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@@ -154,7 +168,11 @@
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>setupapi.lib;dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
+ <ProjectReference>
+ <UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
+ </ProjectReference>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\calibrate.c" />
diff --git a/winbuild/libsurvive/libsurvive.vcxproj b/winbuild/libsurvive/libsurvive.vcxproj
index dc23907..643cff5 100644
--- a/winbuild/libsurvive/libsurvive.vcxproj
+++ b/winbuild/libsurvive/libsurvive.vcxproj
@@ -30,27 +30,27 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
+ <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
+ <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
+ <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
+ <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -77,12 +77,13 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>USE_DOUBLE;MANUAL_REGISTRATION;RUNTIME_SYMNUMX;NOZLIB;_CRT_SECURE_NO_WARNINGS;HIDAPI;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\windows;..\..\include\libsurvive;..\..\redist;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>USE_DOUBLE;RUNTIME_SYMNUM;RUNTIME_SYMNUMX;NOZLIB;_CRT_SECURE_NO_WARNINGS;HIDAPI;WINDOWS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\winbuild;..\..\include\libsurvive;..\..\redist;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
+ <ProjectReference />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@@ -90,12 +91,13 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>USE_DOUBLE;MANUAL_REGISTRATION;RUNTIME_SYMNUMX;NOZLIB;_CRT_SECURE_NO_WARNINGS;HIDAPI;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\windows;..\..\include\libsurvive;..\..\redist;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>USE_DOUBLE;RUNTIME_SYMNUM;RUNTIME_SYMNUMX;NOZLIB;_CRT_SECURE_NO_WARNINGS;HIDAPI;WINDOWS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\winbuild;..\..\include\libsurvive;..\..\redist;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
+ <ProjectReference />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@@ -105,14 +107,15 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>USE_DOUBLE;MANUAL_REGISTRATION;RUNTIME_SYMNUMX;NOZLIB;_CRT_SECURE_NO_WARNINGS;HIDAPI;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\windows;..\..\include\libsurvive;..\..\redist;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>USE_DOUBLE;RUNTIME_SYMNUM;RUNTIME_SYMNUMX;NOZLIB;_CRT_SECURE_NO_WARNINGS;HIDAPI;WINDOWS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\winbuild;..\..\include\libsurvive;..\..\redist;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
+ <ProjectReference />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@@ -122,28 +125,30 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>USE_DOUBLE;MANUAL_REGISTRATION;RUNTIME_SYMNUMX;NOZLIB;_CRT_SECURE_NO_WARNINGS;HIDAPI;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\windows;..\..\include\libsurvive;..\..\redist;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>USE_DOUBLE;RUNTIME_SYMNUM;RUNTIME_SYMNUMX;NOZLIB;_CRT_SECURE_NO_WARNINGS;HIDAPI;WINDOWS;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\winbuild;..\..\include\libsurvive;..\..\redist;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
+ <ProjectReference />
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="..\..\redist\CNFGFunctions.c" />
+ <ClCompile Include="..\..\redist\CNFGWinDriver.c" />
<ClCompile Include="..\..\redist\crc32.c" />
- <ClCompile Include="..\..\redist\DrawFunctions.c" />
+ <ClCompile Include="..\..\redist\hid-windows.c" />
<ClCompile Include="..\..\redist\jsmn.c" />
<ClCompile Include="..\..\redist\json_helpers.c" />
<ClCompile Include="..\..\redist\linmath.c" />
<ClCompile Include="..\..\redist\os_generic.c" />
<ClCompile Include="..\..\redist\puff.c" />
<ClCompile Include="..\..\redist\symbol_enumerator.c" />
- <ClCompile Include="..\..\redist\WinDriver.c" />
<ClCompile Include="..\..\src\ootx_decoder.c" />
<ClCompile Include="..\..\src\poser_charlesslow.c" />
<ClCompile Include="..\..\src\poser_daveortho.c" />
@@ -156,14 +161,13 @@
<ClCompile Include="..\..\src\survive_process.c" />
<ClCompile Include="..\..\src\survive_usb.c" />
<ClCompile Include="..\..\src\survive_vive.c" />
- <ClCompile Include="..\..\windows\hid.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\libsurvive\poser.h" />
<ClInclude Include="..\..\include\libsurvive\survive.h" />
<ClInclude Include="..\..\include\libsurvive\survive_types.h" />
+ <ClInclude Include="..\..\redist\CNFGFunctions.h" />
<ClInclude Include="..\..\redist\crc32.h" />
- <ClInclude Include="..\..\redist\DrawFunctions.h" />
<ClInclude Include="..\..\redist\jsmn.h" />
<ClInclude Include="..\..\redist\json_helpers.h" />
<ClInclude Include="..\..\redist\linmath.h" />
@@ -173,7 +177,7 @@
<ClInclude Include="..\..\src\survive_cal.h" />
<ClInclude Include="..\..\src\survive_config.h" />
<ClInclude Include="..\..\src\survive_internal.h" />
- <ClInclude Include="..\..\windows\hidapi.h" />
+ <ClInclude Include="..\hidapi.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/winbuild/libsurvive/libsurvive.vcxproj.filters b/winbuild/libsurvive/libsurvive.vcxproj.filters
index 370ce14..0bb9d1b 100644
--- a/winbuild/libsurvive/libsurvive.vcxproj.filters
+++ b/winbuild/libsurvive/libsurvive.vcxproj.filters
@@ -60,12 +60,6 @@
<ClCompile Include="..\..\redist\puff.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\redist\DrawFunctions.c">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\redist\WinDriver.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\redist\json_helpers.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -78,10 +72,16 @@
<ClCompile Include="..\..\redist\symbol_enumerator.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\windows\hid.c">
+ <ClCompile Include="..\..\redist\linmath.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\redist\linmath.c">
+ <ClCompile Include="..\..\redist\hid-windows.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\redist\CNFGFunctions.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\redist\CNFGWinDriver.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@@ -110,9 +110,6 @@
<ClInclude Include="..\..\redist\os_generic.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\redist\DrawFunctions.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="..\..\redist\json_helpers.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -125,10 +122,13 @@
<ClInclude Include="..\..\redist\symbol_enumerator.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\windows\hidapi.h">
+ <ClInclude Include="..\..\redist\linmath.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\redist\linmath.h">
+ <ClInclude Include="..\hidapi.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\redist\CNFGFunctions.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
diff --git a/windows/tcc_stubs.c b/winbuild/tcc_stubs.c
index 7872914..7872914 100644
--- a/windows/tcc_stubs.c
+++ b/winbuild/tcc_stubs.c
diff --git a/windows/custom_msvcrt.def b/windows/custom_msvcrt.def
deleted file mode 100644
index f40884e..0000000
--- a/windows/custom_msvcrt.def
+++ /dev/null
@@ -1,1400 +0,0 @@
-LIBRARY msvcrt.dll
-
-EXPORTS
-$I10_OUTPUT
-??0__non_rtti_object@@QAE@ABV0@@Z
-??0__non_rtti_object@@QAE@PBD@Z
-??0bad_cast@@AAE@PBQBD@Z
-??0bad_cast@@QAE@ABQBD@Z
-??0bad_cast@@QAE@ABV0@@Z
-??0bad_cast@@QAE@PBD@Z
-??0bad_typeid@@QAE@ABV0@@Z
-??0bad_typeid@@QAE@PBD@Z
-??0exception@@QAE@ABQBD@Z
-??0exception@@QAE@ABQBDH@Z
-??0exception@@QAE@ABV0@@Z
-??0exception@@QAE@XZ
-??1__non_rtti_object@@UAE@XZ
-??1bad_cast@@UAE@XZ
-??1bad_typeid@@UAE@XZ
-??1exception@@UAE@XZ
-??1type_info@@UAE@XZ
-??2@YAPAXI@Z
-??2@YAPAXIHPBDH@Z
-??3@YAXPAX@Z
-??4__non_rtti_object@@QAEAAV0@ABV0@@Z
-??4bad_cast@@QAEAAV0@ABV0@@Z
-??4bad_typeid@@QAEAAV0@ABV0@@Z
-??4exception@@QAEAAV0@ABV0@@Z
-??8type_info@@QBEHABV0@@Z
-??9type_info@@QBEHABV0@@Z
-??_7__non_rtti_object@@6B@
-??_7bad_cast@@6B@
-??_7bad_typeid@@6B@
-??_7exception@@6B@
-??_E__non_rtti_object@@UAEPAXI@Z
-??_Ebad_cast@@UAEPAXI@Z
-??_Ebad_typeid@@UAEPAXI@Z
-??_Eexception@@UAEPAXI@Z
-??_Fbad_cast@@QAEXXZ
-??_Fbad_typeid@@QAEXXZ
-??_G__non_rtti_object@@UAEPAXI@Z
-??_Gbad_cast@@UAEPAXI@Z
-??_Gbad_typeid@@UAEPAXI@Z
-??_Gexception@@UAEPAXI@Z
-??_U@YAPAXI@Z
-??_U@YAPAXIHPBDH@Z
-??_V@YAXPAX@Z
-?_query_new_handler@@YAP6AHI@ZXZ
-?_query_new_mode@@YAHXZ
-?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z
-?_set_new_mode@@YAHH@Z
-?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
-?before@type_info@@QBEHABV1@@Z
-?name@type_info@@QBEPBDXZ
-?raw_name@type_info@@QBEPBDXZ
-?set_new_handler@@YAP6AXXZP6AXXZ@Z
-?set_terminate@@YAP6AXXZP6AXXZ@Z
-?set_unexpected@@YAP6AXXZP6AXXZ@Z
-?terminate@@YAXXZ
-?unexpected@@YAXXZ
-?what@exception@@UBEPBDXZ
-_CIacos
-_CIasin
-_CIatan
-_CIatan2
-_CIcos
-_CIcosh
-_CIexp
-_CIfmod
-_CIlog
-_CIlog10
-_CIpow
-_CIsin
-_CIsinh
-_CIsqrt
-_CItan
-_CItanh
-_CrtCheckMemory
-_CrtDbgBreak
-_CrtDbgReport
-_CrtDbgReportV
-_CrtDbgReportW
-_CrtDbgReportWV
-_CrtDoForAllClientObjects
-_CrtDumpMemoryLeaks
-_CrtIsMemoryBlock
-_CrtIsValidHeapPointer
-_CrtIsValidPointer
-_CrtMemCheckpoint
-_CrtMemDifference
-_CrtMemDumpAllObjectsSince
-_CrtMemDumpStatistics
-_CrtReportBlockType
-_CrtSetAllocHook
-_CrtSetBreakAlloc
-_CrtSetDbgBlockType
-_CrtSetDbgFlag
-_CrtSetDumpClient
-_CrtSetReportFile
-_CrtSetReportHook
-_CrtSetReportHook2
-_CrtSetReportMode
-_CxxThrowException
-_EH_prolog
-_Getdays
-_Getmonths
-_Gettnames
-_HUGE
-_Strftime
-_XcptFilter
-__CppXcptFilter
-__CxxCallUnwindDelDtor
-__CxxCallUnwindDtor
-__CxxCallUnwindVecDtor
-__CxxDetectRethrow
-__CxxExceptionFilter
-__CxxFrameHandler
-__CxxFrameHandler2
-__CxxFrameHandler3
-__CxxLongjmpUnwind
-__CxxQueryExceptionSize
-__CxxRegisterExceptionObject
-__CxxUnregisterExceptionObject
-__DestructExceptionObject
-__RTCastToVoid
-__RTDynamicCast
-__RTtypeid
-__STRINGTOLD
-___lc_codepage_func
-___lc_collate_cp_func
-___lc_handle_func
-___mb_cur_max_func
-___setlc_active_func
-___unguarded_readlc_active_add_func
-__argc
-__argv
-__badioinfo
-__crtCompareStringA
-__crtCompareStringW
-__crtGetLocaleInfoW
-__crtGetStringTypeW
-__crtLCMapStringA
-__crtLCMapStringW
-__daylight
-__dllonexit
-__doserrno
-__dstbias
-__fpecode
-__getmainargs
-__initenv
-__iob_func
-__isascii
-__iscsym
-__iscsymf
-__lc_codepage
-__lc_collate_cp
-__lc_handle
-__lconv_init
-__libm_sse2_acos
-__libm_sse2_acosf
-__libm_sse2_asin
-__libm_sse2_asinf
-__libm_sse2_atan
-__libm_sse2_atan2
-__libm_sse2_atanf
-__libm_sse2_cos
-__libm_sse2_cosf
-__libm_sse2_exp
-__libm_sse2_expf
-__libm_sse2_log
-__libm_sse2_log10
-__libm_sse2_log10f
-__libm_sse2_logf
-__libm_sse2_pow
-__libm_sse2_powf
-__libm_sse2_sin
-__libm_sse2_sinf
-__libm_sse2_tan
-__libm_sse2_tanf
-__mb_cur_max
-__p___argc
-__p___argv
-__p___initenv
-__p___mb_cur_max
-__p___wargv
-__p___winitenv
-__p__acmdln
-__p__amblksiz
-__p__commode
-__p__daylight
-__p__dstbias
-__p__environ
-__p__fileinfo
-__p__fmode
-__p__iob
-__p__mbcasemap
-__p__mbctype
-__p__osver
-__p__pctype
-__p__pgmptr
-__p__pwctype
-__p__timezone
-__p__tzname
-__p__wcmdln
-__p__wenviron
-__p__winmajor
-__p__winminor
-__p__winver
-__p__wpgmptr
-__pctype_func
-__pioinfo
-__pwctype_func
-__pxcptinfoptrs
-__set_app_type
-__setlc_active
-__setusermatherr
-__strncnt
-__threadhandle
-__threadid
-__toascii
-__unDName
-__unDNameEx
-__uncaught_exception
-__unguarded_readlc_active
-__wargv
-__wcserror
-__wcserror_s
-__wcsncnt
-__wgetmainargs
-__winitenv
-_abnormal_termination
-_abs64
-_access
-_access_s
-_acmdln
-_adj_fdiv_m16i
-_adj_fdiv_m32
-_adj_fdiv_m32i
-_adj_fdiv_m64
-_adj_fdiv_r
-_adj_fdivr_m16i
-_adj_fdivr_m32
-_adj_fdivr_m32i
-_adj_fdivr_m64
-_adj_fpatan
-_adj_fprem
-_adj_fprem1
-_adj_fptan
-_adjust_fdiv
-_aexit_rtn
-_aligned_free
-_aligned_free_dbg
-_aligned_malloc
-_aligned_malloc_dbg
-_aligned_offset_malloc
-_aligned_offset_malloc_dbg
-_aligned_offset_realloc
-_aligned_offset_realloc_dbg
-_aligned_realloc
-_aligned_realloc_dbg
-_amsg_exit
-_assert
-_atodbl
-_atodbl_l
-_atof_l
-_atoflt_l
-_atoi64
-_atoi64_l
-_atoi_l
-_atol_l
-_atoldbl
-_atoldbl_l
-_beep
-_beginthread
-_beginthreadex
-_c_exit
-_cabs
-_callnewh
-_calloc_dbg
-_cexit
-_cgets
-_cgets_s
-_cgetws
-_cgetws_s
-_chdir
-_chdrive
-_chgsign
-_chkesp
-_chmod
-_chsize
-_chsize_s
-_chvalidator
-_chvalidator_l
-_clearfp
-_close
-_commit
-_commode
-_control87
-_controlfp
-_controlfp_s
-_copysign
-_cprintf
-_cprintf_l
-_cprintf_p
-_cprintf_p_l
-_cprintf_s
-_cprintf_s_l
-_cputs
-_cputws
-_creat
-_crtAssertBusy
-_crtBreakAlloc
-_crtDbgFlag
-_cscanf
-_cscanf_l
-_cscanf_s
-_cscanf_s_l
-_ctime32
-_ctime32_s
-_ctime64
-_ctime64_s
-_ctype
-_cwait
-_cwprintf
-_cwprintf_l
-_cwprintf_p
-_cwprintf_p_l
-_cwprintf_s
-_cwprintf_s_l
-_cwscanf
-_cwscanf_l
-_cwscanf_s
-_cwscanf_s_l
-_daylight
-_difftime32
-_difftime64
-_dstbias
-_dup
-_dup2
-_ecvt
-_ecvt_s
-_endthread
-_endthreadex
-_environ
-_eof
-_errno
-_except_handler2
-_except_handler3
-_except_handler4_common
-_execl
-_execle
-_execlp
-_execlpe
-_execv
-_execve
-_execvp
-_execvpe
-_exit
-_expand
-_expand_dbg
-_fcloseall
-_fcvt
-_fcvt_s
-_fdopen
-_fgetchar
-_fgetwchar
-_filbuf
-_fileinfo
-_filelength
-_filelengthi64
-_fileno
-_findclose
-_findfirst
-_findfirst64
-_findfirsti64
-_findnext
-_findnext64
-_findnexti64
-_finite
-_flsbuf
-_flushall
-_fmode
-_fpclass
-_fpieee_flt
-_fpreset
-_fprintf_l
-_fprintf_p
-_fprintf_p_l
-_fprintf_s_l
-_fputchar
-_fputwchar
-_free_dbg
-_freea
-_freea_s
-_fscanf_l
-_fscanf_s_l
-_fseeki64
-_fsopen
-_fstat
-_fstat64
-_fstati64
-_ftime
-_ftime32
-_ftime32_s
-_ftime64
-_ftime64_s
-_ftol
-_ftol2
-_ftol2_sse
-_ftol2_sse_excpt
-_fullpath
-_fullpath_dbg
-_futime
-_futime32
-_futime64
-_fwprintf_l
-_fwprintf_p
-_fwprintf_p_l
-_fwprintf_s_l
-_fwscanf_l
-_fwscanf_s_l
-_gcvt
-_gcvt_s
-_get_doserrno
-_get_environ
-_get_errno
-_get_fileinfo
-_get_fmode
-_get_heap_handle
-_get_osfhandle
-_get_osplatform
-_get_osver
-_get_output_format
-_get_pgmptr
-_get_sbh_threshold
-_get_wenviron
-_get_winmajor
-_get_winminor
-_get_winver
-_get_wpgmptr
-_getch
-_getche
-_getcwd
-_getdcwd
-_getdiskfree
-_getdllprocaddr
-_getdrive
-_getdrives
-_getmaxstdio
-_getmbcp
-_getpid
-_getsystime
-_getw
-_getwch
-_getwche
-_getws
-_global_unwind2
-_gmtime32
-_gmtime32_s
-_gmtime64
-_gmtime64_s
-_heapadd
-_heapchk
-_heapmin
-_heapset
-_heapused
-_heapwalk
-_hypot
-_i64toa
-_i64toa_s
-_i64tow
-_i64tow_s
-_initterm
-_initterm_e
-_inp
-_inpd
-_inpw
-_invalid_parameter
-_iob
-_isalnum_l
-_isalpha_l
-_isatty
-_iscntrl_l
-_isctype
-_isctype_l
-_isdigit_l
-_isgraph_l
-_isleadbyte_l
-_islower_l
-_ismbbalnum
-_ismbbalnum_l
-_ismbbalpha
-_ismbbalpha_l
-_ismbbgraph
-_ismbbgraph_l
-_ismbbkalnum
-_ismbbkalnum_l
-_ismbbkana
-_ismbbkana_l
-_ismbbkprint
-_ismbbkprint_l
-_ismbbkpunct
-_ismbbkpunct_l
-_ismbblead
-_ismbblead_l
-_ismbbprint
-_ismbbprint_l
-_ismbbpunct
-_ismbbpunct_l
-_ismbbtrail
-_ismbbtrail_l
-_ismbcalnum
-_ismbcalnum_l
-_ismbcalpha
-_ismbcalpha_l
-_ismbcdigit
-_ismbcdigit_l
-_ismbcgraph
-_ismbcgraph_l
-_ismbchira
-_ismbchira_l
-_ismbckata
-_ismbckata_l
-_ismbcl0
-_ismbcl0_l
-_ismbcl1
-_ismbcl1_l
-_ismbcl2
-_ismbcl2_l
-_ismbclegal
-_ismbclegal_l
-_ismbclower
-_ismbclower_l
-_ismbcprint
-_ismbcprint_l
-_ismbcpunct
-_ismbcpunct_l
-_ismbcspace
-_ismbcspace_l
-_ismbcsymbol
-_ismbcsymbol_l
-_ismbcupper
-_ismbcupper_l
-_ismbslead
-_ismbslead_l
-_ismbstrail
-_ismbstrail_l
-_isnan
-_isprint_l
-_isspace_l
-_isupper_l
-_iswalnum_l
-_iswalpha_l
-_iswcntrl_l
-_iswctype_l
-_iswdigit_l
-_iswgraph_l
-_iswlower_l
-_iswprint_l
-_iswpunct_l
-_iswspace_l
-_iswupper_l
-_iswxdigit_l
-_isxdigit_l
-_itoa
-_itoa_s
-_itow
-_itow_s
-_j0
-_j1
-_jn
-_kbhit
-_lfind
-_lfind_s
-_loaddll
-_local_unwind2
-_local_unwind4
-_localtime32
-_localtime32_s
-_localtime64
-_localtime64_s
-_lock
-_locking
-_logb
-_longjmpex
-_lrotl
-_lrotr
-_lsearch
-_lsearch_s
-_lseek
-_lseeki64
-_ltoa
-_ltoa_s
-_ltow
-_ltow_s
-_makepath
-_makepath_s
-_malloc_dbg
-_mbbtombc
-_mbbtombc_l
-_mbbtype
-_mbcasemap
-_mbccpy
-_mbccpy_l
-_mbccpy_s
-_mbccpy_s_l
-_mbcjistojms
-_mbcjistojms_l
-_mbcjmstojis
-_mbcjmstojis_l
-_mbclen
-_mbclen_l
-_mbctohira
-_mbctohira_l
-_mbctokata
-_mbctokata_l
-_mbctolower
-_mbctolower_l
-_mbctombb
-_mbctombb_l
-_mbctoupper
-_mbctoupper_l
-_mbctype
-_mblen_l
-_mbsbtype
-_mbsbtype_l
-_mbscat
-_mbscat_s
-_mbscat_s_l
-_mbschr
-_mbschr_l
-_mbscmp
-_mbscmp_l
-_mbscoll
-_mbscoll_l
-_mbscpy
-_mbscpy_s
-_mbscpy_s_l
-_mbscspn
-_mbscspn_l
-_mbsdec
-_mbsdec_l
-_mbsdup
-_mbsicmp
-_mbsicmp_l
-_mbsicoll
-_mbsicoll_l
-_mbsinc
-_mbsinc_l
-_mbslen
-_mbslen_l
-_mbslwr
-_mbslwr_l
-_mbslwr_s
-_mbslwr_s_l
-_mbsnbcat
-_mbsnbcat_l
-_mbsnbcat_s
-_mbsnbcat_s_l
-_mbsnbcmp
-_mbsnbcmp_l
-_mbsnbcnt
-_mbsnbcnt_l
-_mbsnbcoll
-_mbsnbcoll_l
-_mbsnbcpy
-_mbsnbcpy_l
-_mbsnbcpy_s
-_mbsnbcpy_s_l
-_mbsnbicmp
-_mbsnbicmp_l
-_mbsnbicoll
-_mbsnbicoll_l
-_mbsnbset
-_mbsnbset_l
-_mbsnbset_s
-_mbsnbset_s_l
-_mbsncat
-_mbsncat_l
-_mbsncat_s
-_mbsncat_s_l
-_mbsnccnt
-_mbsnccnt_l
-_mbsncmp
-_mbsncmp_l
-_mbsncoll
-_mbsncoll_l
-_mbsncpy
-_mbsncpy_l
-_mbsncpy_s
-_mbsncpy_s_l
-_mbsnextc
-_mbsnextc_l
-_mbsnicmp
-_mbsnicmp_l
-_mbsnicoll
-_mbsnicoll_l
-_mbsninc
-_mbsninc_l
-_mbsnlen
-_mbsnlen_l
-_mbsnset
-_mbsnset_l
-_mbsnset_s
-_mbsnset_s_l
-_mbspbrk
-_mbspbrk_l
-_mbsrchr
-_mbsrchr_l
-_mbsrev
-_mbsrev_l
-_mbsset
-_mbsset_l
-_mbsset_s
-_mbsset_s_l
-_mbsspn
-_mbsspn_l
-_mbsspnp
-_mbsspnp_l
-_mbsstr
-_mbsstr_l
-_mbstok
-_mbstok_l
-_mbstok_s
-_mbstok_s_l
-_mbstowcs_l
-_mbstowcs_s_l
-_mbstrlen
-_mbstrlen_l
-_mbstrnlen
-_mbstrnlen_l
-_mbsupr
-_mbsupr_l
-_mbsupr_s
-_mbsupr_s_l
-_mbtowc_l
-_memccpy
-_memicmp
-_memicmp_l
-_mkdir
-_mkgmtime
-_mkgmtime32
-_mkgmtime64
-_mktemp
-_mktemp_s
-_mktime32
-_mktime64
-_msize
-_msize_debug
-_nextafter
-_onexit
-_open
-_open_osfhandle
-_osplatform
-_osver
-_outp
-_outpd
-_outpw
-_pclose
-_pctype
-_pgmptr
-_pipe
-_popen
-_printf_l
-_printf_p
-_printf_p_l
-_printf_s_l
-_purecall
-_putch
-_putenv
-_putenv_s
-_putw
-_putwch
-_putws
-_pwctype
-_read
-_realloc_dbg
-_resetstkoflw
-_rmdir
-_rmtmp
-_rotl
-_rotl64
-_rotr
-_rotr64
-_safe_fdiv
-_safe_fdivr
-_safe_fprem
-_safe_fprem1
-_scalb
-_scanf_l
-_scanf_s_l
-_scprintf
-_scprintf_l
-_scprintf_p_l
-_scwprintf
-_scwprintf_l
-_scwprintf_p_l
-_searchenv
-_searchenv_s
-_seh_longjmp_unwind
-_seh_longjmp_unwind4
-_set_SSE2_enable
-_set_controlfp
-_set_doserrno
-_set_errno
-_set_error_mode
-_set_fileinfo
-_set_fmode
-_set_output_format
-_set_sbh_threshold
-_seterrormode
-_setjmp
-_setjmp3
-_setmaxstdio
-_setmbcp
-_setmode
-_setsystime
-_sleep
-_snprintf
-_snprintf_c
-_snprintf_c_l
-_snprintf_l
-_snprintf_s
-_snprintf_s_l
-_snscanf
-_snscanf_l
-_snscanf_s
-_snscanf_s_l
-_snwprintf
-_snwprintf_l
-_snwprintf_s
-_snwprintf_s_l
-_snwscanf
-_snwscanf_l
-_snwscanf_s
-_snwscanf_s_l
-_sopen
-_sopen_s
-_spawnl
-_spawnle
-_spawnlp
-_spawnlpe
-_spawnv
-_spawnve
-_spawnvp
-_spawnvpe
-_splitpath
-_splitpath_s
-_sprintf_l
-_sprintf_p_l
-_sprintf_s_l
-_sscanf_l
-_sscanf_s_l
-_stat
-_stat64
-_stati64
-_statusfp
-_strcmpi
-_strcoll_l
-_strdate
-_strdate_s
-_strdup
-_strdup_dbg
-_strerror
-_strerror_s
-_stricmp
-_stricmp_l
-_stricoll
-_stricoll_l
-_strlwr
-_strlwr_l
-_strlwr_s
-_strlwr_s_l
-_strncoll
-_strncoll_l
-_strnicmp
-_strnicmp_l
-_strnicoll
-_strnicoll_l
-_strnset
-_strnset_s
-_strrev
-_strset
-_strset_s
-_strtime
-_strtime_s
-_strtod_l
-_strtoi64
-_strtoi64_l
-_strtol_l
-_strtoui64
-_strtoui64_l
-_strtoul_l
-_strupr
-_strupr_l
-_strupr_s
-_strupr_s_l
-_strxfrm_l
-_swab
-_swprintf
-_swprintf_c
-_swprintf_c_l
-_swprintf_p_l
-_swprintf_s_l
-_swscanf_l
-_swscanf_s_l
-_sys_errlist
-_sys_nerr
-_tell
-_telli64
-_tempnam
-_tempnam_dbg
-_time32
-_time64
-_timezone
-_tolower
-_tolower_l
-_toupper
-_toupper_l
-_towlower_l
-_towupper_l
-_tzname
-_tzset
-_ui64toa
-_ui64toa_s
-_ui64tow
-_ui64tow_s
-_ultoa
-_ultoa_s
-_ultow
-_ultow_s
-_umask
-_umask_s
-_ungetch
-_ungetwch
-_unlink
-_unloaddll
-_unlock
-_utime
-_utime32
-_utime64
-_vcprintf
-_vcprintf_l
-_vcprintf_p
-_vcprintf_p_l
-_vcprintf_s
-_vcprintf_s_l
-_vcwprintf
-_vcwprintf_l
-_vcwprintf_p
-_vcwprintf_p_l
-_vcwprintf_s
-_vcwprintf_s_l
-_vfprintf_l
-_vfprintf_p
-_vfprintf_p_l
-_vfprintf_s_l
-_vfwprintf_l
-_vfwprintf_p
-_vfwprintf_p_l
-_vfwprintf_s_l
-_vprintf_l
-_vprintf_p
-_vprintf_p_l
-_vprintf_s_l
-_vscprintf
-_vscprintf_l
-_vscprintf_p_l
-_vscwprintf
-_vscwprintf_l
-_vscwprintf_p_l
-_vsnprintf
-_vsnprintf_c
-_vsnprintf_c_l
-_vsnprintf_l
-_vsnprintf_s
-_vsnprintf_s_l
-_vsnwprintf
-_vsnwprintf_l
-_vsnwprintf_s
-_vsnwprintf_s_l
-_vsprintf_l
-_vsprintf_p
-_vsprintf_p_l
-_vsprintf_s_l
-_vswprintf
-_vswprintf_c
-_vswprintf_c_l
-_vswprintf_l
-_vswprintf_p_l
-_vswprintf_s_l
-_vwprintf_l
-_vwprintf_p
-_vwprintf_p_l
-_vwprintf_s_l
-_waccess
-_waccess_s
-_wasctime
-_wasctime_s
-_wassert
-_wchdir
-_wchmod
-_wcmdln
-_wcreat
-_wcscoll_l
-_wcsdup
-_wcsdup_dbg
-_wcserror
-_wcserror_s
-_wcsftime_l
-_wcsicmp
-_wcsicmp_l
-_wcsicoll
-_wcsicoll_l
-_wcslwr
-_wcslwr_l
-_wcslwr_s
-_wcslwr_s_l
-_wcsncoll
-_wcsncoll_l
-_wcsnicmp
-_wcsnicmp_l
-_wcsnicoll
-_wcsnicoll_l
-_wcsnset
-_wcsnset_s
-_wcsrev
-_wcsset
-_wcsset_s
-_wcstoi64
-_wcstoi64_l
-_wcstol_l
-_wcstombs_l
-_wcstombs_s_l
-_wcstoui64
-_wcstoui64_l
-_wcstoul_l
-_wcsupr
-_wcsupr_l
-_wcsupr_s
-_wcsupr_s_l
-_wcsxfrm_l
-_wctime
-_wctime32
-_wctime32_s
-_wctime64
-_wctime64_s
-_wctomb_l
-_wctomb_s_l
-_wctype
-_wenviron
-_wexecl
-_wexecle
-_wexeclp
-_wexeclpe
-_wexecv
-_wexecve
-_wexecvp
-_wexecvpe
-_wfdopen
-_wfindfirst
-_wfindfirst64
-_wfindfirsti64
-_wfindnext
-_wfindnext64
-_wfindnexti64
-_wfopen
-_wfopen_s
-_wfreopen
-_wfreopen_s
-_wfsopen
-_wfullpath
-_wfullpath_dbg
-_wgetcwd
-_wgetdcwd
-_wgetenv
-_wgetenv_s
-_winmajor
-_winminor
-_winput_s
-_winver
-_wmakepath
-_wmakepath_s
-_wmkdir
-_wmktemp
-_wmktemp_s
-_wopen
-_woutput_s
-_wperror
-_wpgmptr
-_wpopen
-_wprintf_l
-_wprintf_p
-_wprintf_p_l
-_wprintf_s_l
-_wputenv
-_wputenv_s
-_wremove
-_wrename
-_write
-_wrmdir
-_wscanf_l
-_wscanf_s_l
-_wsearchenv
-_wsearchenv_s
-_wsetlocale
-_wsopen
-_wsopen_s
-_wspawnl
-_wspawnle
-_wspawnlp
-_wspawnlpe
-_wspawnv
-_wspawnve
-_wspawnvp
-_wspawnvpe
-_wsplitpath
-_wsplitpath_s
-_wstat
-_wstat64
-_wstati64
-_wstrdate
-_wstrdate_s
-_wstrtime
-_wstrtime_s
-_wsystem
-_wtempnam
-_wtempnam_dbg
-_wtmpnam
-_wtmpnam_s
-_wtof
-_wtof_l
-_wtoi
-_wtoi64
-_wtoi64_l
-_wtoi_l
-_wtol
-_wtol_l
-_wunlink
-_wutime
-_wutime32
-_wutime64
-_y0
-_y1
-_yn
-abort
-abs
-acos
-asctime
-asctime_s
-asin
-atan
-atan2
-atexit
-atof
-atoi
-atol
-bsearch
-bsearch_s
-btowc
-calloc
-ceil
-clearerr
-clearerr_s
-clock
-cos
-cosh
-ctime
-difftime
-div
-exit
-exp
-fabs
-fclose
-feof
-ferror
-fflush
-fgetc
-fgetpos
-fgets
-fgetwc
-fgetws
-floor
-fmod
-fopen
-fopen_s
-fprintf
-fprintf_s
-fputc
-fputs
-fputwc
-fputws
-fread
-free
-freopen
-freopen_s
-frexp
-fscanf
-fscanf_s
-fseek
-fsetpos
-ftell
-fwprintf
-fwprintf_s
-fwrite
-fwscanf
-fwscanf_s
-getc
-getchar
-getenv
-getenv_s
-gets
-getwc
-getwchar
-gmtime
-is_wctype
-isalnum
-isalpha
-iscntrl
-isdigit
-isgraph
-isleadbyte
-islower
-isprint
-ispunct
-isspace
-isupper
-iswalnum
-iswalpha
-iswascii
-iswcntrl
-iswctype
-iswdigit
-iswgraph
-iswlower
-iswprint
-iswpunct
-iswspace
-iswupper
-iswxdigit
-isxdigit
-labs
-ldexp
-ldiv
-localeconv
-localtime
-log
-log10
-longjmp
-malloc
-mblen
-mbrlen
-mbrtowc
-mbsdup_dbg
-mbsrtowcs
-mbsrtowcs_s
-mbstowcs
-mbstowcs_s
-mbtowc
-memchr
-memcmp
-memcpy
-memcpy_s
-memmove
-memmove_s
-memset
-mktime
-modf
-perror
-pow
-printf
-printf_s
-putc
-putchar
-puts
-putwc
-putwchar
-qsort
-qsort_s
-raise
-rand
-rand_s
-realloc
-remove
-rename
-rewind
-scanf
-scanf_s
-setbuf
-setlocale
-setvbuf
-signal
-sin
-sinh
-sprintf
-sprintf_s
-sqrt
-srand
-sscanf
-sscanf_s
-strcat
-strcat_s
-strchr
-strcmp
-strcoll
-strcpy
-strcpy_s
-strcspn
-strerror
-strerror_s
-strftime
-strlen
-strncat
-strncat_s
-strncmp
-strncpy
-strncpy_s
-strnlen
-strpbrk
-strrchr
-strspn
-strstr
-strtod
-strtok
-strtok_s
-strtol
-strtoul
-strxfrm
-swprintf
-swprintf_s
-swscanf
-swscanf_s
-system
-tan
-tanh
-time
-tmpfile
-tmpfile_s
-tmpnam
-tmpnam_s
-tolower
-toupper
-towlower
-towupper
-ungetc
-ungetwc
-utime
-vfprintf
-vfprintf_s
-vfwprintf
-vfwprintf_s
-vprintf
-vprintf_s
-vsnprintf
-vsprintf
-vsprintf_s
-vswprintf
-vswprintf_s
-vwprintf
-vwprintf_s
-wcrtomb
-wcrtomb_s
-wcscat
-wcscat_s
-wcschr
-wcscmp
-wcscoll
-wcscpy
-wcscpy_s
-wcscspn
-wcsftime
-wcslen
-wcsncat
-wcsncat_s
-wcsncmp
-wcsncpy
-wcsncpy_s
-wcsnlen
-wcspbrk
-wcsrchr
-wcsrtombs
-wcsrtombs_s
-wcsspn
-wcsstr
-wcstod
-wcstok
-wcstok_s
-wcstol
-wcstombs
-wcstombs_s
-wcstoul
-wcsxfrm
-wctob
-wctomb
-wctomb_s
-wprintf
-wprintf_s
-wscanf
-wscanf_s
-vsprintf_s \ No newline at end of file