make ColorChord work on Android.
This commit is contained in:
parent
241733ab9a
commit
79089566a1
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -7,3 +7,6 @@
|
|||
[submodule "colorchord2/cnfa"]
|
||||
path = colorchord2/cnfa
|
||||
url = https://github.com/cnlohr/cnfa
|
||||
[submodule "colorchord2/android/rawdrawandroid"]
|
||||
path = colorchord2/android/rawdrawandroid
|
||||
url = https://github.com/cnlohr/rawdrawandroid
|
||||
|
|
|
@ -31,7 +31,7 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
int i;
|
||||
float cw = ((float)(screenx)) / 2.0;
|
||||
float ch = ((float)(screeny)) / 2.0;
|
||||
RDPoint pts[4];
|
||||
RDPoint pts[6];
|
||||
float sizeA = sqrtf( screenx * screenx + screeny * screeny ) * d->pie_min;
|
||||
float sizeB = sqrtf( screenx * screenx + screeny * screeny ) * d->pie_max;
|
||||
for( i = 0; i < d->leds; i++ )
|
||||
|
@ -44,11 +44,16 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
|||
pts[1].y = ch + sin(angA) * sizeB;
|
||||
pts[2].x = cw + cos(angB) * sizeB;
|
||||
pts[2].y = ch + sin(angB) * sizeB;
|
||||
pts[3].x = cw + cos(angB) * sizeA;
|
||||
pts[3].y = ch + sin(angB) * sizeA;
|
||||
|
||||
pts[3].x = cw + cos(angA) * sizeA;
|
||||
pts[3].y = ch + sin(angA) * sizeA;
|
||||
pts[4].x = cw + cos(angB) * sizeB;
|
||||
pts[4].y = ch + sin(angB) * sizeB;
|
||||
pts[5].x = cw + cos(angB) * sizeA;
|
||||
pts[5].y = ch + sin(angB) * sizeA;
|
||||
|
||||
CNFGColor( OutLEDs[i*3+0] | (OutLEDs[i*3+1] <<8)|(OutLEDs[i*3+2] <<16) );
|
||||
CNFGTackPoly( pts, 4 );
|
||||
CNFGTackPoly( pts, 6 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,13 +14,13 @@ LDLIBS:=-lpthread -lasound -lm -lpulse-simple -lpulse -ludev -lrt
|
|||
CFLAGS:=-g -O1 -flto -Wall -ffast-math -I../embeddedcommon -I. -Icnfa -Irawdraw -DICACHE_FLASH_ATTR=
|
||||
EXTRALIBS:=-lusb-1.0
|
||||
|
||||
OBJS:=os_generic.o main.o dft.o decompose.o filter.o color.o notefinder.o util.o outdrivers.o $(OUTS) parameters.o chash.o hook.o ../embeddedcommon/DFT32.o configs.o
|
||||
OBJS:=main.o dft.o decompose.o filter.o color.o notefinder.o util.o outdrivers.o $(OUTS) parameters.o chash.o hook.o ../embeddedcommon/DFT32.o configs.o
|
||||
|
||||
colorchord : $(OBJS)
|
||||
gcc -o $@ $^ $(CFLAGS) $(LDLIBS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
||||
|
||||
|
||||
colorchord.exe : os_generic.c main.c dft.c decompose.c filter.c color.c notefinder.c util.c outdrivers.c parameters.c chash.c OutputVoronoi.c OutputProminent.c DisplayArray.c OutputLinear.c DisplayPie.c DisplayNetwork.c hook.c RecorderPlugin.c ../embeddedcommon/DFT32.c OutputCells.c configs.c hidapi.c DisplayHIDAPI.c
|
||||
colorchord.exe : main.c dft.c decompose.c filter.c color.c notefinder.c util.c outdrivers.c parameters.c chash.c OutputVoronoi.c OutputProminent.c DisplayArray.c OutputLinear.c DisplayPie.c DisplayNetwork.c hook.c RecorderPlugin.c ../embeddedcommon/DFT32.c OutputCells.c configs.c hidapi.c DisplayHIDAPI.c
|
||||
$(WINGCC) $(WINGCCFLAGS) -o $@ $^ $(WINLDFLAGS)
|
||||
|
||||
|
||||
|
|
24
colorchord2/android/AndroidManifest.xml
Normal file
24
colorchord2/android/AndroidManifest.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" package="org.cnlohr.colorchord">
|
||||
|
||||
<uses-permission android:name="android.permission.SET_RELEASE_APP"/>
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
|
||||
|
||||
<application android:debuggable="true" android:hasCode="false" android:label="colorchord" tools:replace="android:icon,android:theme,android:allowBackup,label" android:icon="@mipmap/icon">
|
||||
<activity android:configChanges="keyboardHidden|orientation" android:label="colorchord" android:name="android.app.NativeActivity">
|
||||
|
||||
<!-- This device filter seems to do nothing at all! If you figure out how to use it or what it does, let me know!! -->
|
||||
<intent-filter>
|
||||
<action android:name="android.hardware.usb.action.ACTION_USB_DEVICE_ATTACHED" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.hardware.usb.action.ACTION_USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />
|
||||
|
||||
<meta-data android:name="android.app.lib_name" android:value="colorchord"/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
125
colorchord2/android/DisplayTensigralAndroid.c
Normal file
125
colorchord2/android/DisplayTensigralAndroid.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
#include "outdrivers.h"
|
||||
#include "notefinder.h"
|
||||
#include <stdio.h>
|
||||
#include "parameters.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "color.h"
|
||||
#include "CNFG.h"
|
||||
#include "rawdrawandroid/android_usb_devices.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/usbdevice_fs.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
|
||||
#define MAX_LEDS_PER_NOTE 512
|
||||
|
||||
extern short screenx, screeny;
|
||||
|
||||
struct DTADriver
|
||||
{
|
||||
int leds;
|
||||
};
|
||||
|
||||
char TensigralDebugStatus[8192];
|
||||
|
||||
int RequestPermissionOrGetConnectionFD( char * debug_status, uint16_t vid, uint16_t pid );
|
||||
void DisconnectUSB(); //Disconnect from USB
|
||||
|
||||
extern jobject deviceConnection;
|
||||
extern int deviceConnectionFD;
|
||||
|
||||
|
||||
|
||||
static void DTAUpdate(void * id, struct NoteFinder*nf)
|
||||
{
|
||||
struct DTADriver * d = (struct DTADriver*)id;
|
||||
int i;
|
||||
|
||||
if( deviceConnectionFD == 0 )
|
||||
{
|
||||
RequestPermissionOrGetConnectionFD( TensigralDebugStatus, 0xabcd, 0xf410 );
|
||||
}
|
||||
|
||||
CNFGPenX = 800;
|
||||
CNFGPenY = 800;
|
||||
CNFGColor( 0xffffff );
|
||||
CNFGDrawText( TensigralDebugStatus, 2 );
|
||||
|
||||
if( !deviceConnectionFD ) return;
|
||||
|
||||
|
||||
uint8_t packet[64];
|
||||
|
||||
if( deviceConnectionFD )
|
||||
{
|
||||
//This section does the crazy wacky stuff to actually split the LEDs into HID Packets and get them out the door... Carefully.
|
||||
int byrem = d->leds*4; //OutLEDs[i*3+1]
|
||||
int offset = 0;
|
||||
int marker = 0;
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
uint8_t sendbuf[64];
|
||||
sendbuf[0] = (byrem > 60)?15:(byrem/4);
|
||||
sendbuf[1] = offset;
|
||||
|
||||
// memcpy( sendbuf + 2, Colorbuf + offset*4, sendbuf[0]*4 );
|
||||
int j;
|
||||
for( j = 0; j < sendbuf[0]; j++ )
|
||||
{
|
||||
sendbuf[j*4+3] = OutLEDs[marker++];
|
||||
sendbuf[j*4+2] = OutLEDs[marker++];
|
||||
sendbuf[j*4+4] = OutLEDs[marker++];
|
||||
sendbuf[j*4+5] = 0;
|
||||
}
|
||||
|
||||
offset += sendbuf[0];
|
||||
byrem -= sendbuf[0]*4;
|
||||
|
||||
|
||||
if( byrem == 0 ) sendbuf[0] |= 0x80;
|
||||
int tsend = 65; //Size of payload (must be 64+1 always)
|
||||
|
||||
//Ok this looks weird, because Android has a bulkTransfer function, but that has a TON of layers of misdirection before it just calls the ioctl.
|
||||
struct usbdevfs_bulktransfer ctrl;
|
||||
memset(&ctrl, 0, sizeof(ctrl));
|
||||
ctrl.ep = 0x02; //Endpoint 0x02 is output endpoint.
|
||||
ctrl.len = 64;
|
||||
ctrl.data = sendbuf;
|
||||
ctrl.timeout = 100;
|
||||
int lastFDWrite = ioctl(deviceConnectionFD, USBDEVFS_BULK, &ctrl);
|
||||
if( lastFDWrite < 0 )
|
||||
{
|
||||
DisconnectUSB();
|
||||
break;
|
||||
}
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
CNFGColor( 0xffffff );
|
||||
}
|
||||
|
||||
static void DTAParams(void * id )
|
||||
{
|
||||
struct DTADriver * d = (struct DTADriver*)id;
|
||||
|
||||
d->leds = 9; RegisterValue( "leds", PAINT, &d->leds, sizeof( d->leds ) );
|
||||
}
|
||||
|
||||
static struct DriverInstances * DisplayTensigralAndroid(const char * parameters)
|
||||
{
|
||||
struct DriverInstances * ret = malloc( sizeof( struct DriverInstances ) );
|
||||
struct DTADriver * d = ret->id = malloc( sizeof( struct DTADriver ) );
|
||||
memset( d, 0, sizeof( struct DTADriver ) );
|
||||
ret->Func = DTAUpdate;
|
||||
ret->Params = DTAParams;
|
||||
DTAParams( d );
|
||||
return ret;
|
||||
}
|
||||
|
||||
REGISTER_OUT_DRIVER(DisplayTensigralAndroid);
|
||||
|
||||
|
16
colorchord2/android/Makefile
Normal file
16
colorchord2/android/Makefile
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
APPNAME=colorchord
|
||||
RAWDRAWANDROID=rawdrawandroid
|
||||
PACKAGENAME?=org.cnlohr.$(APPNAME)
|
||||
|
||||
CFLAGS:=-I. -I.. -Irawdrawandroid/rawdraw -I../cnfa -I../../embeddedcommon -ffunction-sections -Os -DPRINTF_NO_OVERRIDDE
|
||||
LDFLAGS:=-s -lOpenSLES
|
||||
PACKAGENAME?=org.yourorgexample.$(APPNAME)
|
||||
|
||||
CC_C:= ../main.c ../dft.c ../decompose.c ../filter.c ../color.c ../notefinder.c ../util.c ../hook.c ../outdrivers.c ../parameters.c ../chash.c ../OutputVoronoi.c ../OutputProminent.c ../DisplayArray.c ../OutputLinear.c ../DisplayPie.c ../DisplayNetwork.c ../../embeddedcommon/DFT32.c ../OutputCells.c ../configs.c
|
||||
|
||||
SRC:=rawdrawandroid/android_usb_devices.c DisplayTensigralAndroid.c $(CC_C)
|
||||
|
||||
include rawdrawandroid/Makefile
|
||||
|
||||
|
2
colorchord2/android/README.md
Normal file
2
colorchord2/android/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
This part of the project is baed on https://github.com/cnlohr/androidusbtest
|
||||
|
BIN
colorchord2/android/Sources/res/mipmap/icon.png
Normal file
BIN
colorchord2/android/Sources/res/mipmap/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
8
colorchord2/android/Sources/res/xml/device_filter.xml
Normal file
8
colorchord2/android/Sources/res/xml/device_filter.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- This file seems to do NOTHING AT ALL! If you have any idea how to use the device filters file, please let me know! -->
|
||||
<resources>
|
||||
<!-- <usb-device vendor-id="abcd" product-id="f410" /> --> <!-- class="3" subclass="255" protocol="255" -->
|
||||
<usb-device vendor-id="43981" product-id="62480" />
|
||||
</resources>
|
||||
|
1
colorchord2/android/rawdrawandroid
Submodule
1
colorchord2/android/rawdrawandroid
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit a124feee8d928f2276c00a35c56e15b8d5984a06
|
392
colorchord2/android/test.c
Normal file
392
colorchord2/android/test.c
Normal file
|
@ -0,0 +1,392 @@
|
|||
//Copyright (c) 2011-2020 <>< Charles Lohr - Under the MIT/x11 or NewBSD License you choose.
|
||||
// NO WARRANTY! NO GUARANTEE OF SUPPORT! USE AT YOUR OWN RISK
|
||||
// Super basic test - see rawdrawandroid's thing for a more reasonable test.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#include <asset_manager.h>
|
||||
#include <asset_manager_jni.h>
|
||||
#include <android_native_app_glue.h>
|
||||
#include <android/log.h>
|
||||
#include <android/sensor.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/usbdevice_fs.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include "android_usb_devices.h"
|
||||
|
||||
#include "os_generic.h"
|
||||
|
||||
#define CNFG_IMPLEMENTATION
|
||||
#include "CNFG.h"
|
||||
|
||||
#define printf( x...) LOGI( x )
|
||||
|
||||
unsigned frames = 0;
|
||||
unsigned long iframeno = 0;
|
||||
|
||||
void AndroidDisplayKeyboard(int pShow);
|
||||
volatile int suspended;
|
||||
|
||||
short screenx, screeny;
|
||||
int lastmousex = 0;
|
||||
int lastmousey = 0;
|
||||
int lastbid = 0;
|
||||
int lastmask = 0;
|
||||
int lastkey, lastkeydown;
|
||||
|
||||
static int keyboard_up;
|
||||
|
||||
int mousedown;
|
||||
int colormode;
|
||||
double colormodechangetime;
|
||||
|
||||
|
||||
void HandleKey( int keycode, int bDown )
|
||||
{
|
||||
lastkey = keycode;
|
||||
lastkeydown = bDown;
|
||||
if( keycode == 10 && !bDown ) { keyboard_up = 0; AndroidDisplayKeyboard( keyboard_up ); }
|
||||
}
|
||||
|
||||
void HandleButton( int x, int y, int button, int bDown )
|
||||
{
|
||||
lastbid = button;
|
||||
lastmousex = x;
|
||||
lastmousey = y;
|
||||
|
||||
if( bDown ) { colormode = (colormode+1)%2; }
|
||||
if( !bDown ) { colormodechangetime = OGGetAbsoluteTime(); }
|
||||
mousedown = bDown;
|
||||
// if( bDown ) { keyboard_up = !keyboard_up; AndroidDisplayKeyboard( keyboard_up ); }
|
||||
}
|
||||
|
||||
void HandleMotion( int x, int y, int mask )
|
||||
{
|
||||
lastmask = mask;
|
||||
lastmousex = x;
|
||||
lastmousey = y;
|
||||
}
|
||||
|
||||
extern struct android_app * gapp;
|
||||
|
||||
int lastFDWrite = 0;
|
||||
|
||||
void HandleDestroy()
|
||||
{
|
||||
printf( "Destroying\n" );
|
||||
exit(10);
|
||||
}
|
||||
|
||||
void HandleSuspend()
|
||||
{
|
||||
suspended = 1;
|
||||
}
|
||||
|
||||
void HandleResume()
|
||||
{
|
||||
suspended = 0;
|
||||
}
|
||||
|
||||
|
||||
#define NUM_LEDS 20
|
||||
uint8_t Colorbuf[NUM_LEDS*4];
|
||||
|
||||
char rettext[512];
|
||||
char assettext[512];
|
||||
|
||||
int pixelhueX = -1, pixelhueY = -1;
|
||||
|
||||
unsigned long HSVtoHEX( float hue, float sat, float value );
|
||||
unsigned long PixelHue( int x, int y )
|
||||
{
|
||||
float sat = (pixelhueY-y) / (float)pixelhueY * 2.0;
|
||||
float hue = x / (float)pixelhueX;
|
||||
if( sat < 1.0 )
|
||||
{
|
||||
return HSVtoHEX( x * 0.0012, (sat<1)?sat:1, 1.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return HSVtoHEX( x * 0.0012, (sat<1)?sat:1, 2.0-sat );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i, x, y;
|
||||
double ThisTime;
|
||||
double LastFPSTime = OGGetAbsoluteTime();
|
||||
double LastFrameTime = OGGetAbsoluteTime();
|
||||
double SecToWait;
|
||||
int linesegs = 0;
|
||||
uint32_t * pixelHueBackdrop = 0;
|
||||
|
||||
CNFGBGColor = 0x400000;
|
||||
CNFGDialogColor = 0x444444;
|
||||
CNFGSetup( "Test Bench", 0, 0 );
|
||||
|
||||
//To make text look boldish
|
||||
|
||||
while(1)
|
||||
{
|
||||
int i, pos;
|
||||
float f;
|
||||
iframeno++;
|
||||
RDPoint pto[3];
|
||||
|
||||
CNFGHandleInput();
|
||||
|
||||
if( suspended ) { usleep(50000); continue; }
|
||||
|
||||
CNFGClearFrame();
|
||||
CNFGGetDimensions( &screenx, &screeny );
|
||||
|
||||
if( ( screenx != pixelhueX || screeny != pixelhueY ) && screenx > 0 && screeny > 0)
|
||||
{
|
||||
pixelhueX = screenx;
|
||||
pixelhueY = screeny;
|
||||
pixelHueBackdrop = realloc( pixelHueBackdrop, pixelhueX * pixelhueY * 4 );
|
||||
int x, y;
|
||||
for( y = 0; y < pixelhueY; y++ )
|
||||
for( x = 0; x < pixelhueX; x++ )
|
||||
{
|
||||
pixelHueBackdrop[x+y*screenx] = PixelHue( x, y );
|
||||
}
|
||||
}
|
||||
|
||||
//This whole section does cool stuff with LEDs
|
||||
int allledbytes = NUM_LEDS*4;
|
||||
for( i = 0; i < allledbytes; i+=4 )
|
||||
{
|
||||
uint32_t rk;
|
||||
float sat = (OGGetAbsoluteTime() - colormodechangetime)*3.0;
|
||||
|
||||
if( colormode )
|
||||
{
|
||||
rk = PixelHue( lastmousex, lastmousey );
|
||||
}
|
||||
else
|
||||
{
|
||||
rk = HSVtoHEX( i * 0.012+ iframeno* .01, (sat<1)?sat:1, 1.0 );
|
||||
}
|
||||
|
||||
int white = (int)((1.-sat) * 255);
|
||||
if( white > 255 ) white = 255;
|
||||
if( white < 0 ) white = 0;
|
||||
|
||||
Colorbuf[i+0] = rk>>8;
|
||||
Colorbuf[i+1] = rk;
|
||||
Colorbuf[i+2] = rk>>16;
|
||||
Colorbuf[i+3] = white;
|
||||
}
|
||||
|
||||
|
||||
if( pixelHueBackdrop && colormode == 1 && mousedown )
|
||||
{
|
||||
CNFGUpdateScreenWithBitmap( pixelHueBackdrop, pixelhueX, pixelhueY );
|
||||
}
|
||||
else
|
||||
{
|
||||
int led = 0;
|
||||
for( led = 0; led < NUM_LEDS; led++ )
|
||||
{
|
||||
uint32_t col = ( Colorbuf[led*4+0] << 8) | ( Colorbuf[led*4+1] ) | ( Colorbuf[led*4+2] << 16);
|
||||
CNFGColor( 0xff000000 | col );
|
||||
int sx = (led * screenx) / (NUM_LEDS);
|
||||
CNFGTackRectangle( sx, 850, sx + screenx/(NUM_LEDS)+1, screeny );
|
||||
CNFGFlushRender();
|
||||
}
|
||||
}
|
||||
|
||||
if( deviceConnectionFD )
|
||||
{
|
||||
//This section does the crazy wacky stuff to actually split the LEDs into HID Packets and get them out the door... Carefully.
|
||||
int byrem = allledbytes;
|
||||
int offset = 0;
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
uint8_t sendbuf[64];
|
||||
sendbuf[0] = (byrem > 60)?15:(byrem/4);
|
||||
sendbuf[1] = offset;
|
||||
|
||||
memcpy( sendbuf + 2, Colorbuf + offset*4, sendbuf[0]*4 );
|
||||
|
||||
offset += sendbuf[0];
|
||||
byrem -= sendbuf[0]*4;
|
||||
|
||||
|
||||
if( byrem == 0 ) sendbuf[0] |= 0x80;
|
||||
int tsend = 65; //Size of payload (must be 64+1 always)
|
||||
|
||||
//Ok this looks weird, because Android has a bulkTransfer function, but that has a TON of layers of misdirection before it just calls the ioctl.
|
||||
struct usbdevfs_bulktransfer ctrl;
|
||||
memset(&ctrl, 0, sizeof(ctrl));
|
||||
ctrl.ep = 0x02; //Endpoint 0x02 is output endpoint.
|
||||
ctrl.len = 64;
|
||||
ctrl.data = sendbuf;
|
||||
ctrl.timeout = 100;
|
||||
lastFDWrite = ioctl(deviceConnectionFD, USBDEVFS_BULK, &ctrl);
|
||||
if( lastFDWrite < 0 )
|
||||
{
|
||||
DisconnectUSB();
|
||||
break;
|
||||
}
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
{
|
||||
char * rxprintf = rettext;
|
||||
uint8_t RXbuf[64];
|
||||
//Also read-back the properties.
|
||||
struct usbdevfs_bulktransfer ctrl;
|
||||
memset(&ctrl, 0, sizeof(ctrl));
|
||||
ctrl.ep = 0x81; //Endpoint 0x81 is input endpoint.
|
||||
ctrl.len = 64;
|
||||
ctrl.data = RXbuf;
|
||||
ctrl.timeout = 100;
|
||||
int lastfdread = ioctl(deviceConnectionFD, USBDEVFS_BULK, &ctrl);
|
||||
rxprintf += sprintf( rxprintf, "RX: %d\n", lastfdread );
|
||||
if( lastfdread == 64 )
|
||||
{
|
||||
int temperature = RXbuf[4] | (RXbuf[5]<<8);
|
||||
int adc = RXbuf[6] | (RXbuf[7]<<8);
|
||||
int voltage = RXbuf[8] | (RXbuf[9]<<8);
|
||||
rxprintf += sprintf( rxprintf, "T: %d ADC: %d V: %d\n", temperature, adc, voltage );
|
||||
|
||||
int t;
|
||||
CNFGColor( 0xffffffff );
|
||||
for( t = 0; t < 3; t++ )
|
||||
{
|
||||
CNFGTackSegment( t * screenx / 3, RXbuf[20+t] * 50 + 1100, (t+1)*screenx/3, RXbuf[20+t] * 50 + 1100 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( deviceConnectionFD == 0 )
|
||||
{
|
||||
RequestPermissionOrGetConnectionFD( assettext, 0xabcd, 0xf410 );
|
||||
}
|
||||
|
||||
CNFGPenX = 20; CNFGPenY = 200;
|
||||
char st[2048];
|
||||
sprintf( st, "%dx%d %d %d %d %d - %d %d - %d\n%s\n%s", screenx, screeny, lastmousex, lastmousey, lastkey, lastkeydown, lastbid, lastmask, lastFDWrite, assettext, rettext );
|
||||
|
||||
CNFGColor( 0xff000000 );
|
||||
glLineWidth( 20.0f );
|
||||
CNFGDrawText( st, 10 );
|
||||
CNFGFlushRender();
|
||||
|
||||
CNFGColor( 0xFFFFFFFF );
|
||||
glLineWidth( 2.0f );
|
||||
CNFGDrawText( st, 10 );
|
||||
CNFGFlushRender();
|
||||
|
||||
|
||||
// Square behind text
|
||||
|
||||
frames++;
|
||||
CNFGSwapBuffers();
|
||||
|
||||
ThisTime = OGGetAbsoluteTime();
|
||||
if( ThisTime > LastFPSTime + 1 )
|
||||
{
|
||||
printf( "FPS: %d\n", frames );
|
||||
frames = 0;
|
||||
linesegs = 0;
|
||||
LastFPSTime+=1;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned long HSVtoHEX( float hue, float sat, float value )
|
||||
{
|
||||
float pr = 0;
|
||||
float pg = 0;
|
||||
float pb = 0;
|
||||
|
||||
short ora = 0;
|
||||
short og = 0;
|
||||
short ob = 0;
|
||||
|
||||
float ro = fmod( hue * 6, 6. );
|
||||
|
||||
float avg = 0;
|
||||
|
||||
ro = fmod( ro + 6 + 1, 6 ); //Hue was 60* off...
|
||||
|
||||
if( ro < 1 ) //yellow->red
|
||||
{
|
||||
pr = 1;
|
||||
pg = 1. - ro;
|
||||
} else if( ro < 2 )
|
||||
{
|
||||
pr = 1;
|
||||
pb = ro - 1.;
|
||||
} else if( ro < 3 )
|
||||
{
|
||||
pr = 3. - ro;
|
||||
pb = 1;
|
||||
} else if( ro < 4 )
|
||||
{
|
||||
pb = 1;
|
||||
pg = ro - 3;
|
||||
} else if( ro < 5 )
|
||||
{
|
||||
pb = 5 - ro;
|
||||
pg = 1;
|
||||
} else
|
||||
{
|
||||
pg = 1;
|
||||
pr = ro - 5;
|
||||
}
|
||||
|
||||
//Actually, above math is backwards, oops!
|
||||
pr *= value;
|
||||
pg *= value;
|
||||
pb *= value;
|
||||
|
||||
avg += pr;
|
||||
avg += pg;
|
||||
avg += pb;
|
||||
|
||||
pr = pr * sat + avg * (1.-sat);
|
||||
pg = pg * sat + avg * (1.-sat);
|
||||
pb = pb * sat + avg * (1.-sat);
|
||||
|
||||
ora = pr * 255;
|
||||
og = pb * 255;
|
||||
ob = pg * 255;
|
||||
|
||||
if( ora < 0 ) ora = 0;
|
||||
if( ora > 255 ) ora = 255;
|
||||
if( og < 0 ) og = 0;
|
||||
if( og > 255 ) og = 255;
|
||||
if( ob < 0 ) ob = 0;
|
||||
if( ob > 255 ) ob = 255;
|
||||
|
||||
return (ob<<16) | (og<<8) | ora;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 22f0e58a4df57c6a6b5fa05665a6d454e597e2da
|
||||
Subproject commit c474fb4c0a81a3d460125ce275c5dc7d96eba0b5
|
Binary file not shown.
|
@ -96,8 +96,8 @@ void SetEnvValues( int force )
|
|||
SetParametersFromString( "outdrivers=OutputVoronoi,DisplayArray" );
|
||||
SetParametersFromString( "note_attach_amp_iir2=0.250" );
|
||||
|
||||
SetParametersFromString( "lightx=64" );
|
||||
SetParametersFromString( "lighty=32" );
|
||||
SetParametersFromString( "lightx=32" );
|
||||
SetParametersFromString( "lighty=60" );
|
||||
SetParametersFromString( "fromsides=1" );
|
||||
SetParametersFromString( "shape_cutoff=0.03" );
|
||||
|
||||
|
@ -105,7 +105,9 @@ void SetEnvValues( int force )
|
|||
SetParametersFromString( "amppow=2.510" );
|
||||
SetParametersFromString( "distpow=1.500" );
|
||||
|
||||
#else
|
||||
printf( "On Android, looking for configuration file in: %s\n", InitialFile[0] );
|
||||
#endif
|
||||
|
||||
LoadFile( InitialFile[0] );
|
||||
|
||||
for( i = 1; i < gargc; i++ )
|
||||
|
@ -121,7 +123,6 @@ void SetEnvValues( int force )
|
|||
LoadFile( gargv[i] );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ProcessArgs()
|
||||
|
@ -145,9 +146,11 @@ void ProcessArgs()
|
|||
|
||||
void SetupConfigs()
|
||||
{
|
||||
|
||||
#ifdef ANDROID
|
||||
InitialFile[0] = "/sdcard/colorchord-android.conf";
|
||||
#else
|
||||
InitialFile[0] = "default.conf";
|
||||
#endif
|
||||
|
||||
ProcessArgs();
|
||||
|
||||
}
|
||||
|
|
|
@ -41,14 +41,23 @@ struct CNFADriver * sd;
|
|||
#include <fcntl.h>
|
||||
#include <android/log.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static int pfd[2];
|
||||
static pthread_t loggingThread;
|
||||
static const char *LOG_TAG = "colorchord";
|
||||
|
||||
char genlog[16384] = "log";
|
||||
char * genlogptr;
|
||||
|
||||
static void *loggingFunction(void*v) {
|
||||
ssize_t readSize;
|
||||
char buf[128];
|
||||
char buf[1024];
|
||||
static og_mutex_t m;
|
||||
if( !m ) m = OGCreateMutex();
|
||||
|
||||
|
||||
while((readSize = read(pfd[0], buf, sizeof buf - 1)) > 0) {
|
||||
OGLockMutex( m );
|
||||
if(buf[readSize - 1] == '\n') {
|
||||
--readSize;
|
||||
}
|
||||
|
@ -56,6 +65,45 @@ static void *loggingFunction(void*v) {
|
|||
buf[readSize] = 0; // add null-terminator
|
||||
|
||||
__android_log_write(ANDROID_LOG_DEBUG, LOG_TAG, buf); // Set any log level you want
|
||||
if( genlogptr == 0 ) genlogptr = genlog;
|
||||
int genlogbuffer = genlogptr - genlog;
|
||||
if( genlogbuffer + readSize + 1 < sizeof( genlog ) )
|
||||
{
|
||||
memcpy( genlogptr, buf, readSize );
|
||||
genlogptr += readSize;
|
||||
*genlogptr = '\n';
|
||||
genlogptr++;
|
||||
*genlogptr = 0;
|
||||
}
|
||||
|
||||
//Scroll lines.
|
||||
|
||||
#define KEEPLINES 80
|
||||
int lineplaces[KEEPLINES];
|
||||
int newlinect = 0;
|
||||
genlogbuffer = genlogptr - genlog;
|
||||
int i;
|
||||
for( i = 0; i < genlogbuffer; i++ )
|
||||
{
|
||||
if( genlog[i] == '\n' )
|
||||
{
|
||||
lineplaces[newlinect%KEEPLINES] = i;
|
||||
newlinect++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( newlinect >= KEEPLINES )
|
||||
{
|
||||
int placemark = lineplaces[(newlinect+1)%KEEPLINES];
|
||||
for( i = placemark; i <= genlogbuffer; i++ )
|
||||
{
|
||||
genlog[i-placemark] = genlog[i];
|
||||
}
|
||||
genlogptr -= placemark;
|
||||
}
|
||||
|
||||
OGUnlockMutex( m );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -97,8 +145,14 @@ char sound_source[16]; REGISTER_PARAM( sound_source, PABUFFER );
|
|||
int cpu_autolimit = 1; REGISTER_PARAM( cpu_autolimit, PAINT );
|
||||
float cpu_autolimit_interval = 0.016; REGISTER_PARAM( cpu_autolimit_interval, PAFLOAT );
|
||||
int sample_channel = -1;REGISTER_PARAM( sample_channel, PAINT );
|
||||
int showfps = 0; REGISTER_PARAM( showfps, PAINT );
|
||||
float in_amplitude = 1; REGISTER_PARAM( in_amplitude, PAFLOAT );
|
||||
int showfps = 1; REGISTER_PARAM( showfps, PAINT );
|
||||
|
||||
#if defined(ANDROID) || defined( __android__ )
|
||||
float in_amplitude = 2;
|
||||
#else
|
||||
float in_amplitude = 1;
|
||||
#endif
|
||||
REGISTER_PARAM( in_amplitude, PAFLOAT );
|
||||
|
||||
struct NoteFinder * nf;
|
||||
|
||||
|
@ -115,14 +169,19 @@ int show_debug_basic = 1;
|
|||
int gKey = 0;
|
||||
extern int force_white;
|
||||
|
||||
void RecalcBaseHz()
|
||||
{
|
||||
nf->base_hz = 55 * pow( 2, gKey / 12.0 ); ChangeNFParameters( nf );
|
||||
}
|
||||
|
||||
void HandleKey( int keycode, int bDown )
|
||||
{
|
||||
char c = toupper( keycode );
|
||||
if( c == 'D' && bDown ) show_debug = !show_debug;
|
||||
if( c == 'W' ) force_white = bDown;
|
||||
if( c == '9' && bDown ) { gKey--; nf->base_hz = 55 * pow( 2, gKey / 12.0 ); ChangeNFParameters( nf ); }
|
||||
if( c == '-' && bDown ) { gKey++; nf->base_hz = 55 * pow( 2, gKey / 12.0 ); ChangeNFParameters( nf ); }
|
||||
if( c == '0' && bDown ) { gKey = 0; nf->base_hz = 55 * pow( 2, gKey / 12.0 ); ChangeNFParameters( nf ); }
|
||||
if( c == '9' && bDown ) { gKey--; RecalcBaseHz(); }
|
||||
if( c == '-' && bDown ) { gKey++; RecalcBaseHz(); }
|
||||
if( c == '0' && bDown ) { gKey = 0; RecalcBaseHz(); }
|
||||
if( c == 'E' && bDown ) show_debug_basic = !show_debug_basic;
|
||||
if( c == 'K' && bDown ) DumpParameters();
|
||||
if( keycode == ESCAPE_KEY ) exit( 0 );
|
||||
|
@ -133,6 +192,26 @@ void HandleKey( int keycode, int bDown )
|
|||
void HandleButton( int x, int y, int button, int bDown )
|
||||
{
|
||||
printf( "Button: %d,%d (%d) -> %d\n", x, y, button, bDown );
|
||||
if( bDown )
|
||||
{
|
||||
if( y < 800 )
|
||||
{
|
||||
if( x < screenx/3 )
|
||||
{
|
||||
gKey --;
|
||||
}
|
||||
else if( x < (screenx*2/3) )
|
||||
{
|
||||
gKey = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gKey++;
|
||||
}
|
||||
printf( "KEY: %d\n", gKey );
|
||||
RecalcBaseHz();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleMotion( int x, int y, int mask )
|
||||
|
@ -202,7 +281,7 @@ void SoundCB( struct CNFADriver * sd, short * in, short * out, int samplesr, int
|
|||
{
|
||||
out[j] = 0;
|
||||
}
|
||||
SoundEventHappened( samplesr, out, 1, sd->channelsPlay );
|
||||
SoundEventHappened( samplesp, out, 1, channelout );
|
||||
}
|
||||
|
||||
|
||||
|
@ -224,6 +303,7 @@ int main(int argc, char ** argv)
|
|||
{
|
||||
int i;
|
||||
|
||||
|
||||
#ifdef ANDROID
|
||||
setvbuf(stdout, 0, _IOLBF, 0); // make stdout line-buffered
|
||||
setvbuf(stderr, 0, _IONBF, 0); // make stderr unbuffered
|
||||
|
@ -233,6 +313,9 @@ int main(int argc, char ** argv)
|
|||
dup2(pfd[1], 1);
|
||||
dup2(pfd[1], 2);
|
||||
|
||||
genlogptr = genlog;
|
||||
*genlogptr = 0;
|
||||
|
||||
/* spawn the logging thread */
|
||||
if(pthread_create(&loggingThread, 0, loggingFunction, 0) == -1) {
|
||||
return -1;
|
||||
|
@ -260,6 +343,14 @@ int main(int argc, char ** argv)
|
|||
strcpy( sound_source, "WIN" );
|
||||
#elif defined( ANDROID )
|
||||
strcpy( sound_source, "ANDROID" );
|
||||
|
||||
int hasperm = AndroidHasPermissions( "READ_EXTERNAL_STORAGE" );
|
||||
if( !hasperm )
|
||||
{
|
||||
AndroidRequestAppPermissions( "READ_EXTERNAL_STORAGE" );
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
strcpy( sound_source, "PULSE" );
|
||||
#endif
|
||||
|
@ -324,22 +415,31 @@ int main(int argc, char ** argv)
|
|||
free(OutDriverNames);
|
||||
|
||||
|
||||
//Initialize Sound
|
||||
sd = CNFAInit( sound_source, "colorchord", &SoundCB, GetParameterI( "samplerate", 44100 ),
|
||||
GetParameterI( "channels", 2 ), GetParameterI( "channels", 2 ), GetParameterI( "buffer", 1024 ),
|
||||
GetParameterS( "devrecord", 0 ), GetParameterS( "devplay", 0 ) );
|
||||
|
||||
if( !sd )
|
||||
do
|
||||
{
|
||||
fprintf( stderr, "ERROR: Failed to initialize sound output device\n" );
|
||||
return -1;
|
||||
}
|
||||
//Initialize Sound
|
||||
sd = CNFAInit( sound_source, "colorchord", &SoundCB, GetParameterI( "samplerate", 44100 ),
|
||||
GetParameterI( "channels", 2 ), GetParameterI( "channels", 2 ), GetParameterI( "buffer", 1024 ),
|
||||
GetParameterS( "devrecord", 0 ), GetParameterS( "devplay", 0 ) );
|
||||
|
||||
if( sd ) break;
|
||||
|
||||
CNFGColor( 0xffffff );
|
||||
CNFGPenX = 10; CNFGPenY = 100;
|
||||
CNFGHandleInput();
|
||||
CNFGClearFrame();
|
||||
CNFGDrawText( "Colorchord must be used with sound. Sound not available.", 10 );
|
||||
CNFGSwapBuffers();
|
||||
sleep(1);
|
||||
} while( 1 );
|
||||
|
||||
nf = CreateNoteFinder( sd->sps );
|
||||
|
||||
//Once everything was reinitialized, re-read the ini files.
|
||||
SetEnvValues( 1 );
|
||||
|
||||
printf( "================================================= Set Up\n" );
|
||||
|
||||
Now = OGGetAbsoluteTime();
|
||||
double Last = Now;
|
||||
while(1)
|
||||
|
@ -500,6 +600,13 @@ int main(int argc, char ** argv)
|
|||
CNFGPenX = 440; CNFGPenY = screeny-10;
|
||||
sprintf( stt, "FPS: %d", lastfps );
|
||||
CNFGDrawText( stt, 2 );
|
||||
|
||||
#ifdef ANDROID
|
||||
CNFGColor( 0xffffff );
|
||||
CNFGPenX = 10; CNFGPenY = 600;
|
||||
CNFGDrawText( genlog, 3 );
|
||||
#endif
|
||||
|
||||
CNFGSwapBuffers();
|
||||
}
|
||||
|
||||
|
@ -509,7 +616,9 @@ int main(int argc, char ** argv)
|
|||
ThisTime = OGGetAbsoluteTime();
|
||||
if( ThisTime > LastFPSTime + 1 && showfps )
|
||||
{
|
||||
#ifndef ANDROID
|
||||
printf( "FPS: %d\n", frames );
|
||||
#endif
|
||||
lastfps = frames;
|
||||
frames = 0;
|
||||
LastFPSTime+=1;
|
||||
|
@ -530,3 +639,5 @@ int main(int argc, char ** argv)
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,343 +0,0 @@
|
|||
//Copyright 2015 <>< Charles Lohr under the NewBSD OR MIT/x11 License.
|
||||
|
||||
#include "os_generic.h"
|
||||
|
||||
#ifdef USE_WINDOWS
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void OGSleep( int is )
|
||||
{
|
||||
Sleep( is*1000 );
|
||||
}
|
||||
|
||||
void OGUSleep( int ius )
|
||||
{
|
||||
Sleep( ius/1000 );
|
||||
}
|
||||
|
||||
double OGGetAbsoluteTime()
|
||||
{
|
||||
static LARGE_INTEGER lpf;
|
||||
LARGE_INTEGER li;
|
||||
|
||||
if( !lpf.QuadPart )
|
||||
{
|
||||
QueryPerformanceFrequency( &lpf );
|
||||
}
|
||||
|
||||
QueryPerformanceCounter( &li );
|
||||
return (double)li.QuadPart / (double)lpf.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
double OGGetFileTime( const char * file )
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
HANDLE h = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if( h==INVALID_HANDLE_VALUE )
|
||||
return -1;
|
||||
|
||||
GetFileTime( h, 0, 0, &ft );
|
||||
|
||||
CloseHandle( h );
|
||||
|
||||
return ft.dwHighDateTime + ft.dwLowDateTime;
|
||||
}
|
||||
|
||||
|
||||
og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter )
|
||||
{
|
||||
return (og_thread_t)CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)routine, parameter, 0, 0 );
|
||||
}
|
||||
|
||||
void * OGJoinThread( og_thread_t ot )
|
||||
{
|
||||
WaitForSingleObject( ot, INFINITE );
|
||||
CloseHandle( ot );
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OGCancelThread( og_thread_t ot )
|
||||
{
|
||||
CloseHandle( ot );
|
||||
}
|
||||
|
||||
og_mutex_t OGCreateMutex()
|
||||
{
|
||||
return CreateMutex( 0, 0, 0 );
|
||||
}
|
||||
|
||||
void OGLockMutex( og_mutex_t om )
|
||||
{
|
||||
WaitForSingleObject(om, INFINITE);
|
||||
}
|
||||
|
||||
void OGUnlockMutex( og_mutex_t om )
|
||||
{
|
||||
ReleaseMutex(om);
|
||||
}
|
||||
|
||||
void OGDeleteMutex( og_mutex_t om )
|
||||
{
|
||||
CloseHandle( om );
|
||||
}
|
||||
|
||||
|
||||
|
||||
og_sema_t OGCreateSema()
|
||||
{
|
||||
HANDLE sem = CreateSemaphore( 0, 0, 32767, 0 );
|
||||
return (og_sema_t)sem;
|
||||
}
|
||||
|
||||
int OGGetSema( og_sema_t os )
|
||||
{
|
||||
typedef LONG NTSTATUS;
|
||||
HANDLE sem = (HANDLE)os;
|
||||
typedef NTSTATUS (NTAPI *_NtQuerySemaphore)(
|
||||
HANDLE SemaphoreHandle,
|
||||
DWORD SemaphoreInformationClass, /* Would be SEMAPHORE_INFORMATION_CLASS */
|
||||
PVOID SemaphoreInformation, /* but this is to much to dump here */
|
||||
ULONG SemaphoreInformationLength,
|
||||
PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
typedef struct _SEMAPHORE_BASIC_INFORMATION {
|
||||
ULONG CurrentCount;
|
||||
ULONG MaximumCount;
|
||||
} SEMAPHORE_BASIC_INFORMATION;
|
||||
|
||||
|
||||
static _NtQuerySemaphore NtQuerySemaphore;
|
||||
SEMAPHORE_BASIC_INFORMATION BasicInfo;
|
||||
NTSTATUS Status;
|
||||
|
||||
if( !NtQuerySemaphore )
|
||||
{
|
||||
NtQuerySemaphore = (_NtQuerySemaphore)GetProcAddress (GetModuleHandle ("ntdll.dll"), "NtQuerySemaphore");
|
||||
if( !NtQuerySemaphore )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Status = NtQuerySemaphore (sem, 0 /*SemaphoreBasicInformation*/,
|
||||
&BasicInfo, sizeof (SEMAPHORE_BASIC_INFORMATION), NULL);
|
||||
|
||||
if (Status == ERROR_SUCCESS)
|
||||
{
|
||||
return BasicInfo.CurrentCount;
|
||||
}
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
void OGLockSema( og_sema_t os )
|
||||
{
|
||||
WaitForSingleObject( (HANDLE)os, INFINITE );
|
||||
}
|
||||
|
||||
void OGUnlockSema( og_sema_t os )
|
||||
{
|
||||
ReleaseSemaphore( (HANDLE)os, 1, 0 );
|
||||
}
|
||||
|
||||
void OGDeleteSema( og_sema_t os )
|
||||
{
|
||||
CloseHandle( os );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <semaphore.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pthread_mutex_t g_RawMutexStart = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void OGSleep( int is )
|
||||
{
|
||||
sleep( is );
|
||||
}
|
||||
|
||||
void OGUSleep( int ius )
|
||||
{
|
||||
usleep( ius );
|
||||
}
|
||||
|
||||
double OGGetAbsoluteTime()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday( &tv, 0 );
|
||||
return ((double)tv.tv_usec)/1000000. + (tv.tv_sec);
|
||||
}
|
||||
|
||||
double OGGetFileTime( const char * file )
|
||||
{
|
||||
struct stat buff;
|
||||
|
||||
int r = stat( file, &buff );
|
||||
|
||||
if( r < 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return buff.st_mtime;
|
||||
}
|
||||
|
||||
|
||||
|
||||
og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter )
|
||||
{
|
||||
pthread_t * ret = malloc( sizeof( pthread_t ) );
|
||||
int r = pthread_create( ret, 0, routine, parameter );
|
||||
if( r )
|
||||
{
|
||||
free( ret );
|
||||
return 0;
|
||||
}
|
||||
return (og_thread_t)ret;
|
||||
}
|
||||
|
||||
void * OGJoinThread( og_thread_t ot )
|
||||
{
|
||||
void * retval;
|
||||
if( !ot )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pthread_join( *(pthread_t*)ot, &retval );
|
||||
free( ot );
|
||||
return retval;
|
||||
}
|
||||
|
||||
void OGCancelThread( og_thread_t ot )
|
||||
{
|
||||
if( !ot )
|
||||
{
|
||||
return;
|
||||
}
|
||||
#ifdef ANDROID
|
||||
void * fakeret;
|
||||
pthread_join( *(pthread_t*)ot, &fakeret );
|
||||
#else
|
||||
pthread_cancel( *(pthread_t*)ot );
|
||||
#endif
|
||||
free( ot );
|
||||
}
|
||||
|
||||
og_mutex_t OGCreateMutex()
|
||||
{
|
||||
pthread_mutexattr_t mta;
|
||||
og_mutex_t r = malloc( sizeof( pthread_mutex_t ) );
|
||||
|
||||
pthread_mutexattr_init(&mta);
|
||||
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
|
||||
|
||||
pthread_mutex_init( (pthread_mutex_t *)r, &mta );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void OGLockMutex( og_mutex_t om )
|
||||
{
|
||||
if( !om )
|
||||
{
|
||||
return;
|
||||
}
|
||||
pthread_mutex_lock( (pthread_mutex_t*)om );
|
||||
}
|
||||
|
||||
void OGUnlockMutex( og_mutex_t om )
|
||||
{
|
||||
if( !om )
|
||||
{
|
||||
return;
|
||||
}
|
||||
pthread_mutex_unlock( (pthread_mutex_t*)om );
|
||||
}
|
||||
|
||||
void OGDeleteMutex( og_mutex_t om )
|
||||
{
|
||||
if( !om )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_destroy( (pthread_mutex_t*)om );
|
||||
free( om );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
og_sema_t OGCreateSema()
|
||||
{
|
||||
sem_t * sem = malloc( sizeof( sem_t ) );
|
||||
sem_init( sem, 0, 0 );
|
||||
return (og_sema_t)sem;
|
||||
}
|
||||
|
||||
int OGGetSema( og_sema_t os )
|
||||
{
|
||||
int valp;
|
||||
sem_getvalue( os, &valp );
|
||||
return valp;
|
||||
}
|
||||
|
||||
|
||||
void OGLockSema( og_sema_t os )
|
||||
{
|
||||
sem_wait( os );
|
||||
}
|
||||
|
||||
void OGUnlockSema( og_sema_t os )
|
||||
{
|
||||
sem_post( os );
|
||||
}
|
||||
|
||||
void OGDeleteSema( og_sema_t os )
|
||||
{
|
||||
sem_destroy( os );
|
||||
free(os);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
//Date Stamp: 2012-02-15
|
||||
|
||||
/*
|
||||
Copyright (c) 2011-2012 <>< Charles Lohr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of this file.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
//Copyright 2015 <>< Charles Lohr under the NewBSD or MIT/x11 License.
|
||||
#ifndef _OS_GENERIC_H
|
||||
#define _OS_GENERIC_H
|
||||
|
||||
#if defined( WIN32 ) || defined (WINDOWS) || defined( _WIN32)
|
||||
#define USE_WINDOWS
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
//Things that shouldn't be macro'd
|
||||
double OGGetAbsoluteTime();
|
||||
void OGSleep( int is );
|
||||
void OGUSleep( int ius );
|
||||
double OGGetFileTime( const char * file );
|
||||
|
||||
//Threads and Mutices
|
||||
typedef void* og_thread_t;
|
||||
typedef void* og_mutex_t;
|
||||
typedef void* og_sema_t;
|
||||
|
||||
og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter );
|
||||
void * OGJoinThread( og_thread_t ot );
|
||||
void OGCancelThread( og_thread_t ot );
|
||||
|
||||
//Always a recrusive mutex.
|
||||
og_mutex_t OGCreateMutex();
|
||||
void OGLockMutex( og_mutex_t om );
|
||||
void OGUnlockMutex( og_mutex_t om );
|
||||
void OGDeleteMutex( og_mutex_t om );
|
||||
|
||||
//Always a semaphore
|
||||
og_sema_t OGCreateSema(); //Create a semaphore, comes locked initially. NOTE: Max count is 32767
|
||||
void OGLockSema( og_sema_t os );
|
||||
int OGGetSema( og_sema_t os ); //if <0 there was a failure.
|
||||
void OGUnlockSema( og_sema_t os );
|
||||
void OGDeleteSema( og_sema_t os );
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//Date Stamp: 2012-02-15
|
||||
|
||||
/*
|
||||
NOTE: Portions (namely the top section) are part of headers from other
|
||||
sources.
|
||||
|
||||
Copyright (c) 2011-2012 <>< Charles Lohr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of this file.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 55fa52d1eb355baf1456aa55251e722500a32ab8
|
||||
Subproject commit 407da6d1e7a11e68565c4f8cb35dfc330167e30b
|
Loading…
Reference in a new issue