fflush( logfp );
}
}
+
+static void log_named_value( const scs_named_value_t *nv ) {
+ switch (nv->value.type) {
+ case SCS_VALUE_TYPE_INVALID: {
+ log_print("none\n");
+ break;
+ }
+ case SCS_VALUE_TYPE_bool: {
+ log_print("bool = %s\n", nv->value.value_bool.value ? "true" : "false");
+ break;
+ }
+ case SCS_VALUE_TYPE_s32: {
+ log_print("s32 = %d\n", static_cast<int>(nv->value.value_s32.value));
+ break;
+ }
+ case SCS_VALUE_TYPE_u32: {
+ log_print("u32 = %u\n", static_cast<unsigned>(nv->value.value_u32.value));
+ break;
+ }
+ case SCS_VALUE_TYPE_u64: {
+ log_print("u64 = %" SCS_PF_U64 "\n", nv->value.value_u64.value);
+ break;
+ }
+ case SCS_VALUE_TYPE_float: {
+ log_print("float = %f\n", nv->value.value_float.value);
+ break;
+ }
+ case SCS_VALUE_TYPE_double: {
+ log_print("double = %f\n", nv->value.value_double.value);
+ break;
+ }
+ case SCS_VALUE_TYPE_fvector: {
+ log_print(
+ "fvector = (%f,%f,%f)\n",
+ nv->value.value_fvector.x,
+ nv->value.value_fvector.y,
+ nv->value.value_fvector.z
+ );
+ break;
+ }
+ case SCS_VALUE_TYPE_dvector: {
+ log_print(
+ "dvector = (%f,%f,%f)\n",
+ nv->value.value_dvector.x,
+ nv->value.value_dvector.y,
+ nv->value.value_dvector.z
+ );
+ break;
+ }
+ case SCS_VALUE_TYPE_euler: {
+ log_print(
+ "euler = h:%f p:%f r:%f\n",
+ nv->value.value_euler.heading * 360.0f,
+ nv->value.value_euler.pitch * 360.0f,
+ nv->value.value_euler.roll * 360.0f
+ );
+ break;
+ }
+ case SCS_VALUE_TYPE_fplacement: {
+ log_print(
+ "fplacement = (%f,%f,%f) h:%f p:%f r:%f\n",
+ nv->value.value_fplacement.position.x,
+ nv->value.value_fplacement.position.y,
+ nv->value.value_fplacement.position.z,
+ nv->value.value_fplacement.orientation.heading * 360.0f,
+ nv->value.value_fplacement.orientation.pitch * 360.0f,
+ nv->value.value_fplacement.orientation.roll * 360.0f
+ );
+ break;
+ }
+ case SCS_VALUE_TYPE_dplacement: {
+ log_print(
+ "dplacement = (%f,%f,%f) h:%f p:%f r:%f\n",
+ nv->value.value_dplacement.position.x,
+ nv->value.value_dplacement.position.y,
+ nv->value.value_dplacement.position.z,
+ nv->value.value_dplacement.orientation.heading * 360.0f,
+ nv->value.value_dplacement.orientation.pitch * 360.0f,
+ nv->value.value_dplacement.orientation.roll * 360.0f
+ );
+ break;
+ }
+ case SCS_VALUE_TYPE_string: {
+ log_print("string = %s\n", nv->value.value_string.value);
+ break;
+ }
+ default: {
+ log_print("unknown\n");
+ break;
+ }
+ }
+}
#else
#define log_open()
#define log_close()
#define log_print(...)
+#define log_named_value(...)
#endif // def LOGGING
telemetry->paused = (event == SCS_TELEMETRY_EVENT_paused);
}
-SCSAPI_VOID telemetry_configuration(const scs_event_t event, const void *const event_info, const scs_context_t UNUSED(context))
+SCSAPI_VOID telemetry_gameplay(const scs_event_t event, const void *const event_info, const scs_context_t UNUSED(context))
{
- // Here we just print the configuration info.
+ const struct scs_telemetry_gameplay_event_t *const info = static_cast<const scs_telemetry_gameplay_event_t *>(event_info);
- const struct scs_telemetry_configuration_t *const info = static_cast<const scs_telemetry_configuration_t *>(event_info);
- log_print("Configuration: %s\n", info->id);
+ if ( 0 == strcmp( info->id, SCS_TELEMETRY_GAMEPLAY_EVENT_job_cancelled )
+ || 0 == strcmp( info->id, SCS_TELEMETRY_GAMEPLAY_EVENT_job_delivered ) ) {
+ telemetry->job_isvalid = false;
+ }
+ // Log the gameplay event.
+ log_print("Gameplay: %s\n", info->id);
for (const scs_named_value_t *current = info->attributes; current->name; ++current) {
+ log_print(" %s", current->name);
+ if (current->index != SCS_U32_NIL) {
+ log_print("[%u]", static_cast<unsigned>(current->index));
+ }
+ log_print(" : ");
+ log_named_value( current );
+ }
+}
- if ( 0 == strcmp( current->name, SCS_TELEMETRY_CONFIG_ATTRIBUTE_shifter_type ) ) {
- // SCS_SHIFTER_TYPE_arcade
- // SCS_SHIFTER_TYPE_automatic
- // SCS_SHIFTER_TYPE_manual
- // SCS_SHIFTER_TYPE_hshifter
- telemetry->shifter = !strcmp( current->value.value_string.value, SCS_SHIFTER_TYPE_manual )
- || !strcmp( current->value.value_string.value, SCS_SHIFTER_TYPE_hshifter );
+SCSAPI_VOID telemetry_configuration(const scs_event_t event, const void *const event_info, const scs_context_t UNUSED(context))
+{
+ const struct scs_telemetry_configuration_t *const info = static_cast<const scs_telemetry_configuration_t *>(event_info);
+
+ if ( 0 == strcmp( info->id, SCS_TELEMETRY_CONFIG_controls ) ) {
+ for (const scs_named_value_t *current = info->attributes; current->name; ++current) {
+ if ( 0 == strcmp( current->name, SCS_TELEMETRY_CONFIG_ATTRIBUTE_shifter_type ) ) {
+ // SCS_SHIFTER_TYPE_arcade
+ // SCS_SHIFTER_TYPE_automatic
+ // SCS_SHIFTER_TYPE_manual
+ // SCS_SHIFTER_TYPE_hshifter
+ telemetry->shifter = !strcmp( current->value.value_string.value, SCS_SHIFTER_TYPE_manual )
+ || !strcmp( current->value.value_string.value, SCS_SHIFTER_TYPE_hshifter );
+ }
}
- else if ( 0 == strcmp( current->name, SCS_TELEMETRY_CONFIG_ATTRIBUTE_delivery_time ) ) {
- telemetry->job_deltime = current->value.value_u32.value;
+ }
+ else if ( 0 == strcmp( info->id, SCS_TELEMETRY_CONFIG_job ) ) {
+ for (const scs_named_value_t *current = info->attributes; current->name; ++current) {
+ if ( 0 == strcmp( current->name, SCS_TELEMETRY_CONFIG_ATTRIBUTE_delivery_time ) ) {
+ telemetry->job_deltime = current->value.value_u32.value;
+ telemetry->job_isvalid = true;
+ }
}
+ }
- // log configuration
+ // Log the configuration info.
+ log_print("Configuration: %s\n", info->id);
+ for (const scs_named_value_t *current = info->attributes; current->name; ++current) {
log_print(" %s", current->name);
if (current->index != SCS_U32_NIL) {
log_print("[%u]", static_cast<unsigned>(current->index));
}
log_print(" : ");
- switch (current->value.type) {
- case SCS_VALUE_TYPE_INVALID: {
- log_print("none\n");
- break;
- }
- case SCS_VALUE_TYPE_bool: {
- log_print("bool = %s\n", current->value.value_bool.value ? "true" : "false");
- break;
- }
- case SCS_VALUE_TYPE_s32: {
- log_print("s32 = %d\n", static_cast<int>(current->value.value_s32.value));
- break;
- }
- case SCS_VALUE_TYPE_u32: {
- log_print("u32 = %u\n", static_cast<unsigned>(current->value.value_u32.value));
- break;
- }
- case SCS_VALUE_TYPE_u64: {
- log_print("u64 = %" SCS_PF_U64 "\n", current->value.value_u64.value);
- break;
- }
- case SCS_VALUE_TYPE_float: {
- log_print("float = %f\n", current->value.value_float.value);
- break;
- }
- case SCS_VALUE_TYPE_double: {
- log_print("double = %f\n", current->value.value_double.value);
- break;
- }
- case SCS_VALUE_TYPE_fvector: {
- log_print(
- "fvector = (%f,%f,%f)\n",
- current->value.value_fvector.x,
- current->value.value_fvector.y,
- current->value.value_fvector.z
- );
- break;
- }
- case SCS_VALUE_TYPE_dvector: {
- log_print(
- "dvector = (%f,%f,%f)\n",
- current->value.value_dvector.x,
- current->value.value_dvector.y,
- current->value.value_dvector.z
- );
- break;
- }
- case SCS_VALUE_TYPE_euler: {
- log_print(
- "euler = h:%f p:%f r:%f\n",
- current->value.value_euler.heading * 360.0f,
- current->value.value_euler.pitch * 360.0f,
- current->value.value_euler.roll * 360.0f
- );
- break;
- }
- case SCS_VALUE_TYPE_fplacement: {
- log_print(
- "fplacement = (%f,%f,%f) h:%f p:%f r:%f\n",
- current->value.value_fplacement.position.x,
- current->value.value_fplacement.position.y,
- current->value.value_fplacement.position.z,
- current->value.value_fplacement.orientation.heading * 360.0f,
- current->value.value_fplacement.orientation.pitch * 360.0f,
- current->value.value_fplacement.orientation.roll * 360.0f
- );
- break;
- }
- case SCS_VALUE_TYPE_dplacement: {
- log_print(
- "dplacement = (%f,%f,%f) h:%f p:%f r:%f\n",
- current->value.value_dplacement.position.x,
- current->value.value_dplacement.position.y,
- current->value.value_dplacement.position.z,
- current->value.value_dplacement.orientation.heading * 360.0f,
- current->value.value_dplacement.orientation.pitch * 360.0f,
- current->value.value_dplacement.orientation.roll * 360.0f
- );
- break;
- }
- case SCS_VALUE_TYPE_string: {
- log_print("string = %s\n", current->value.value_string.value);
- break;
- }
- default: {
- log_print("unknown\n");
- break;
- }
- }
+ log_named_value( current );
}
}
// We currently support only one version.
- if (version != SCS_TELEMETRY_VERSION_1_00) {
+ if (version != SCS_TELEMETRY_VERSION_1_01) {
return SCS_RESULT_unsupported;
}
// Below the minimum version there might be some missing features (only minor change) or
// incompatible values (major change).
- const scs_u32_t MINIMAL_VERSION = SCS_TELEMETRY_EUT2_GAME_VERSION_1_00;
+ const scs_u32_t MINIMAL_VERSION = SCS_TELEMETRY_EUT2_GAME_VERSION_1_01;
if (version_params->common.game_version < MINIMAL_VERSION) {
log_print("WARNING: Too old version of the game, some features might behave incorrectly\n");
telemetry->game_ver_warn = true;
// Bellow the minimum version there might be some missing features (only minor change) or
// incompatible values (major change).
- const scs_u32_t MINIMAL_VERSION = SCS_TELEMETRY_ATS_GAME_VERSION_1_00;
+ const scs_u32_t MINIMAL_VERSION = SCS_TELEMETRY_ATS_GAME_VERSION_1_01;
if (version_params->common.game_version < MINIMAL_VERSION) {
log_print("WARNING: Too old version of the game, some features might behave incorrectly\n");
telemetry->game_ver_warn = true;
// Register for events. Note that failure to register those basic events
// likely indicates invalid usage of the api or some critical problem. As the
// example requires all of them, we can not continue if the registration fails.
-
const bool events_registered =
- (version_params->register_for_event(SCS_TELEMETRY_EVENT_frame_start, telemetry_frame_start, NULL) == SCS_RESULT_ok) &&
- (version_params->register_for_event(SCS_TELEMETRY_EVENT_frame_end, telemetry_frame_end, NULL) == SCS_RESULT_ok) &&
- (version_params->register_for_event(SCS_TELEMETRY_EVENT_paused, telemetry_pause, NULL) == SCS_RESULT_ok) &&
- (version_params->register_for_event(SCS_TELEMETRY_EVENT_started, telemetry_pause, NULL) == SCS_RESULT_ok)
- ;
+ (version_params->register_for_event(SCS_TELEMETRY_EVENT_frame_start, telemetry_frame_start, NULL) == SCS_RESULT_ok)
+ && (version_params->register_for_event(SCS_TELEMETRY_EVENT_frame_end, telemetry_frame_end, NULL) == SCS_RESULT_ok)
+ && (version_params->register_for_event(SCS_TELEMETRY_EVENT_paused, telemetry_pause, NULL) == SCS_RESULT_ok)
+ && (version_params->register_for_event(SCS_TELEMETRY_EVENT_started, telemetry_pause, NULL) == SCS_RESULT_ok)
+ && (version_params->register_for_event(SCS_TELEMETRY_EVENT_configuration, telemetry_configuration, NULL) == SCS_RESULT_ok)
+ && (version_params->register_for_event(SCS_TELEMETRY_EVENT_gameplay, telemetry_gameplay, NULL) == SCS_RESULT_ok )
+ ;
if (! events_registered) {
-
// Registrations created by unsuccessfull initialization are
// cleared automatically so we can simply exit.
-
+ log_print("FATAL: Unable to register event callbacks\n");
version_params->common.log(SCS_LOG_TYPE_error, "Unable to register event callbacks");
return SCS_RESULT_generic_error;
}
- // Register for the configuration info. As this example only prints the retrieved
- // data, it can operate even if that fails.
-
- version_params->register_for_event(SCS_TELEMETRY_EVENT_configuration, telemetry_configuration, NULL);
-
// Register for channels. The channel might be missing if the game does not support
// it (SCS_RESULT_not_found) or if does not support the requested type
// (SCS_RESULT_unsupported_type). For purpose of this example we ignore the failues
version_params->register_for_channel(SCS_TELEMETRY_CHANNEL_next_rest_stop, SCS_U32_NIL, SCS_VALUE_TYPE_s32, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_s32, &telemetry->next_rest);
// Set the structure with defaults.
-
last_timestamp = static_cast<scs_timestamp_t>(-1);
-
// Initially the game is paused.
-
telemetry->paused = true;
return SCS_RESULT_ok;
}