if ( (void *)-1 == (shmhnd = shmat(shmid, NULL, 0)) )
return false;
telemetry = static_cast<struct telemetry_state_t *>(shmhnd);
+ memset(telemetry, 0, sizeof *telemetry);
return true;
}
SCSAPI_VOID telemetry_frame_start(const scs_event_t UNUSED(event), const void *const event_info, const scs_context_t UNUSED(context))
{
- const struct scs_telemetry_frame_start_t *const info = static_cast<const scs_telemetry_frame_start_t *>(event_info);
+ const struct scs_telemetry_frame_start_t *const info = static_cast<const scs_telemetry_frame_start_t *>(event_info);
- // The following processing of the timestamps is done so the output
- // from this plugin has continuous time, it is not necessary otherwise.
+ // The following processing of the timestamps is done so the output
+ // from this plugin has continuous time, it is not necessary otherwise.
- // When we just initialized itself, assume that the time started
- // just now.
+ // When we just initialized itself, assume that the time started
+ // just now.
- if (last_timestamp == static_cast<scs_timestamp_t>(-1)) {
- last_timestamp = info->paused_simulation_time;
- }
+ if (last_timestamp == static_cast<scs_timestamp_t>(-1)) {
+ last_timestamp = info->paused_simulation_time;
+ }
- // The timer might be sometimes restarted (e.g. after load) while
- // we want to provide continuous time on our output.
+ // The timer might be sometimes restarted (e.g. after load) while
+ // we want to provide continuous time on our output.
- if (info->flags & SCS_TELEMETRY_FRAME_START_FLAG_timer_restart) {
- last_timestamp = 0;
- }
+ if (info->flags & SCS_TELEMETRY_FRAME_START_FLAG_timer_restart) {
+ last_timestamp = 0;
+ }
- // Advance the timestamp by delta since last frame.
+ // Advance the timestamp by delta since last frame.
- telemetry->timestamp += (info->paused_simulation_time - last_timestamp);
- last_timestamp = info->paused_simulation_time;
+ telemetry->timestamp += (info->paused_simulation_time - last_timestamp);
+ last_timestamp = info->paused_simulation_time;
- // The raw values.
+ // The raw values.
- telemetry->raw_rendering_timestamp = info->render_time;
- telemetry->raw_simulation_timestamp = info->simulation_time;
- telemetry->raw_paused_simulation_timestamp = info->paused_simulation_time;
+ telemetry->raw_rendering_timestamp = info->render_time;
+ telemetry->raw_simulation_timestamp = info->simulation_time;
+ telemetry->raw_paused_simulation_timestamp = info->paused_simulation_time;
}
SCSAPI_VOID telemetry_frame_end(const scs_event_t UNUSED(event), const void *const UNUSED(event_info), const scs_context_t UNUSED(context))
{
- if (output_paused) {
- return;
- }
-
- // The header.
-
- if (print_header) {
- print_header = false;
- log_line("timestamp[us];raw rendering timestamp[us];raw simulation timestamp[us];raw paused simulation timestamp[us];heading[deg];pitch[deg];roll[deg];speed[km/s];cc[km/s]rpm;gear");
- }
-
- // The data line.
-
- log_print("%" SCS_PF_U64 ";%" SCS_PF_U64 ";%" SCS_PF_U64 ";%" SCS_PF_U64, telemetry->timestamp, telemetry->raw_rendering_timestamp, telemetry->raw_simulation_timestamp, telemetry->raw_paused_simulation_timestamp);
- if (telemetry->orientation_available) {
- log_print(";%f;%f;%f", telemetry->heading, telemetry->pitch, telemetry->roll);
- }
- else {
- log_print(";---;---;---");
- }
- log_line(
- ";%3.2f;%3.2f;%f;%d",
- telemetry->speed * 3.6,
- telemetry->cc * 3.6,
- telemetry->rpm,
- telemetry->gear
- );
+ if (output_paused) {
+ return;
+ }
+
+ // The header.
+
+ if (print_header) {
+ print_header = false;
+ log_line("timestamp[us];raw rendering timestamp[us];raw simulation timestamp[us];raw paused simulation timestamp[us];heading[deg];pitch[deg];roll[deg];speed[km/s];cc[km/s]rpm;gear");
+ }
+
+ // The data line.
+
+ log_print("%" SCS_PF_U64 ";%" SCS_PF_U64 ";%" SCS_PF_U64 ";%" SCS_PF_U64, telemetry->timestamp, telemetry->raw_rendering_timestamp, telemetry->raw_simulation_timestamp, telemetry->raw_paused_simulation_timestamp);
+ if (telemetry->orientation_available) {
+ log_print(";%f;%f;%f", telemetry->heading, telemetry->pitch, telemetry->roll);
+ }
+ else {
+ log_print(";---;---;---");
+ }
+ log_line(
+ ";%3.2f;%3.2f;%f;%d",
+ telemetry->speed * 3.6,
+ telemetry->cc * 3.6,
+ telemetry->rpm,
+ telemetry->gear
+ );
}
SCSAPI_VOID telemetry_pause(const scs_event_t event, const void *const UNUSED(event_info), const scs_context_t UNUSED(context))
{
- output_paused = (event == SCS_TELEMETRY_EVENT_paused);
- if (output_paused) {
- log_line("Telemetry paused");
- }
- else {
- log_line("Telemetry unpaused");
- }
- print_header = true;
+ output_paused = (event == SCS_TELEMETRY_EVENT_paused);
+ if (output_paused) {
+ log_line("Telemetry paused");
+ }
+ else {
+ log_line("Telemetry unpaused");
+ }
+ print_header = true;
}
SCSAPI_VOID telemetry_configuration(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_configuration_t *const info = static_cast<const scs_telemetry_configuration_t *>(event_info);
- log_line("Configuration: %s", 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_line("none");
- break;
- }
- case SCS_VALUE_TYPE_bool: {
- log_line("bool = %s", current->value.value_bool.value ? "true" : "false");
- break;
- }
- case SCS_VALUE_TYPE_s32: {
- log_line("s32 = %d", static_cast<int>(current->value.value_s32.value));
- break;
- }
- case SCS_VALUE_TYPE_u32: {
- log_line("u32 = %u", static_cast<unsigned>(current->value.value_u32.value));
- break;
- }
- case SCS_VALUE_TYPE_u64: {
- log_line("u64 = %" SCS_PF_U64, current->value.value_u64.value);
- break;
- }
- case SCS_VALUE_TYPE_float: {
- log_line("float = %f", current->value.value_float.value);
- break;
- }
- case SCS_VALUE_TYPE_double: {
- log_line("double = %f", current->value.value_double.value);
- break;
- }
- case SCS_VALUE_TYPE_fvector: {
- log_line(
- "fvector = (%f,%f,%f)",
- current->value.value_fvector.x,
- current->value.value_fvector.y,
- current->value.value_fvector.z
- );
- break;
- }
- case SCS_VALUE_TYPE_dvector: {
- log_line(
- "dvector = (%f,%f,%f)",
- current->value.value_dvector.x,
- current->value.value_dvector.y,
- current->value.value_dvector.z
- );
- break;
- }
- case SCS_VALUE_TYPE_euler: {
- log_line(
- "euler = h:%f p:%f r:%f",
- 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_line(
- "fplacement = (%f,%f,%f) h:%f p:%f r:%f",
- 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_line(
- "dplacement = (%f,%f,%f) h:%f p:%f r:%f",
- 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_line("string = %s", current->value.value_string.value);
- break;
- }
- default: {
- log_line("unknown");
- break;
- }
- }
- }
-
- print_header = true;
+ // Here we just print the configuration info.
+
+ const struct scs_telemetry_configuration_t *const info = static_cast<const scs_telemetry_configuration_t *>(event_info);
+ log_line("Configuration: %s", 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_line("none");
+ break;
+ }
+ case SCS_VALUE_TYPE_bool: {
+ log_line("bool = %s", current->value.value_bool.value ? "true" : "false");
+ break;
+ }
+ case SCS_VALUE_TYPE_s32: {
+ log_line("s32 = %d", static_cast<int>(current->value.value_s32.value));
+ break;
+ }
+ case SCS_VALUE_TYPE_u32: {
+ log_line("u32 = %u", static_cast<unsigned>(current->value.value_u32.value));
+ break;
+ }
+ case SCS_VALUE_TYPE_u64: {
+ log_line("u64 = %" SCS_PF_U64, current->value.value_u64.value);
+ break;
+ }
+ case SCS_VALUE_TYPE_float: {
+ log_line("float = %f", current->value.value_float.value);
+ break;
+ }
+ case SCS_VALUE_TYPE_double: {
+ log_line("double = %f", current->value.value_double.value);
+ break;
+ }
+ case SCS_VALUE_TYPE_fvector: {
+ log_line(
+ "fvector = (%f,%f,%f)",
+ current->value.value_fvector.x,
+ current->value.value_fvector.y,
+ current->value.value_fvector.z
+ );
+ break;
+ }
+ case SCS_VALUE_TYPE_dvector: {
+ log_line(
+ "dvector = (%f,%f,%f)",
+ current->value.value_dvector.x,
+ current->value.value_dvector.y,
+ current->value.value_dvector.z
+ );
+ break;
+ }
+ case SCS_VALUE_TYPE_euler: {
+ log_line(
+ "euler = h:%f p:%f r:%f",
+ 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_line(
+ "fplacement = (%f,%f,%f) h:%f p:%f r:%f",
+ 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_line(
+ "dplacement = (%f,%f,%f) h:%f p:%f r:%f",
+ 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_line("string = %s", current->value.value_string.value);
+ break;
+ }
+ default: {
+ log_line("unknown");
+ break;
+ }
+ }
+ }
+
+ print_header = true;
}
// Handling of individual channels.
SCSAPI_VOID telemetry_store_orientation(const scs_string_t name, const scs_u32_t index, const scs_value_t *const value, const scs_context_t context)
{
- assert(context);
- telemetry_state_t *const state = static_cast<telemetry_state_t *>(context);
-
- // This callback was registered with the SCS_TELEMETRY_CHANNEL_FLAG_no_value flag
- // so it is called even when the value is not available.
-
- if (! value) {
- state->orientation_available = false;
- return;
- }
-
- assert(value);
- assert(value->type == SCS_VALUE_TYPE_euler);
- state->orientation_available = true;
- state->heading = value->value_euler.heading * 360.0f;
- state->pitch = value->value_euler.pitch * 360.0f;
- state->roll = value->value_euler.roll * 360.0f;
+ assert(context);
+ telemetry_state_t *const state = static_cast<telemetry_state_t *>(context);
+
+ // This callback was registered with the SCS_TELEMETRY_CHANNEL_FLAG_no_value flag
+ // so it is called even when the value is not available.
+
+ if (! value) {
+ state->orientation_available = false;
+ return;
+ }
+
+ assert(value);
+ assert(value->type == SCS_VALUE_TYPE_euler);
+ state->orientation_available = true;
+ state->heading = value->value_euler.heading * 360.0f;
+ state->pitch = value->value_euler.pitch * 360.0f;
+ state->roll = value->value_euler.roll * 360.0f;
}
SCSAPI_VOID telemetry_store_float(const scs_string_t name, const scs_u32_t index, const scs_value_t *const value, const scs_context_t context)
{
- // The SCS_TELEMETRY_CHANNEL_FLAG_no_value flag was not provided during registration
- // so this callback is only called when a valid value is available.
+ // The SCS_TELEMETRY_CHANNEL_FLAG_no_value flag was not provided during registration
+ // so this callback is only called when a valid value is available.
- assert(value);
- assert(value->type == SCS_VALUE_TYPE_float);
- assert(context);
- *static_cast<float *>(context) = value->value_float.value;
+ assert(value);
+ assert(value->type == SCS_VALUE_TYPE_float);
+ assert(context);
+ *static_cast<float *>(context) = value->value_float.value;
}
SCSAPI_VOID telemetry_store_s32(const scs_string_t name, const scs_u32_t index, const scs_value_t *const value, const scs_context_t context)
{
- // The SCS_TELEMETRY_CHANNEL_FLAG_no_value flag was not provided during registration
- // so this callback is only called when a valid value is available.
+ // The SCS_TELEMETRY_CHANNEL_FLAG_no_value flag was not provided during registration
+ // so this callback is only called when a valid value is available.
- assert(value);
- assert(value->type == SCS_VALUE_TYPE_s32);
- assert(context);
- *static_cast<int *>(context) = value->value_s32.value;
+ assert(value);
+ assert(value->type == SCS_VALUE_TYPE_s32);
+ assert(context);
+ *static_cast<int *>(context) = value->value_s32.value;
}
/**
*/
SCSAPI_RESULT scs_telemetry_init(const scs_u32_t version, const scs_telemetry_init_params_t *const params)
{
- // We currently support only one version.
-
- if (version != SCS_TELEMETRY_VERSION_1_00) {
- return SCS_RESULT_unsupported;
- }
-
- const scs_telemetry_init_params_v100_t *const version_params = static_cast<const scs_telemetry_init_params_v100_t *>(params);
- if (! init_shm()) {
- version_params->common.log(SCS_LOG_TYPE_error, "Unable to initialize the log file");
- return SCS_RESULT_generic_error;
- }
-
- // Check application version. Note that this example uses fairly basic channels which are likely to be supported
- // by any future SCS trucking game however more advanced application might want to at least warn the user if there
- // is game or version they do not support.
-
- log_line("Game '%s' %u.%u", version_params->common.game_id, SCS_GET_MAJOR_VERSION(version_params->common.game_version), SCS_GET_MINOR_VERSION(version_params->common.game_version));
-
- if (strcmp(version_params->common.game_id, SCS_GAME_ID_EUT2) == 0) {
-
- // 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_EUT2_GAME_VERSION_1_00;
- if (version_params->common.game_version < MINIMAL_VERSION) {
- log_line("WARNING: Too old version of the game, some features might behave incorrectly");
- }
-
- // Future versions are fine as long the major version is not changed.
-
- const scs_u32_t IMPLEMENTED_VERSION = SCS_TELEMETRY_EUT2_GAME_VERSION_CURRENT;
- if (SCS_GET_MAJOR_VERSION(version_params->common.game_version) > SCS_GET_MAJOR_VERSION(IMPLEMENTED_VERSION)) {
- log_line("WARNING: Too new major version of the game, some features might behave incorrectly");
- }
- }
- else if (strcmp(version_params->common.game_id, SCS_GAME_ID_ATS) == 0) {
-
- // 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;
- if (version_params->common.game_version < MINIMAL_VERSION) {
- log_line("WARNING: Too old version of the game, some features might behave incorrectly");
- }
-
- // Future versions are fine as long the major version is not changed.
-
- const scs_u32_t IMPLEMENTED_VERSION = SCS_TELEMETRY_ATS_GAME_VERSION_CURRENT;
- if (SCS_GET_MAJOR_VERSION(version_params->common.game_version) > SCS_GET_MAJOR_VERSION(IMPLEMENTED_VERSION)) {
- log_line("WARNING: Too new major version of the game, some features might behave incorrectly");
- }
- }
- else {
- log_line("WARNING: Unsupported game, some features or values might behave incorrectly");
- }
-
- // 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)
- ;
- if (! events_registered) {
-
- // Registrations created by unsuccessfull initialization are
- // cleared automatically so we can simply exit.
-
- 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
- // so the unsupported channels will remain at theirs default value.
-
- version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_world_placement, SCS_U32_NIL, SCS_VALUE_TYPE_euler, SCS_TELEMETRY_CHANNEL_FLAG_no_value, telemetry_store_orientation, &telemetry);
- version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_speed, SCS_U32_NIL, SCS_VALUE_TYPE_float, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_float, &telemetry->speed);
- version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_engine_rpm, SCS_U32_NIL, SCS_VALUE_TYPE_float, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_float, &telemetry->rpm);
- version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_engine_gear, SCS_U32_NIL, SCS_VALUE_TYPE_s32, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_s32, &telemetry->gear);
- version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_cruise_control, SCS_U32_NIL, SCS_VALUE_TYPE_float, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_float, &telemetry->cc);
+ // We currently support only one version.
+
+ if (version != SCS_TELEMETRY_VERSION_1_00) {
+ return SCS_RESULT_unsupported;
+ }
+
+ const scs_telemetry_init_params_v100_t *const version_params = static_cast<const scs_telemetry_init_params_v100_t *>(params);
+ if (! init_shm()) {
+ version_params->common.log(SCS_LOG_TYPE_error, "Unable to initialize the log file");
+ return SCS_RESULT_generic_error;
+ }
+
+ // Check application version. Note that this example uses fairly basic channels which are likely to be supported
+ // by any future SCS trucking game however more advanced application might want to at least warn the user if there
+ // is game or version they do not support.
+
+ log_line("Game '%s' %u.%u", version_params->common.game_id, SCS_GET_MAJOR_VERSION(version_params->common.game_version), SCS_GET_MINOR_VERSION(version_params->common.game_version));
+
+ if (strcmp(version_params->common.game_id, SCS_GAME_ID_EUT2) == 0) {
+
+ // 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_EUT2_GAME_VERSION_1_00;
+ if (version_params->common.game_version < MINIMAL_VERSION) {
+ log_line("WARNING: Too old version of the game, some features might behave incorrectly");
+ }
+
+ // Future versions are fine as long the major version is not changed.
+
+ const scs_u32_t IMPLEMENTED_VERSION = SCS_TELEMETRY_EUT2_GAME_VERSION_CURRENT;
+ if (SCS_GET_MAJOR_VERSION(version_params->common.game_version) > SCS_GET_MAJOR_VERSION(IMPLEMENTED_VERSION)) {
+ log_line("WARNING: Too new major version of the game, some features might behave incorrectly");
+ }
+ }
+ else if (strcmp(version_params->common.game_id, SCS_GAME_ID_ATS) == 0) {
+
+ // 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;
+ if (version_params->common.game_version < MINIMAL_VERSION) {
+ log_line("WARNING: Too old version of the game, some features might behave incorrectly");
+ }
+
+ // Future versions are fine as long the major version is not changed.
+
+ const scs_u32_t IMPLEMENTED_VERSION = SCS_TELEMETRY_ATS_GAME_VERSION_CURRENT;
+ if (SCS_GET_MAJOR_VERSION(version_params->common.game_version) > SCS_GET_MAJOR_VERSION(IMPLEMENTED_VERSION)) {
+ log_line("WARNING: Too new major version of the game, some features might behave incorrectly");
+ }
+ }
+ else {
+ log_line("WARNING: Unsupported game, some features or values might behave incorrectly");
+ }
+
+ // 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)
+ ;
+ if (! events_registered) {
+
+ // Registrations created by unsuccessfull initialization are
+ // cleared automatically so we can simply exit.
+
+ 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
+ // so the unsupported channels will remain at theirs default value.
+
+ version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_world_placement, SCS_U32_NIL, SCS_VALUE_TYPE_euler, SCS_TELEMETRY_CHANNEL_FLAG_no_value, telemetry_store_orientation, &telemetry);
+ version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_speed, SCS_U32_NIL, SCS_VALUE_TYPE_float, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_float, &telemetry->speed);
+ version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_engine_rpm, SCS_U32_NIL, SCS_VALUE_TYPE_float, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_float, &telemetry->rpm);
+ version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_engine_gear, SCS_U32_NIL, SCS_VALUE_TYPE_s32, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_s32, &telemetry->gear);
+ version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_cruise_control, SCS_U32_NIL, SCS_VALUE_TYPE_float, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_float, &telemetry->cc);
version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_fuel_average_consumption, SCS_U32_NIL, SCS_VALUE_TYPE_float, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_float, &telemetry->fc_avg);
- // Set the structure with defaults.
+ // Set the structure with defaults.
-// memset(&telemetry, 0, sizeof(telemetry));
- print_header = true;
- last_timestamp = static_cast<scs_timestamp_t>(-1);
+ print_header = true;
+ last_timestamp = static_cast<scs_timestamp_t>(-1);
- // Initially the game is paused.
+ // Initially the game is paused.
- output_paused = true;
- return SCS_RESULT_ok;
+ output_paused = true;
+ return SCS_RESULT_ok;
}
/**
*/
SCSAPI_VOID scs_telemetry_shutdown(void)
{
- // Any cleanup needed. The registrations will be removed automatically
- // so there is no need to do that manually.
+ // Any cleanup needed. The registrations will be removed automatically
+ // so there is no need to do that manually.
- release_shm();
+ release_shm();
}
// Cleanup
#ifdef _WIN32
BOOL APIENTRY DllMain(
- HMODULE module,
- DWORD reason_for_call,
- LPVOID reseved
+ HMODULE module,
+ DWORD reason_for_call,
+ LPVOID reseved
)
{
- if (reason_for_call == DLL_PROCESS_DETACH) {
- release_shm();
- }
- return TRUE;
+ if (reason_for_call == DLL_PROCESS_DETACH) {
+ release_shm();
+ }
+ return TRUE;
}
#endif
#ifdef __linux__
void __attribute__ ((destructor)) unload(void)
{
- release_shm();
+ release_shm();
}
#endif