diff --git a/src/monocoque/devices/simdevice.h b/src/monocoque/devices/simdevice.h index deb2881..eb93632 100644 --- a/src/monocoque/devices/simdevice.h +++ b/src/monocoque/devices/simdevice.h @@ -82,13 +82,15 @@ typedef struct SimDevice m; int id; SoundType type; + VibrationEffectType effecttype; PATestData sounddata; PaStreamParameters outputParameters; PaStream* stream; } SoundDevice; -int sounddev_update(SimDevice* this, SimData* simdata); +int sounddev_engine_update(SimDevice* this, SimData* simdata); +int sounddev_gearshift_update(SimDevice* this, SimData* simdata); int sounddev_free(SimDevice* this); SoundDevice* new_sound_device(DeviceSettings* ds); diff --git a/src/monocoque/devices/sound/usb_generic_shaker.c b/src/monocoque/devices/sound/usb_generic_shaker.c index 5d660d9..a211c83 100644 --- a/src/monocoque/devices/sound/usb_generic_shaker.c +++ b/src/monocoque/devices/sound/usb_generic_shaker.c @@ -15,8 +15,7 @@ #endif - -int patestCallback(const void* inputBuffer, +int patestCallbackEngineRPM(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, @@ -36,32 +35,45 @@ int patestCallback(const void* inputBuffer, float v = 0; v = data->amp * sin (2 * M_PI * ((float) n) / (float) SAMPLE_RATE); - if ( data->gear_sound_data > 0 ) - { - if (n>=1764) - { - n=0; - } - } - else - { if (n>=data->table_size) { n=0; } - } + *out++ = v; + *out++ = v; + } + + data->n=n; + return 0; +} + + +int patestCallbackGearShift(const void* inputBuffer, + void* outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void* userData) +{ + PATestData* data = (PATestData*)userData; + float* out = (float*)outputBuffer; + memset(out, 0, framesPerBuffer * 2 * sizeof(float)); + unsigned int i; + unsigned int n; + n = data->n; + (void) inputBuffer; /* Prevent unused argument warning. */ + + for( i=0; igear_sound_data > 0 ) { - // right channel only? - // i have my butt hooked up to right channel... make this configurable? - *out++ = v; - } - else - { - *out++ = v; - *out++ = v; + data->gear_sound_data = 0; + *out++ = M_PI; + *out++ = M_PI; + *out++ = M_PI; + *out++ = M_PI; } } @@ -97,14 +109,28 @@ int usb_generic_shaker_init(SoundDevice* sounddevice) sounddevice->outputParameters.suggestedLatency = Pa_GetDeviceInfo( sounddevice->outputParameters.device )->defaultLowOutputLatency; sounddevice->outputParameters.hostApiSpecificStreamInfo = NULL; - err = Pa_OpenStream( &sounddevice->stream, - NULL, /* No input. */ - &sounddevice->outputParameters, /* As above. */ - SAMPLE_RATE, - 440, /* Frames per buffer. */ - paClipOff, /* No out of range samples expected. */ - patestCallback, - &sounddevice->sounddata ); + if (sounddevice->effecttype == SOUNDEFFECT_GEARSHIFT) + { + err = Pa_OpenStream( &sounddevice->stream, + NULL, /* No input. */ + &sounddevice->outputParameters, /* As above. */ + SAMPLE_RATE, + 440, /* Frames per buffer. */ + paClipOff, /* No out of range samples expected. */ + patestCallbackGearShift, + &sounddevice->sounddata ); + } + else + { + err = Pa_OpenStream( &sounddevice->stream, + NULL, /* No input. */ + &sounddevice->outputParameters, /* As above. */ + SAMPLE_RATE, + 440, /* Frames per buffer. */ + paClipOff, /* No out of range samples expected. */ + patestCallbackEngineRPM, + &sounddevice->sounddata ); + } if( err != paNoError ) { goto error; @@ -121,8 +147,5 @@ int usb_generic_shaker_init(SoundDevice* sounddevice) error: Pa_Terminate(); - //fprintf( stderr, "An error occured while using the portaudio stream\n" ); - //fprintf( stderr, "Error number: %d\n", err ); - //fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); return err; } diff --git a/src/monocoque/devices/sounddevice.c b/src/monocoque/devices/sounddevice.c index 64b8826..bc0b752 100644 --- a/src/monocoque/devices/sounddevice.c +++ b/src/monocoque/devices/sounddevice.c @@ -8,16 +8,22 @@ #include "../helper/parameters.h" #include "../slog/slog.h" -int sounddev_update(SimDevice* this, SimData* simdata) +// we could make a vtable for these different effects too +int sounddev_engine_update(SimDevice* this, SimData* simdata) { SoundDevice* sounddevice = (void *) this->derived; sounddevice->sounddata.table_size = 44100/(simdata->rpms/60); +} + +int sounddev_gearshift_update(SimDevice* this, SimData* simdata) +{ + SoundDevice* sounddevice = (void *) this->derived; sounddevice->sounddata.gear_sound_data = 0; if (sounddevice->sounddata.last_gear != simdata->gear) { - sounddevice->sounddata.gear_sound_data = sounddevice->sounddata.amp; + sounddevice->sounddata.gear_sound_data = 3.14; } sounddevice->sounddata.last_gear = simdata->gear; } @@ -47,7 +53,8 @@ int sounddev_init(SoundDevice* sounddevice) usb_generic_shaker_init(sounddevice); } -static const vtable sound_simdevice_vtable = { &sounddev_update, &sounddev_free }; +static const vtable engine_sound_simdevice_vtable = { &sounddev_engine_update, &sounddev_free }; +static const vtable gear_sound_simdevice_vtable = { &sounddev_gearshift_update, &sounddev_free }; SoundDevice* new_sound_device(DeviceSettings* ds) { @@ -56,9 +63,28 @@ SoundDevice* new_sound_device(DeviceSettings* ds) { this->m.update = &update; this->m.free = &simdevfree; this->m.derived = this; - this->m.vtable = &sound_simdevice_vtable; - sounddev_init(this); + slogt("Attempting to configure sound device with subtype: %i", ds->dev_subtype); + switch (ds->dev_subtype) { + case (SIMDEVTYPE_ENGINESOUND): + this->effecttype = SOUNDEFFECT_ENGINERPM; + this->m.vtable = &engine_sound_simdevice_vtable; + slogi("Initializing sound device for engine vibrations."); + break; + case (SIMDEVTYPE_GEARSOUND): + this->effecttype = SOUNDEFFECT_GEARSHIFT; + this->m.vtable = &gear_sound_simdevice_vtable; + slogi("Initializing sound device for gear shift vibrations."); + break; + } + + int error = sounddev_init(this); + if (error != 0) + { + free(this); + return NULL; + } return this; } + diff --git a/src/monocoque/devices/sounddevice.h b/src/monocoque/devices/sounddevice.h index 243e710..8d1e36b 100644 --- a/src/monocoque/devices/sounddevice.h +++ b/src/monocoque/devices/sounddevice.h @@ -10,6 +10,13 @@ typedef enum } SoundType; +typedef enum +{ + SOUNDEFFECT_ENGINERPM = 0, + SOUNDEFFECT_GEARSHIFT = 1 +} +VibrationEffectType; + #define MAX_TABLE_SIZE (6000) typedef struct { diff --git a/src/monocoque/gameloop/gameloop.c b/src/monocoque/gameloop/gameloop.c index 16afc1b..326afbf 100644 --- a/src/monocoque/gameloop/gameloop.c +++ b/src/monocoque/gameloop/gameloop.c @@ -242,7 +242,7 @@ int looper(SimDevice* devices, int numdevices, Simulator simulator) int tester(SimDevice* devices, int numdevices) { - slogi("preparing game loop with %i devices...", numdevices); + slogi("preparing test with %i devices...", numdevices); SimData* simdata = malloc(sizeof(SimData)); struct termios newsettings, canonicalmode; @@ -254,7 +254,10 @@ int tester(SimDevice* devices, int numdevices) tcsetattr(0, TCSANOW, &newsettings); fprintf(stdout, "\n"); + simdata->gear = 0; + simdata->rpms = 100; simdata->maxrpm = 8000; + sleep(3); fprintf(stdout, "Setting rpms to 1000\n"); simdata->rpms = 1000; @@ -264,6 +267,30 @@ int tester(SimDevice* devices, int numdevices) } sleep(3); + fprintf(stdout, "Shifting into first gear\n"); + simdata->gear = 1; + for (int x = 0; x < numdevices; x++) + { + devices[x].update(&devices[x], simdata); + } + sleep(3); + + fprintf(stdout, "Shifting into second gear\n"); + simdata->gear = 2; + for (int x = 0; x < numdevices; x++) + { + devices[x].update(&devices[x], simdata); + } + sleep(3); + + fprintf(stdout, "Shifting into third gear\n"); + simdata->gear = 3; + for (int x = 0; x < numdevices; x++) + { + devices[x].update(&devices[x], simdata); + } + sleep(3); + fprintf(stdout, "Setting rpms to 2000\n"); simdata->rpms = 2000; for (int x = 0; x < numdevices; x++) @@ -280,6 +307,14 @@ int tester(SimDevice* devices, int numdevices) } sleep(3); + fprintf(stdout, "Shifting into fourth gear\n"); + simdata->gear = 4; + for (int x = 0; x < numdevices; x++) + { + devices[x].update(&devices[x], simdata); + } + sleep(3); + fprintf(stdout, "Setting rpms to 8000\n"); simdata->rpms = 8000; for (int x = 0; x < numdevices; x++) diff --git a/src/monocoque/helper/confighelper.c b/src/monocoque/helper/confighelper.c index 82353dc..9ed4563 100644 --- a/src/monocoque/helper/confighelper.c +++ b/src/monocoque/helper/confighelper.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -11,21 +12,32 @@ #include "../slog/slog.h" + +int strcicmp(char const *a, char const *b) +{ + for (;; a++, b++) { + int d = tolower((unsigned char)*a) - tolower((unsigned char)*b); + if (d != 0 || !*a) + return d; + } +} + + int strtogame(const char* game, MonocoqueSettings* ms) { slogd("Checking for %s in list of supported simulators.", game); - if (strcmp(game, "ac") == 0) + if (strcicmp(game, "ac") == 0) { slogd("Setting simulator to Assetto Corsa"); ms->sim_name = SIMULATOR_ASSETTO_CORSA; } - else if (strcmp(game, "rf2") == 0) + else if (strcicmp(game, "rf2") == 0) { slogd("Setting simulator to RFactor 2"); ms->sim_name = SIMULATOR_RFACTOR2; } else - if (strcmp(game, "test") == 0) + if (strcicmp(game, "test") == 0) { slogd("Setting simulator to Test Data"); ms->sim_name = SIMULATOR_MONOCOQUE_TEST; @@ -38,22 +50,63 @@ int strtogame(const char* game, MonocoqueSettings* ms) return MONOCOQUE_ERROR_NONE; } -int strtodev(const char* device_type, DeviceSettings* ds) +int strtodevsubtype(const char* device_subtype, DeviceSettings* ds, int simdev) { ds->is_valid = false; - if (strcmp(device_type, "USB") == 0) + ds->dev_subtype = SIMDEVTYPE_UNKNOWN; + + switch (simdev) { + case SIMDEV_USB: + if (strcicmp(device_subtype, "Tachometer") == 0) + { + ds->dev_subtype = SIMDEVTYPE_TACHOMETER; + break; + } + case SIMDEV_SERIAL: + if (strcicmp(device_subtype, "ShiftLights") == 0) + { + ds->dev_subtype = SIMDEVTYPE_SHIFTLIGHTS; + break; + } + case SIMDEV_SOUND: + if (strcicmp(device_subtype, "Engine") == 0) + { + ds->dev_subtype = SIMDEVTYPE_ENGINESOUND; + break; + } + if (strcicmp(device_subtype, "Gear") == 0) + { + ds->dev_subtype = SIMDEVTYPE_GEARSOUND; + break; + } + default: + ds->is_valid = false; + slogw("%s does not appear to be a valid device sub type, but attempting to continue with other devices", device_subtype); + return MONOCOQUE_ERROR_INVALID_DEV; + } + ds->is_valid = true; + return MONOCOQUE_ERROR_NONE; +} + +int strtodev(const char* device_type, const char* device_subtype, DeviceSettings* ds) +{ + ds->is_valid = false; + if (strcicmp(device_type, "USB") == 0) { ds->dev_type = SIMDEV_USB; + strtodevsubtype(device_subtype, ds, SIMDEV_USB); } else - if (strcmp(device_type, "Sound") == 0) + if (strcicmp(device_type, "Sound") == 0) { ds->dev_type = SIMDEV_SOUND; + strtodevsubtype(device_subtype, ds, SIMDEV_SOUND); } else - if (strcmp(device_type, "Serial") == 0) + if (strcicmp(device_type, "Serial") == 0) { ds->dev_type = SIMDEV_SERIAL; + strtodevsubtype(device_subtype, ds, SIMDEV_SERIAL); } else { @@ -65,33 +118,6 @@ int strtodev(const char* device_type, DeviceSettings* ds) return MONOCOQUE_ERROR_NONE; } -int strtodevtype(const char* device_subtype, DeviceSettings* ds) -{ - ds->is_valid = false; - if (strcmp(device_subtype, "Tachometer") == 0) - { - ds->dev_subtype = SIMDEVTYPE_TACHOMETER; - } - else - if (strcmp(device_subtype, "ShiftLights") == 0) - { - ds->dev_subtype = SIMDEVTYPE_SHIFTLIGHTS; - } - else - if (strcmp(device_subtype, "Shaker") == 0) - { - ds->dev_subtype = SIMDEVTYPE_SHAKER; - } - else - { - ds->is_valid = false; - slogi("%s does not appear to be a valid device sub type, but attempting to continue with other devices", device_subtype); - return MONOCOQUE_ERROR_INVALID_DEV; - } - ds->is_valid = true; - return MONOCOQUE_ERROR_NONE; -} - int loadtachconfig(const char* config_file, DeviceSettings* ds) { @@ -131,7 +157,7 @@ int loadtachconfig(const char* config_file, DeviceSettings* ds) { slogt("Xml Element name %s", cursubsubnode->name); } - if (strcmp(cursubsubnode->name, "SettingsItem") == 0) + if (strcicmp(cursubsubnode->name, "SettingsItem") == 0) { arraysize++; } @@ -153,13 +179,13 @@ int loadtachconfig(const char* config_file, DeviceSettings* ds) { for (cursubsubsubnode = cursubsubnode->children; cursubsubsubnode; cursubsubsubnode = cursubsubsubnode->next) { - if (strcmp(cursubsubsubnode->name, "Value") == 0) + if (strcicmp(cursubsubsubnode->name, "Value") == 0) { xmlChar* a = xmlNodeGetContent(cursubsubsubnode); rpms_array[i] = strtol((char*) a, &buf, 10); xmlFree(a); } - if (strcmp(cursubsubsubnode->name, "TimeValue") == 0) + if (strcicmp(cursubsubsubnode->name, "TimeValue") == 0) { xmlChar* a = xmlNodeGetContent(cursubsubsubnode); pulses_array[i] = strtol((char*) a, &buf, 10); @@ -199,17 +225,13 @@ int devsetup(const char* device_type, const char* device_subtype, const char* co int error = MONOCOQUE_ERROR_NONE; slogi("Called device setup with %s %s %s", device_type, device_subtype, config_file); ds->dev_type = SIMDEV_UNKNOWN; - ds->dev_subtype = SIMDEVTYPE_UNKNOWN; - error = strtodev(device_type, ds); - if (error != MONOCOQUE_ERROR_NONE) - { - return error; - } - error = strtodevtype(device_subtype, ds); + + error = strtodev(device_type, device_subtype, ds); if (error != MONOCOQUE_ERROR_NONE) { return error; } + if (ms->program_action == A_PLAY) { error = loadconfig(config_file, ds); diff --git a/src/monocoque/helper/confighelper.h b/src/monocoque/helper/confighelper.h index ee1177d..1900deb 100644 --- a/src/monocoque/helper/confighelper.h +++ b/src/monocoque/helper/confighelper.h @@ -21,8 +21,9 @@ typedef enum { SIMDEVTYPE_UNKNOWN = 0, SIMDEVTYPE_TACHOMETER = 1, - SIMDEVTYPE_SHAKER = 2, - SIMDEVTYPE_SHIFTLIGHTS = 3 + SIMDEVTYPE_SHIFTLIGHTS = 2, + SIMDEVTYPE_ENGINESOUND = 3, + SIMDEVTYPE_GEARSOUND = 4 } DeviceSubType;