parent
6daf9d8446
commit
a0df249730
@ -0,0 +1 @@ |
|||||||
|
Subproject commit 3c57a3ce6e91f868973eda0b166e367c5384ff89 |
@ -0,0 +1 @@ |
|||||||
|
Subproject commit c931bac289dd431f1dd30fc4a5d1a7be36668073 |
@ -0,0 +1,321 @@ |
|||||||
|
/**
|
||||||
|
* @brief Simple input device |
||||||
|
* |
||||||
|
* Generates device with a few axes and buttons which change with time |
||||||
|
*/ |
||||||
|
|
||||||
|
// Windows stuff.
|
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
# define WINVER 0x0500 |
||||||
|
# define _WIN32_WINNT 0x0500 |
||||||
|
# include <windows.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <assert.h> |
||||||
|
#include <stdarg.h> |
||||||
|
#include <string.h> |
||||||
|
#include <time.h> |
||||||
|
|
||||||
|
// SDK
|
||||||
|
|
||||||
|
#include "scssdk_input.h" |
||||||
|
#include "eurotrucks2/scssdk_eut2.h" |
||||||
|
#include "eurotrucks2/scssdk_input_eut2.h" |
||||||
|
#include "amtrucks/scssdk_ats.h" |
||||||
|
#include "amtrucks/scssdk_input_ats.h" |
||||||
|
|
||||||
|
#define UNUSED(x) |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logging support. |
||||||
|
*/ |
||||||
|
FILE *log_file = NULL; |
||||||
|
|
||||||
|
const unsigned AXIS_COUNT = 2; |
||||||
|
const unsigned BUTTON_COUNT = 3; |
||||||
|
|
||||||
|
// Simulation of the values.
|
||||||
|
|
||||||
|
struct device_data_t |
||||||
|
{ |
||||||
|
// Current state of the dummy inputs.
|
||||||
|
|
||||||
|
float axes[AXIS_COUNT]; |
||||||
|
unsigned button_state; |
||||||
|
|
||||||
|
// Last time when we simulated movement.
|
||||||
|
|
||||||
|
time_t last_movement_time; |
||||||
|
|
||||||
|
// Index of next input we will report.
|
||||||
|
|
||||||
|
unsigned next_reported_input; |
||||||
|
}; |
||||||
|
|
||||||
|
device_data_t dummy_device; |
||||||
|
|
||||||
|
// Management of the log file.
|
||||||
|
|
||||||
|
bool init_log(void) |
||||||
|
{ |
||||||
|
if (log_file) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
log_file = fopen("input.log", "wt"); |
||||||
|
if (! log_file) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
fprintf(log_file, "Log opened\n"); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void finish_log(void) |
||||||
|
{ |
||||||
|
if (! log_file) { |
||||||
|
return; |
||||||
|
} |
||||||
|
fprintf(log_file, "Log ended\n"); |
||||||
|
fclose(log_file); |
||||||
|
log_file = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void log_print(const char *const text, ...) |
||||||
|
{ |
||||||
|
if (! log_file) { |
||||||
|
return; |
||||||
|
} |
||||||
|
va_list args; |
||||||
|
va_start(args, text); |
||||||
|
vfprintf(log_file, text, args); |
||||||
|
va_end(args); |
||||||
|
} |
||||||
|
|
||||||
|
void log_line(const char *const text, ...) |
||||||
|
{ |
||||||
|
if (! log_file) { |
||||||
|
return; |
||||||
|
} |
||||||
|
va_list args; |
||||||
|
va_start(args, text); |
||||||
|
vfprintf(log_file, text, args); |
||||||
|
fprintf(log_file, "\n"); |
||||||
|
va_end(args); |
||||||
|
} |
||||||
|
|
||||||
|
void simulate_device(device_data_t &device) |
||||||
|
{ |
||||||
|
// Move once per second.
|
||||||
|
|
||||||
|
const time_t now = time(NULL); |
||||||
|
if (device.last_movement_time == now) { |
||||||
|
return; |
||||||
|
} |
||||||
|
device.last_movement_time = now; |
||||||
|
|
||||||
|
// Move each axis to maximum before moving the next
|
||||||
|
// one reseting everything to zero if all of them
|
||||||
|
// reach maximum.
|
||||||
|
|
||||||
|
if (device.axes[AXIS_COUNT - 1] >= 1.0f) { |
||||||
|
memset(device.axes, 0, sizeof(device.axes)); |
||||||
|
} |
||||||
|
|
||||||
|
for (unsigned i = 0; i < AXIS_COUNT; ++i) { |
||||||
|
if (device.axes[i] < 1.0f) { |
||||||
|
device.axes[i] += 0.125f; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
device.button_state = (device.button_state + 1) % (BUTTON_COUNT * 2); |
||||||
|
} |
||||||
|
|
||||||
|
SCSAPI_VOID input_active_callback(const scs_u8_t active, const scs_context_t UNUSED(context)) |
||||||
|
{ |
||||||
|
// This callback is optional. A real implementation could do some cleanup
|
||||||
|
// on deactivation or can leave it to event callback with
|
||||||
|
// SCS_INPUT_EVENT_CALLBACK_FLAG_first_after_activation flag.
|
||||||
|
|
||||||
|
if (active > 0) { |
||||||
|
log_line("Device activated"); |
||||||
|
} |
||||||
|
else { |
||||||
|
log_line("Device deactivated"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
SCSAPI_RESULT input_event_callback(scs_input_event_t *const event_info, const scs_u32_t flags, const scs_context_t context) |
||||||
|
{ |
||||||
|
device_data_t &device = *static_cast<device_data_t *>(context); |
||||||
|
|
||||||
|
if (flags & SCS_INPUT_EVENT_CALLBACK_FLAG_first_after_activation) { |
||||||
|
log_line("First call after activation"); |
||||||
|
} |
||||||
|
|
||||||
|
// Simulates retrieval of current data from some external device at start
|
||||||
|
// of the frame.
|
||||||
|
|
||||||
|
if (flags & SCS_INPUT_EVENT_CALLBACK_FLAG_first_in_frame) { |
||||||
|
simulate_device(device); |
||||||
|
device.next_reported_input = 0; |
||||||
|
} |
||||||
|
|
||||||
|
// Did we process all events for this frame?
|
||||||
|
|
||||||
|
if (device.next_reported_input >= (AXIS_COUNT + BUTTON_COUNT)) { |
||||||
|
return SCS_RESULT_not_found; |
||||||
|
} |
||||||
|
|
||||||
|
// Generate events for individual inputs. If the number of inputs is small,
|
||||||
|
// it is fine to generate events even if there was no change.
|
||||||
|
|
||||||
|
event_info->input_index = device.next_reported_input; |
||||||
|
if (device.next_reported_input < AXIS_COUNT) { |
||||||
|
event_info->value_float.value = device.axes[device.next_reported_input]; |
||||||
|
} |
||||||
|
else { |
||||||
|
event_info->value_bool.value = (((device.next_reported_input - AXIS_COUNT) * 2) == device.button_state) ? 1 : 0; |
||||||
|
} |
||||||
|
++device.next_reported_input; |
||||||
|
return SCS_RESULT_ok; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input API initialization function. |
||||||
|
* |
||||||
|
* See scssdk_input.h |
||||||
|
*/ |
||||||
|
SCSAPI_RESULT scs_input_init(const scs_u32_t version, const scs_input_init_params_t *const params) |
||||||
|
{ |
||||||
|
// We currently support only one version.
|
||||||
|
|
||||||
|
if (version != SCS_INPUT_VERSION_1_00) { |
||||||
|
return SCS_RESULT_unsupported; |
||||||
|
} |
||||||
|
|
||||||
|
const scs_input_init_params_v100_t *const version_params = static_cast<const scs_input_init_params_v100_t *>(params); |
||||||
|
if (! init_log()) { |
||||||
|
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 features which are likely to be supported
|
||||||
|
// by any future SCS trucking game however more advanced applications 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) { |
||||||
|
|
||||||
|
// 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_INPUT_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_INPUT_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) { |
||||||
|
|
||||||
|
// 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_INPUT_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_INPUT_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"); |
||||||
|
} |
||||||
|
|
||||||
|
// Setup the device information.
|
||||||
|
|
||||||
|
const scs_input_device_input_t inputs[] = { |
||||||
|
{"a1", "Analog axis 1", SCS_VALUE_TYPE_float}, |
||||||
|
{"a2", "Analog axis 2", SCS_VALUE_TYPE_float}, |
||||||
|
{"b1", "Button 1", SCS_VALUE_TYPE_bool}, |
||||||
|
{"b2", "Button 2", SCS_VALUE_TYPE_bool}, |
||||||
|
{"b3", "Button 3", SCS_VALUE_TYPE_bool}, |
||||||
|
}; |
||||||
|
assert(AXIS_COUNT == 2); |
||||||
|
assert(BUTTON_COUNT == 3); |
||||||
|
|
||||||
|
scs_input_device_t device_info; |
||||||
|
memset(&device_info, 0, sizeof(device_info)); |
||||||
|
device_info.name = "example"; |
||||||
|
device_info.display_name = "Example SDK Device"; |
||||||
|
device_info.type = SCS_INPUT_DEVICE_TYPE_generic; |
||||||
|
device_info.input_count = sizeof(inputs) / sizeof(inputs[0]); |
||||||
|
device_info.inputs = inputs; |
||||||
|
|
||||||
|
device_info.input_active_callback = input_active_callback; |
||||||
|
device_info.input_event_callback = input_event_callback; |
||||||
|
device_info.callback_context = &dummy_device; |
||||||
|
|
||||||
|
memset(&dummy_device, 0, sizeof(dummy_device)); |
||||||
|
dummy_device.last_movement_time = time(NULL); |
||||||
|
|
||||||
|
if (version_params->register_device(&device_info) != SCS_RESULT_ok) { |
||||||
|
|
||||||
|
// Registrations created by unsuccessfull initialization are
|
||||||
|
// cleared automatically so we can simply exit.
|
||||||
|
|
||||||
|
version_params->common.log(SCS_LOG_TYPE_error, "Unable to register device"); |
||||||
|
return SCS_RESULT_generic_error; |
||||||
|
} |
||||||
|
|
||||||
|
return SCS_RESULT_ok; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input API deinitialization function. |
||||||
|
* |
||||||
|
* See scssdk_input.h |
||||||
|
*/ |
||||||
|
SCSAPI_VOID scs_input_shutdown(void) |
||||||
|
{ |
||||||
|
// Any cleanup needed. The registrations will be removed automatically.
|
||||||
|
|
||||||
|
finish_log(); |
||||||
|
} |
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
BOOL APIENTRY DllMain( |
||||||
|
HMODULE module, |
||||||
|
DWORD reason_for_call, |
||||||
|
LPVOID reseved |
||||||
|
) |
||||||
|
{ |
||||||
|
if (reason_for_call == DLL_PROCESS_DETACH) { |
||||||
|
finish_log(); |
||||||
|
} |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef __linux__ |
||||||
|
void __attribute__ ((destructor)) unload(void) |
||||||
|
{ |
||||||
|
finish_log(); |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,4 @@ |
|||||||
|
LIBRARY input |
||||||
|
EXPORTS |
||||||
|
scs_input_init=scs_input_init |
||||||
|
scs_input_shutdown=scs_input_shutdown |
@ -0,0 +1,102 @@ |
|||||||
|
/**
|
||||||
|
* @brief Simple semantical input device |
||||||
|
* |
||||||
|
* Generates a simple device which toggles lights based on time |
||||||
|
*/ |
||||||
|
|
||||||
|
// Windows stuff.
|
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
# define WINVER 0x0500 |
||||||
|
# define _WIN32_WINNT 0x0500 |
||||||
|
# include <windows.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <assert.h> |
||||||
|
#include <stdarg.h> |
||||||
|
#include <string.h> |
||||||
|
#include <time.h> |
||||||
|
|
||||||
|
// SDK
|
||||||
|
|
||||||
|
#include "scssdk_input.h" |
||||||
|
#include "eurotrucks2/scssdk_eut2.h" |
||||||
|
#include "eurotrucks2/scssdk_input_eut2.h" |
||||||
|
#include "amtrucks/scssdk_ats.h" |
||||||
|
#include "amtrucks/scssdk_input_ats.h" |
||||||
|
|
||||||
|
#define UNUSED(x) |
||||||
|
|
||||||
|
SCSAPI_RESULT input_event_callback(scs_input_event_t *const event_info, const scs_u32_t flags, const scs_context_t UNUSED(context)) |
||||||
|
{ |
||||||
|
if ((flags & SCS_INPUT_EVENT_CALLBACK_FLAG_first_in_frame) == 0) { |
||||||
|
return SCS_RESULT_not_found; |
||||||
|
} |
||||||
|
|
||||||
|
event_info->input_index = 0; |
||||||
|
event_info->value_bool.value = (time(NULL) & 1); |
||||||
|
return SCS_RESULT_ok; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input API initialization function. |
||||||
|
* |
||||||
|
* See scssdk_input.h |
||||||
|
*/ |
||||||
|
SCSAPI_RESULT scs_input_init(const scs_u32_t version, const scs_input_init_params_t *const params) |
||||||
|
{ |
||||||
|
// We currently support only one version.
|
||||||
|
|
||||||
|
if (version != SCS_INPUT_VERSION_1_00) { |
||||||
|
return SCS_RESULT_unsupported; |
||||||
|
} |
||||||
|
|
||||||
|
const scs_input_init_params_v100_t *const version_params = static_cast<const scs_input_init_params_v100_t *>(params); |
||||||
|
|
||||||
|
// Setup the device information. The name of the input matches the name of the
|
||||||
|
// mix as seen in controls.sii. Note that only some inputs are supported this way.
|
||||||
|
// See documentation of SCS_INPUT_DEVICE_TYPE_semantical
|
||||||
|
|
||||||
|
const scs_input_device_input_t input = {"light", "Lights", SCS_VALUE_TYPE_bool}; |
||||||
|
|
||||||
|
scs_input_device_t device_info; |
||||||
|
memset(&device_info, 0, sizeof(device_info)); |
||||||
|
device_info.name = "example_semantical"; |
||||||
|
device_info.display_name = "Example Semantical SDK Device"; |
||||||
|
device_info.type = SCS_INPUT_DEVICE_TYPE_semantical; |
||||||
|
device_info.input_count = 1; |
||||||
|
device_info.inputs = &input; |
||||||
|
device_info.input_event_callback = input_event_callback; |
||||||
|
device_info.callback_context = NULL; |
||||||
|
|
||||||
|
if (version_params->register_device(&device_info) != SCS_RESULT_ok) { |
||||||
|
version_params->common.log(SCS_LOG_TYPE_error, "Unable to register device"); |
||||||
|
return SCS_RESULT_generic_error; |
||||||
|
} |
||||||
|
|
||||||
|
return SCS_RESULT_ok; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input API deinitialization function. |
||||||
|
* |
||||||
|
* See scssdk_input.h |
||||||
|
*/ |
||||||
|
SCSAPI_VOID scs_input_shutdown(void) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
BOOL APIENTRY DllMain( |
||||||
|
HMODULE module, |
||||||
|
DWORD reason_for_call, |
||||||
|
LPVOID reseved |
||||||
|
) |
||||||
|
{ |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,4 @@ |
|||||||
|
LIBRARY input_semantical |
||||||
|
EXPORTS |
||||||
|
scs_input_init=scs_input_init |
||||||
|
scs_input_shutdown=scs_input_shutdown |
@ -0,0 +1,18 @@ |
|||||||
|
{ |
||||||
|
"configurations": [ |
||||||
|
{ |
||||||
|
"name": "Linux", |
||||||
|
"includePath": [ |
||||||
|
"${workspaceFolder}/**", |
||||||
|
"/home/jimj316/nextcloud/jimj316 home/Programming/_Libraries/scs_sdk_1_14/include/**" |
||||||
|
], |
||||||
|
"defines": [], |
||||||
|
"compilerPath": "/usr/bin/clang-16", |
||||||
|
"cStandard": "c17", |
||||||
|
"cppStandard": "c++17", |
||||||
|
"intelliSenseMode": "linux-clang-x64", |
||||||
|
"configurationProvider": "ms-vscode.makefile-tools" |
||||||
|
} |
||||||
|
], |
||||||
|
"version": 4 |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
{ |
||||||
|
// Use IntelliSense to learn about possible attributes. |
||||||
|
// Hover to view descriptions of existing attributes. |
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 |
||||||
|
"version": "0.2.0", |
||||||
|
"configurations": [] |
||||||
|
} |
@ -0,0 +1,529 @@ |
|||||||
|
/**
|
||||||
|
* @brief Simple logger. |
||||||
|
* |
||||||
|
* Writes the output into file inside the current directory. |
||||||
|
*/ |
||||||
|
|
||||||
|
// Windows stuff.
|
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
# define WINVER 0x0500 |
||||||
|
# define _WIN32_WINNT 0x0500 |
||||||
|
# include <windows.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <assert.h> |
||||||
|
#include <stdarg.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
// SDK
|
||||||
|
|
||||||
|
#include "scssdk_telemetry.h" |
||||||
|
#include "eurotrucks2/scssdk_eut2.h" |
||||||
|
#include "eurotrucks2/scssdk_telemetry_eut2.h" |
||||||
|
#include "amtrucks/scssdk_ats.h" |
||||||
|
#include "amtrucks/scssdk_telemetry_ats.h" |
||||||
|
|
||||||
|
#define UNUSED(x) |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logging support. |
||||||
|
*/ |
||||||
|
FILE *log_file = NULL; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tracking of paused state of the game. |
||||||
|
*/ |
||||||
|
bool output_paused = true; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Should we print the data header next time |
||||||
|
* we are printing the data? |
||||||
|
*/ |
||||||
|
bool print_header = true; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Last timestamp we received. |
||||||
|
*/ |
||||||
|
scs_timestamp_t last_timestamp = static_cast<scs_timestamp_t>(-1); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Combined telemetry data. |
||||||
|
*/ |
||||||
|
struct telemetry_state_t |
||||||
|
{ |
||||||
|
scs_timestamp_t timestamp; |
||||||
|
scs_timestamp_t raw_rendering_timestamp; |
||||||
|
scs_timestamp_t raw_simulation_timestamp; |
||||||
|
scs_timestamp_t raw_paused_simulation_timestamp; |
||||||
|
|
||||||
|
bool orientation_available; |
||||||
|
float heading; |
||||||
|
float pitch; |
||||||
|
float roll; |
||||||
|
|
||||||
|
float speed; |
||||||
|
float rpm; |
||||||
|
int gear; |
||||||
|
|
||||||
|
} telemetry; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function writting message to the game internal log. |
||||||
|
*/ |
||||||
|
scs_log_t game_log = NULL; |
||||||
|
|
||||||
|
// Management of the log file.
|
||||||
|
|
||||||
|
bool init_log(void) |
||||||
|
{ |
||||||
|
if (log_file) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
log_file = fopen("telemetry.log", "wt"); |
||||||
|
if (! log_file) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
fprintf(log_file, "Log opened\n"); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void finish_log(void) |
||||||
|
{ |
||||||
|
if (! log_file) { |
||||||
|
return; |
||||||
|
} |
||||||
|
fprintf(log_file, "Log ended\n"); |
||||||
|
fclose(log_file); |
||||||
|
log_file = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void log_print(const char *const text, ...) |
||||||
|
{ |
||||||
|
if (! log_file) { |
||||||
|
return; |
||||||
|
} |
||||||
|
va_list args; |
||||||
|
va_start(args, text); |
||||||
|
vfprintf(log_file, text, args); |
||||||
|
va_end(args); |
||||||
|
} |
||||||
|
|
||||||
|
void log_line(const char *const text, ...) |
||||||
|
{ |
||||||
|
if (! log_file) { |
||||||
|
return; |
||||||
|
} |
||||||
|
va_list args; |
||||||
|
va_start(args, text); |
||||||
|
vfprintf(log_file, text, args); |
||||||
|
fprintf(log_file, "\n"); |
||||||
|
va_end(args); |
||||||
|
} |
||||||
|
|
||||||
|
// Handling of individual events.
|
||||||
|
|
||||||
|
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); |
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
if (info->flags & SCS_TELEMETRY_FRAME_START_FLAG_timer_restart) { |
||||||
|
last_timestamp = 0; |
||||||
|
} |
||||||
|
|
||||||
|
// Advance the timestamp by delta since last frame.
|
||||||
|
|
||||||
|
telemetry.timestamp += (info->paused_simulation_time - last_timestamp); |
||||||
|
last_timestamp = info->paused_simulation_time; |
||||||
|
|
||||||
|
// 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; |
||||||
|
} |
||||||
|
|
||||||
|
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[m/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( |
||||||
|
";%f;%f;%d", |
||||||
|
telemetry.speed, |
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
void telemetry_print_attributes(const scs_named_value_t *const attributes) |
||||||
|
{ |
||||||
|
for (const scs_named_value_t *current = 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_s64: { |
||||||
|
log_line("s64 = %" SCS_PF_S64, current->value.value_s64.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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
|
||||||
|
telemetry_print_attributes(info->attributes); |
||||||
|
|
||||||
|
print_header = true; |
||||||
|
} |
||||||
|
|
||||||
|
SCSAPI_VOID telemetry_gameplay_event(const scs_event_t event, const void *const event_info, const scs_context_t UNUSED(context)) |
||||||
|
{ |
||||||
|
// Here we just print the event info.
|
||||||
|
|
||||||
|
const struct scs_telemetry_gameplay_event_t *const info = static_cast<const scs_telemetry_gameplay_event_t *>(event_info); |
||||||
|
log_line("Gameplay event: %s", info->id); |
||||||
|
|
||||||
|
telemetry_print_attributes(info->attributes); |
||||||
|
|
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
assert(value); |
||||||
|
assert(value->type == SCS_VALUE_TYPE_s32); |
||||||
|
assert(context); |
||||||
|
*static_cast<int *>(context) = value->value_s32.value; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Telemetry API initialization function. |
||||||
|
* |
||||||
|
* See scssdk_telemetry.h |
||||||
|
*/ |
||||||
|
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_01) { |
||||||
|
return SCS_RESULT_unsupported; |
||||||
|
} |
||||||
|
|
||||||
|
const scs_telemetry_init_params_v101_t *const version_params = static_cast<const scs_telemetry_init_params_v101_t *>(params); |
||||||
|
if (! init_log()) { |
||||||
|
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) { |
||||||
|
|
||||||
|
// 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; |
||||||
|
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) { |
||||||
|
|
||||||
|
// 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_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 gameplay events.
|
||||||
|
|
||||||
|
version_params->register_for_event(SCS_TELEMETRY_EVENT_gameplay, telemetry_gameplay_event, 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); |
||||||
|
|
||||||
|
// Remember the function we will use for logging.
|
||||||
|
|
||||||
|
game_log = version_params->common.log; |
||||||
|
game_log(SCS_LOG_TYPE_message, "Initializing telemetry log example"); |
||||||
|
|
||||||
|
// Set the structure with defaults.
|
||||||
|
|
||||||
|
memset(&telemetry, 0, sizeof(telemetry)); |
||||||
|
print_header = true; |
||||||
|
last_timestamp = static_cast<scs_timestamp_t>(-1); |
||||||
|
|
||||||
|
// Initially the game is paused.
|
||||||
|
|
||||||
|
output_paused = true; |
||||||
|
return SCS_RESULT_ok; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Telemetry API deinitialization function. |
||||||
|
* |
||||||
|
* See scssdk_telemetry.h |
||||||
|
*/ |
||||||
|
SCSAPI_VOID scs_telemetry_shutdown(void) |
||||||
|
{ |
||||||
|
// Any cleanup needed. The registrations will be removed automatically
|
||||||
|
// so there is no need to do that manually.
|
||||||
|
|
||||||
|
game_log = NULL; |
||||||
|
finish_log(); |
||||||
|
} |
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
BOOL APIENTRY DllMain( |
||||||
|
HMODULE module, |
||||||
|
DWORD reason_for_call, |
||||||
|
LPVOID reseved |
||||||
|
) |
||||||
|
{ |
||||||
|
if (reason_for_call == DLL_PROCESS_DETACH) { |
||||||
|
finish_log(); |
||||||
|
} |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef __linux__ |
||||||
|
void __attribute__ ((destructor)) unload(void) |
||||||
|
{ |
||||||
|
finish_log(); |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,4 @@ |
|||||||
|
LIBRARY telemetry |
||||||
|
EXPORTS |
||||||
|
scs_telemetry_init=scs_telemetry_init |
||||||
|
scs_telemetry_shutdown=scs_telemetry_shutdown |
@ -0,0 +1,485 @@ |
|||||||
|
/**
|
||||||
|
* @brief Example of using a shared memory to pass a mostly fixed set of telemetry |
||||||
|
* data to another process. |
||||||
|
* |
||||||
|
* Note that use of the shared memory reduces precision of the output and |
||||||
|
* increases latency between event and possible reaction. |
||||||
|
*/ |
||||||
|
|
||||||
|
// Windows stuff.
|
||||||
|
|
||||||
|
#define WINVER 0x0500 |
||||||
|
#define _WIN32_WINNT 0x0500 |
||||||
|
#include <windows.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <assert.h> |
||||||
|
#include <stdarg.h> |
||||||
|
|
||||||
|
// SDK
|
||||||
|
|
||||||
|
#include "scssdk_telemetry.h" |
||||||
|
#include "eurotrucks2/scssdk_eut2.h" |
||||||
|
#include "eurotrucks2/scssdk_telemetry_eut2.h" |
||||||
|
#include "amtrucks/scssdk_ats.h" |
||||||
|
#include "amtrucks/scssdk_telemetry_ats.h" |
||||||
|
|
||||||
|
#define UNUSED(x) |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Callbacks remembered from the initialization info. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
scs_telemetry_register_for_channel_t register_for_channel = NULL; |
||||||
|
scs_telemetry_unregister_from_channel_t unregister_from_channel = NULL; |
||||||
|
scs_log_t game_log = NULL; |
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prints message to game log. |
||||||
|
*/ |
||||||
|
void log_line(const scs_log_type_t type, const char *const text, ...) |
||||||
|
{ |
||||||
|
if (! game_log) { |
||||||
|
return; |
||||||
|
} |
||||||
|
char formated[1000]; |
||||||
|
|
||||||
|
va_list args; |
||||||
|
va_start(args, text); |
||||||
|
vsnprintf_s(formated, sizeof(formated), _TRUNCATE, text, args); |
||||||
|
formated[sizeof(formated) - 1] = 0; |
||||||
|
va_end(args); |
||||||
|
|
||||||
|
game_log(type, formated); |
||||||
|
} |
||||||
|
|
||||||
|
const size_t MAX_SUPPORTED_WHEEL_COUNT = 8; |
||||||
|
|
||||||
|
#pragma pack(push) |
||||||
|
#pragma pack(1) |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The layout of the shared memory. |
||||||
|
*/ |
||||||
|
struct telemetry_state_t |
||||||
|
{ |
||||||
|
scs_u8_t running; // Is the telemetry running or it is paused?
|
||||||
|
|
||||||
|
scs_value_dplacement_t ws_truck_placement; // SCS_TELEMETRY_TRUCK_CHANNEL_world_placement
|
||||||
|
|
||||||
|
scs_float_t speedometer_speed; // SCS_TELEMETRY_TRUCK_CHANNEL_speed
|
||||||
|
scs_float_t rpm; // SCS_TELEMETRY_TRUCK_CHANNEL_engine_rpm
|
||||||
|
scs_s32_t gear; // SCS_TELEMETRY_TRUCK_CHANNEL_engine_gear
|
||||||
|
|
||||||
|
scs_float_t steering; // SCS_TELEMETRY_TRUCK_CHANNEL_effective_steering
|
||||||
|
scs_float_t throttle; // SCS_TELEMETRY_TRUCK_CHANNEL_effective_throttle
|
||||||
|
scs_float_t brake; // SCS_TELEMETRY_TRUCK_CHANNEL_effective_brake
|
||||||
|
scs_float_t clutch; // SCS_TELEMETRY_TRUCK_CHANNEL_effective_clutch
|
||||||
|
|
||||||
|
scs_value_fvector_t linear_valocity; // SCS_TELEMETRY_TRUCK_CHANNEL_local_linear_velocity
|
||||||
|
scs_value_fvector_t angular_velocity; // SCS_TELEMETRY_TRUCK_CHANNEL_local_angular_velocity
|
||||||
|
scs_value_fvector_t linear_acceleration; // SCS_TELEMETRY_TRUCK_CHANNEL_local_linear_acceleration
|
||||||
|
scs_value_fvector_t angular_acceleration; // SCS_TELEMETRY_TRUCK_CHANNEL_local_angular_acceleration
|
||||||
|
scs_value_fvector_t cabin_angular_velocity; // SCS_TELEMETRY_TRUCK_CHANNEL_cabin_angular_velocity
|
||||||
|
scs_value_fvector_t cabin_angular_acceleration; // SCS_TELEMETRY_TRUCK_CHANNEL_cabin_angular_acceleration
|
||||||
|
|
||||||
|
scs_u32_t wheel_count; // SCS_TELEMETRY_CONFIG_ATTRIBUTE_wheel_count
|
||||||
|
scs_float_t wheel_deflections[MAX_SUPPORTED_WHEEL_COUNT]; // SCS_TELEMETRY_TRUCK_CHANNEL_wheel_susp_deflection
|
||||||
|
}; |
||||||
|
|
||||||
|
#pragma pack(pop) |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle of the memory mapping. |
||||||
|
*/ |
||||||
|
HANDLE memory_mapping = NULL; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Block inside the shared memory. |
||||||
|
*/ |
||||||
|
telemetry_state_t *shared_memory = NULL; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitialize the shared memory objects. |
||||||
|
*/ |
||||||
|
void deinitialize_shared_memory(void) |
||||||
|
{ |
||||||
|
if (shared_memory) { |
||||||
|
UnmapViewOfFile(shared_memory); |
||||||
|
shared_memory = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
if (memory_mapping) { |
||||||
|
CloseHandle(memory_mapping); |
||||||
|
memory_mapping = NULL; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the shared memory objects. |
||||||
|
*/ |
||||||
|
bool initialize_shared_memory(void) |
||||||
|
{ |
||||||
|
// Setup the mapping.
|
||||||
|
|
||||||
|
const DWORD memory_size = sizeof(telemetry_state_t); |
||||||
|
memory_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, memory_size, "SCSTelemetryExample"); |
||||||
|
if (! memory_mapping) { |
||||||
|
log_line(SCS_LOG_TYPE_error, "Unable to create shared memory %08X", GetLastError()); |
||||||
|
deinitialize_shared_memory(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (GetLastError() == ERROR_ALREADY_EXISTS) { |
||||||
|
log_line(SCS_LOG_TYPE_error, "Shared memory is already in use."); |
||||||
|
deinitialize_shared_memory(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
shared_memory = static_cast<telemetry_state_t *>(MapViewOfFile(memory_mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0)); |
||||||
|
if (! shared_memory) { |
||||||
|
log_line(SCS_LOG_TYPE_error, "Unable to map the view %08X", GetLastError()); |
||||||
|
deinitialize_shared_memory(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// Defaults in the structure.
|
||||||
|
|
||||||
|
memset(shared_memory, 0, memory_size); |
||||||
|
|
||||||
|
// We are always initialized in the paused state.
|
||||||
|
|
||||||
|
shared_memory->running = 0; |
||||||
|
|
||||||
|
// No wheels until we get corresponding configuration message.
|
||||||
|
|
||||||
|
shared_memory->wheel_count = 0; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Float storage callback. |
||||||
|
* |
||||||
|
* Can be used together with SCS_TELEMETRY_CHANNEL_FLAG_no_value in which case it |
||||||
|
* will store zero if the value is not available. |
||||||
|
*/ |
||||||
|
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) |
||||||
|
{ |
||||||
|
assert(context); |
||||||
|
scs_float_t *const storage = static_cast<scs_float_t *>(context); |
||||||
|
|
||||||
|
if (value) { |
||||||
|
assert(value->type == SCS_VALUE_TYPE_float); |
||||||
|
*storage = value->value_float.value; |
||||||
|
} |
||||||
|
else { |
||||||
|
*storage = 0.0f; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief s32 storage callback. |
||||||
|
* |
||||||
|
* Can be used together with SCS_TELEMETRY_CHANNEL_FLAG_no_value in which case it |
||||||
|
* will store zero if the value is not available. |
||||||
|
*/ |
||||||
|
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) |
||||||
|
{ |
||||||
|
assert(context); |
||||||
|
scs_s32_t *const storage = static_cast<scs_s32_t *>(context); |
||||||
|
|
||||||
|
if (value) { |
||||||
|
assert(value->type == SCS_VALUE_TYPE_s32); |
||||||
|
*storage = value->value_s32.value; |
||||||
|
} |
||||||
|
else { |
||||||
|
*storage = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Orientation storage callback. |
||||||
|
* |
||||||
|
* Can be used together with SCS_TELEMETRY_CHANNEL_FLAG_no_value in which case it |
||||||
|
* will store zero if the value is not available. |
||||||
|
*/ |
||||||
|
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); |
||||||
|
scs_value_euler_t *const storage = static_cast<scs_value_euler_t *>(context); |
||||||
|
|
||||||
|
if (value) { |
||||||
|
assert(value->type == SCS_VALUE_TYPE_euler); |
||||||
|
*storage = value->value_euler; |
||||||
|
} |
||||||
|
else { |
||||||
|
storage->heading = 0.0f; |
||||||
|
storage->pitch = 0.0f; |
||||||
|
storage->roll = 0.0f; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vector storage callback. |
||||||
|
* |
||||||
|
* Can be used together with SCS_TELEMETRY_CHANNEL_FLAG_no_value in which case it |
||||||
|
* will store zero if the value is not available. |
||||||
|
*/ |
||||||
|
SCSAPI_VOID telemetry_store_fvector(const scs_string_t name, const scs_u32_t index, const scs_value_t *const value, const scs_context_t context) |
||||||
|
{ |
||||||
|
assert(context); |
||||||
|
scs_value_fvector_t *const storage = static_cast<scs_value_fvector_t *>(context); |
||||||
|
|
||||||
|
if (value) { |
||||||
|
assert(value->type == SCS_VALUE_TYPE_fvector); |
||||||
|
*storage = value->value_fvector; |
||||||
|
} |
||||||
|
else { |
||||||
|
storage->x = 0.0f; |
||||||
|
storage->y = 0.0f; |
||||||
|
storage->z = 0.0f; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Placement storage callback. |
||||||
|
* |
||||||
|
* Can be used together with SCS_TELEMETRY_CHANNEL_FLAG_no_value in which case it |
||||||
|
* will store zeros if the value is not available. |
||||||
|
*/ |
||||||
|
SCSAPI_VOID telemetry_store_dplacement(const scs_string_t name, const scs_u32_t index, const scs_value_t *const value, const scs_context_t context) |
||||||
|
{ |
||||||
|
assert(context); |
||||||
|
scs_value_dplacement_t *const storage = static_cast<scs_value_dplacement_t *>(context); |
||||||
|
|
||||||
|
if (value) { |
||||||
|
assert(value->type == SCS_VALUE_TYPE_dplacement); |
||||||
|
*storage = value->value_dplacement; |
||||||
|
} |
||||||
|
else { |
||||||
|
storage->position.x = 0.0; |
||||||
|
storage->position.y = 0.0; |
||||||
|
storage->position.z = 0.0; |
||||||
|
storage->orientation.heading = 0.0f; |
||||||
|
storage->orientation.pitch = 0.0f; |
||||||
|
storage->orientation.roll = 0.0f; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Finds attribute with specified name in the configuration structure. |
||||||
|
* |
||||||
|
* Returns NULL if the attribute was not found or if it is not of the expected type. |
||||||
|
*/ |
||||||
|
const scs_named_value_t *find_attribute(const scs_telemetry_configuration_t &configuration, const char *const name, const scs_u32_t index, const scs_value_type_t expected_type) |
||||||
|
{ |
||||||
|
for (const scs_named_value_t *current = configuration.attributes; current->name; ++current) { |
||||||
|
if ((current->index != index) || (strcmp(current->name, name) != 0)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
if (current->value.type == expected_type) { |
||||||
|
return current; |
||||||
|
} |
||||||
|
log_line(SCS_LOG_TYPE_error, "Attribute %s has unexpected type %u", name, static_cast<unsigned>(current->value.type)); |
||||||
|
break; |
||||||
|
} |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called whenever the game pauses or unpauses its telemetry output. |
||||||
|
*/ |
||||||
|
SCSAPI_VOID telemetry_pause(const scs_event_t event, const void *const UNUSED(event_info), const scs_context_t UNUSED(context)) |
||||||
|
{ |
||||||
|
shared_memory->running = (event == SCS_TELEMETRY_EVENT_started) ? 1 : 0; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called whenever configuration changes. |
||||||
|
*/ |
||||||
|
SCSAPI_VOID telemetry_configuration(const scs_event_t event, const void *const event_info, const scs_context_t UNUSED(context)) |
||||||
|
{ |
||||||
|
// We currently only care for the truck telemetry info.
|
||||||
|
|
||||||
|
const struct scs_telemetry_configuration_t *const info = static_cast<const scs_telemetry_configuration_t *>(event_info); |
||||||
|
if (strcmp(info->id, SCS_TELEMETRY_CONFIG_truck) != 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Determine number of wheels up to the number supported by our memory structure.
|
||||||
|
|
||||||
|
const scs_named_value_t *const wheel_count_attr = find_attribute(*info, SCS_TELEMETRY_CONFIG_ATTRIBUTE_wheel_count, SCS_U32_NIL, SCS_VALUE_TYPE_u32); |
||||||
|
size_t wheel_count = wheel_count_attr ? wheel_count_attr->value.value_u32.value : 0; |
||||||
|
if (wheel_count > MAX_SUPPORTED_WHEEL_COUNT) { |
||||||
|
wheel_count = MAX_SUPPORTED_WHEEL_COUNT; |
||||||
|
} |
||||||
|
|
||||||
|
// Update the wheel-related channel registrations to match.
|
||||||
|
|
||||||
|
while (shared_memory->wheel_count > wheel_count) { |
||||||
|
--shared_memory->wheel_count; |
||||||
|
shared_memory->wheel_deflections[shared_memory->wheel_count] = 0.0f; |
||||||
|
unregister_from_channel(SCS_TELEMETRY_TRUCK_CHANNEL_wheel_susp_deflection, shared_memory->wheel_count, SCS_VALUE_TYPE_float); |
||||||
|
} |
||||||
|
while (shared_memory->wheel_count < wheel_count) { |
||||||
|
register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_wheel_susp_deflection, shared_memory->wheel_count, SCS_VALUE_TYPE_float, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_float, (shared_memory->wheel_deflections + shared_memory->wheel_count)); |
||||||
|
++shared_memory->wheel_count; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Telemetry API initialization function. |
||||||
|
* |
||||||
|
* See scssdk_telemetry.h |
||||||
|
*/ |
||||||
|
SCSAPI_RESULT scs_telemetry_init(const scs_u32_t version, const scs_telemetry_init_params_t *const params) |
||||||
|
{ |
||||||
|
// We currently support only one version of the API.
|
||||||
|
|
||||||
|
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); |
||||||
|
game_log = version_params->common.log; |
||||||
|
|
||||||
|
// Check application version.
|
||||||
|
|
||||||
|
log_line(SCS_LOG_TYPE_message, "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) { |
||||||
|
|
||||||
|
// Below the minimum version there might be some missing features (only minor change) or
|
||||||
|
// incompatible values (major change).
|
||||||
|
|
||||||
|
if (version_params->common.game_version < SCS_TELEMETRY_EUT2_GAME_VERSION_1_03) { // Fixed the wheels.count attribute
|
||||||
|
log_line(SCS_LOG_TYPE_error, "Too old version of the game"); |
||||||
|
game_log = NULL; |
||||||
|
return SCS_RESULT_unsupported; |
||||||
|
} |
||||||
|
|
||||||
|
if (version_params->common.game_version < SCS_TELEMETRY_EUT2_GAME_VERSION_1_07) { // Fixed the angular acceleration calculation
|
||||||
|
log_line(SCS_LOG_TYPE_warning, "This version of the game has less precise output of angular acceleration of the cabin"); |
||||||
|
} |
||||||
|
|
||||||
|
// 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(SCS_LOG_TYPE_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) { |
||||||
|
|
||||||
|
// 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_ATS_GAME_VERSION_1_00; |
||||||
|
if (version_params->common.game_version < MINIMAL_VERSION) { |
||||||
|
log_line(SCS_LOG_TYPE_warning, "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(SCS_LOG_TYPE_warning, "WARNING: Too new major version of the game, some features might behave incorrectly"); |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
log_line(SCS_LOG_TYPE_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_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) |
||||||
|
; |
||||||
|
if (! events_registered) { |
||||||
|
|
||||||
|
// Registrations created by unsuccessful initialization are
|
||||||
|
// cleared automatically so we can simply exit.
|
||||||
|
|
||||||
|
log_line(SCS_LOG_TYPE_error, "Unable to register event callbacks"); |
||||||
|
game_log = NULL; |
||||||
|
return SCS_RESULT_generic_error; |
||||||
|
} |
||||||
|
|
||||||
|
// Initialize the shared memory.
|
||||||
|
|
||||||
|
if (! initialize_shared_memory()) { |
||||||
|
log_line(SCS_LOG_TYPE_error, "Unable to initialize shared memory"); |
||||||
|
game_log = NULL; |
||||||
|
return SCS_RESULT_generic_error; |
||||||
|
} |
||||||
|
|
||||||
|
// Register all changes we are interested in. Note that some wheel-related channels will be initialized when we
|
||||||
|
// receive a configuration event. 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 failures so the unsupported channels will remain at theirs default value.
|
||||||
|
|
||||||
|
#define register_channel(name, index, type, field) version_params->register_for_channel(SCS_TELEMETRY_##name, index, SCS_VALUE_TYPE_##type, SCS_TELEMETRY_CHANNEL_FLAG_no_value, telemetry_store_##type, &shared_memory->field); |
||||||
|
|
||||||
|
register_channel(TRUCK_CHANNEL_world_placement, SCS_U32_NIL, dplacement, ws_truck_placement); |
||||||
|
|
||||||
|
register_channel(TRUCK_CHANNEL_speed, SCS_U32_NIL, float, speedometer_speed); |
||||||
|
register_channel(TRUCK_CHANNEL_engine_rpm, SCS_U32_NIL, float, rpm); |
||||||
|
register_channel(TRUCK_CHANNEL_engine_gear, SCS_U32_NIL, s32, gear); |
||||||
|
|
||||||
|
register_channel(TRUCK_CHANNEL_effective_steering, SCS_U32_NIL, float, steering); |
||||||
|
register_channel(TRUCK_CHANNEL_effective_throttle, SCS_U32_NIL, float, throttle); |
||||||
|
register_channel(TRUCK_CHANNEL_effective_brake, SCS_U32_NIL, float, brake); |
||||||
|
register_channel(TRUCK_CHANNEL_effective_clutch, SCS_U32_NIL, float, clutch); |
||||||
|
|
||||||
|
register_channel(TRUCK_CHANNEL_local_linear_velocity, SCS_U32_NIL, fvector, linear_valocity); |
||||||
|
register_channel(TRUCK_CHANNEL_local_angular_velocity, SCS_U32_NIL, fvector, angular_velocity); |
||||||
|
register_channel(TRUCK_CHANNEL_local_linear_acceleration, SCS_U32_NIL, fvector, linear_acceleration); |
||||||
|
register_channel(TRUCK_CHANNEL_local_angular_acceleration, SCS_U32_NIL, fvector, angular_acceleration); |
||||||
|
register_channel(TRUCK_CHANNEL_cabin_angular_velocity, SCS_U32_NIL, fvector, cabin_angular_velocity); |
||||||
|
register_channel(TRUCK_CHANNEL_cabin_angular_acceleration, SCS_U32_NIL, fvector, cabin_angular_acceleration); |
||||||
|
|
||||||
|
#undef register_channel |
||||||
|
|
||||||
|
// Remember other the functions we will use in the future.
|
||||||
|
|
||||||
|
register_for_channel = version_params->register_for_channel; |
||||||
|
unregister_from_channel = version_params->unregister_from_channel; |
||||||
|
|
||||||
|
// We are done.
|
||||||
|
|
||||||
|
log_line(SCS_LOG_TYPE_message, "Memory telemetry example initialized"); |
||||||
|
return SCS_RESULT_ok; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Telemetry API deinitialization function. |
||||||
|
* |
||||||
|
* See scssdk_telemetry.h |
||||||
|
*/ |
||||||
|
SCSAPI_VOID scs_telemetry_shutdown(void) |
||||||
|
{ |
||||||
|
// Any cleanup needed. The registrations will be removed automatically
|
||||||
|
// so there is no need to do that manually.
|
||||||
|
|
||||||
|
deinitialize_shared_memory(); |
||||||
|
|
||||||
|
unregister_from_channel = NULL; |
||||||
|
register_for_channel = NULL; |
||||||
|
game_log = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
|
||||||
|
BOOL APIENTRY DllMain( |
||||||
|
HMODULE module, |
||||||
|
DWORD reason_for_call, |
||||||
|
LPVOID reseved |
||||||
|
) |
||||||
|
{ |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
|
||||||
|
// EOF //
|
@ -0,0 +1,4 @@ |
|||||||
|
LIBRARY telemetry_mem |
||||||
|
EXPORTS |
||||||
|
scs_telemetry_init=scs_telemetry_init |
||||||
|
scs_telemetry_shutdown=scs_telemetry_shutdown |
@ -0,0 +1,429 @@ |
|||||||
|
/**
|
||||||
|
* @brief Logs calculated world space position of the head to demonstrate |
||||||
|
* combination of telemetry channels and configuration data. |
||||||
|
*/ |
||||||
|
|
||||||
|
// Windows stuff.
|
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
# define WINVER 0x0500 |
||||||
|
# define _WIN32_WINNT 0x0500 |
||||||
|
# include <windows.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <assert.h> |
||||||
|
#include <stdarg.h> |
||||||
|
#include <math.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
// SDK
|
||||||
|
|
||||||
|
#include "scssdk_telemetry.h" |
||||||
|
#include "eurotrucks2/scssdk_eut2.h" |
||||||
|
#include "eurotrucks2/scssdk_telemetry_eut2.h" |
||||||
|
#include "amtrucks/scssdk_ats.h" |
||||||
|
#include "amtrucks/scssdk_telemetry_ats.h" |
||||||
|
|
||||||
|
#define UNUSED(x) |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logging support. |
||||||
|
*/ |
||||||
|
FILE *log_file = NULL; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tracking of paused state of the game. |
||||||
|
*/ |
||||||
|
bool output_paused = true; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Combined telemetry data. |
||||||
|
*/ |
||||||
|
struct telemetry_state_t |
||||||
|
{ |
||||||
|
// Configuration.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Position of the cabin joint in vehicle space. |
||||||
|
*/ |
||||||
|
scs_value_fvector_t cabin_position; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Base position of the head in the cabin. |
||||||
|
*/ |
||||||
|
scs_value_fvector_t head_position; |
||||||
|
|
||||||
|
// Channels.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief World space position & orientation of the truck. |
||||||
|
*/ |
||||||
|
scs_value_dplacement_t truck_placement; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Offset of the cabin from the default position. |
||||||
|
*/ |
||||||
|
scs_value_fplacement_t cabin_offset; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Offset of the head from its default position. |
||||||
|
*/ |
||||||
|
scs_value_fplacement_t head_offset; |
||||||
|
|
||||||
|
} telemetry; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function writting message to the game internal log. |
||||||
|
*/ |
||||||
|
scs_log_t game_log = NULL; |
||||||
|
|
||||||
|
// Management of the log file.
|
||||||
|
|
||||||
|
bool init_log(void) |
||||||
|
{ |
||||||
|
if (log_file) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
log_file = fopen("telemetry_position.log", "wt"); |
||||||
|
if (! log_file) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
fprintf(log_file, "Log opened\n"); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void finish_log(void) |
||||||
|
{ |
||||||
|
if (! log_file) { |
||||||
|
return; |
||||||
|
} |
||||||
|
fprintf(log_file, "Log ended\n"); |
||||||
|
fclose(log_file); |
||||||
|
log_file = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void log_print(const char *const text, ...) |
||||||
|
{ |
||||||
|
if (! log_file) { |
||||||
|
return; |
||||||
|
} |
||||||
|
va_list args; |
||||||
|
va_start(args, text); |
||||||
|
vfprintf(log_file, text, args); |
||||||
|
va_end(args); |
||||||
|
} |
||||||
|
|
||||||
|
void log_line(const char *const text, ...) |
||||||
|
{ |
||||||
|
if (! log_file) { |
||||||
|
return; |
||||||
|
} |
||||||
|
va_list args; |
||||||
|
va_start(args, text); |
||||||
|
vfprintf(log_file, text, args); |
||||||
|
fprintf(log_file, "\n"); |
||||||
|
va_end(args); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds two float vectors. |
||||||
|
*/ |
||||||
|
scs_value_fvector_t add(const scs_value_fvector_t &first, const scs_value_fvector_t &second) |
||||||
|
{ |
||||||
|
scs_value_fvector_t result; |
||||||
|
result.x = first.x + second.x; |
||||||
|
result.y = first.y + second.y; |
||||||
|
result.z = first.z + second.z; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds float vector to double vector. |
||||||
|
*/ |
||||||
|
scs_value_dvector_t add(const scs_value_dvector_t &first, const scs_value_fvector_t &second) |
||||||
|
{ |
||||||
|
scs_value_dvector_t result; |
||||||
|
result.x = first.x + second.x; |
||||||
|
result.y = first.y + second.y; |
||||||
|
result.z = first.z + second.z; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rotates specified vector by specified orientation. |
||||||
|
*/ |
||||||
|
scs_value_fvector_t rotate(const scs_value_euler_t &orientation, const scs_value_fvector_t &vector) |
||||||
|
{ |
||||||
|
const float heading_radians = orientation.heading * 6.2831853071795864769252867665590058f; |
||||||
|
const float pitch_radians = orientation.pitch * 6.2831853071795864769252867665590058f; |
||||||
|
const float roll_radians = orientation.roll * 6.2831853071795864769252867665590058f; |
||||||
|
|
||||||
|
const float cos_heading = cosf(heading_radians); |
||||||
|
const float sin_heading = sinf(heading_radians); |
||||||
|
const float cos_pitch = cosf(pitch_radians); |
||||||
|
const float sin_pitch = sinf(pitch_radians); |
||||||
|
const float cos_roll = cosf(roll_radians); |
||||||
|
const float sin_roll = sinf(roll_radians); |
||||||
|
|
||||||
|
// Roll around Z axis.
|
||||||
|
|
||||||
|
const float post_roll_x = vector.x * cos_roll - vector.y * sin_roll; |
||||||
|
const float post_roll_y = vector.x * sin_roll + vector.y * cos_roll; |
||||||
|
const float post_roll_z = vector.z; |
||||||
|
|
||||||
|
// Pitch around X axis.
|
||||||
|
|
||||||
|
const float post_pitch_x = post_roll_x; |
||||||
|
const float post_pitch_y = post_roll_y * cos_pitch - post_roll_z * sin_pitch; |
||||||
|
const float post_pitch_z = post_roll_y * sin_pitch + post_roll_z * cos_pitch; |
||||||
|
|
||||||
|
// Heading around Y axis.
|
||||||
|
|
||||||
|
scs_value_fvector_t result; |
||||||
|
result.x = post_pitch_x * cos_heading + post_pitch_z * sin_heading; |
||||||
|
result.y = post_pitch_y; |
||||||
|
result.z = -post_pitch_x * sin_heading + post_pitch_z * cos_heading; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
// Handling of individual events.
|
||||||
|
|
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
// Calculate the position. Note that the value differs slightly from the values used by the
|
||||||
|
// game for rendering. This code evaluates the value using data directly corresponding to
|
||||||
|
// simulation steps instead of interpolating between two neighbour simulated positions like
|
||||||
|
// the game does. It also calculates the value for each simulation frame instead of once per
|
||||||
|
// rendering frame like the game does.
|
||||||
|
|
||||||
|
const scs_value_fvector_t head_position_in_cabin_space = add(telemetry.head_position, telemetry.head_offset.position); |
||||||
|
const scs_value_fvector_t head_position_in_vehicle_space = add(add(telemetry.cabin_position, telemetry.cabin_offset.position), rotate(telemetry.cabin_offset.orientation, head_position_in_cabin_space)); |
||||||
|
const scs_value_dvector_t head_position_in_world_space = add(telemetry.truck_placement.position, rotate(telemetry.truck_placement.orientation, head_position_in_vehicle_space)); |
||||||
|
|
||||||
|
log_line("%f;%f;%f", head_position_in_world_space.x, head_position_in_world_space.y, head_position_in_world_space.z); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Finds attribute with specified name in the configuration structure. |
||||||
|
* |
||||||
|
* Returns NULL if the attribute was not found or if it is not of the expected type. |
||||||
|
*/ |
||||||
|
const scs_named_value_t *find_attribute(const scs_telemetry_configuration_t &configuration, const char *const name, const scs_u32_t index, const scs_value_type_t expected_type) |
||||||
|
{ |
||||||
|
for (const scs_named_value_t *current = configuration.attributes; current->name; ++current) { |
||||||
|
if ((current->index != index) || (strcmp(current->name, name) != 0)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
if (current->value.type == expected_type) { |
||||||
|
return current; |
||||||
|
} |
||||||
|
log_line("ERROR: Attribute %s has unexpected type %u", name, static_cast<unsigned>(current->value.type)); |
||||||
|
break; |
||||||
|
} |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
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); |
||||||
|
|
||||||
|
// We currently only care for the truck telemetry info.
|
||||||
|
|
||||||
|
if (strcmp(info->id, SCS_TELEMETRY_CONFIG_truck) != 0) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Extract the value we are interested in.
|
||||||
|
|
||||||
|
const scs_named_value_t *const cabin_position = find_attribute(*info, SCS_TELEMETRY_CONFIG_ATTRIBUTE_cabin_position, SCS_U32_NIL, SCS_VALUE_TYPE_fvector); |
||||||
|
if (cabin_position) { |
||||||
|
telemetry.cabin_position = cabin_position->value.value_fvector; |
||||||
|
} |
||||||
|
else { |
||||||
|
// Vehicle without separate cabin.
|
||||||
|
|
||||||
|
telemetry.cabin_position.x = telemetry.cabin_position.y = telemetry.cabin_position.z = 0.0f; |
||||||
|
} |
||||||
|
|
||||||
|
const scs_named_value_t *const head_position = find_attribute(*info, SCS_TELEMETRY_CONFIG_ATTRIBUTE_head_position, SCS_U32_NIL, SCS_VALUE_TYPE_fvector); |
||||||
|
if (head_position) { |
||||||
|
telemetry.head_position = head_position->value.value_fvector; |
||||||
|
} |
||||||
|
else { |
||||||
|
log_line("WARNING: Head position unavailable"); |
||||||
|
telemetry.head_position.x = telemetry.head_position.y = telemetry.head_position.z = 0.0f; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Handling of individual channels.
|
||||||
|
|
||||||
|
SCSAPI_VOID telemetry_store_fplacement(const scs_string_t name, const scs_u32_t index, const scs_value_t *const value, const scs_context_t context) |
||||||
|
{ |
||||||
|
assert(context); |
||||||
|
assert(value); |
||||||
|
assert(value->type == SCS_VALUE_TYPE_fplacement); |
||||||
|
scs_value_fplacement_t *const placement = static_cast<scs_value_fplacement_t *>(context); |
||||||
|
*placement = value->value_fplacement; |
||||||
|
} |
||||||
|
|
||||||
|
SCSAPI_VOID telemetry_store_dplacement(const scs_string_t name, const scs_u32_t index, const scs_value_t *const value, const scs_context_t context) |
||||||
|
{ |
||||||
|
assert(context); |
||||||
|
assert(value); |
||||||
|
assert(value->type == SCS_VALUE_TYPE_dplacement); |
||||||
|
scs_value_dplacement_t *const placement = static_cast<scs_value_dplacement_t *>(context); |
||||||
|
*placement = value->value_dplacement; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Telemetry API initialization function. |
||||||
|
* |
||||||
|
* See scssdk_telemetry.h |
||||||
|
*/ |
||||||
|
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_log()) { |
||||||
|
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) { |
||||||
|
|
||||||
|
// 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; |
||||||
|
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) { |
||||||
|
|
||||||
|
// 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_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_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) |
||||||
|
; |
||||||
|
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 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_dplacement, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_dplacement, &telemetry.truck_placement); |
||||||
|
version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_cabin_offset, SCS_U32_NIL, SCS_VALUE_TYPE_fplacement, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_fplacement, &telemetry.cabin_offset); |
||||||
|
version_params->register_for_channel(SCS_TELEMETRY_TRUCK_CHANNEL_head_offset , SCS_U32_NIL, SCS_VALUE_TYPE_fplacement, SCS_TELEMETRY_CHANNEL_FLAG_none, telemetry_store_fplacement, &telemetry.head_offset); |
||||||
|
|
||||||
|
game_log = version_params->common.log; |
||||||
|
|
||||||
|
// Set the structure with defaults.
|
||||||
|
|
||||||
|
memset(&telemetry, 0, sizeof(telemetry)); |
||||||
|
|
||||||
|
// Initially the game is paused.
|
||||||
|
|
||||||
|
output_paused = true; |
||||||
|
return SCS_RESULT_ok; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Telemetry API deinitialization function. |
||||||
|
* |
||||||
|
* See scssdk_telemetry.h |
||||||
|
*/ |
||||||
|
SCSAPI_VOID scs_telemetry_shutdown(void) |
||||||
|
{ |
||||||
|
// Any cleanup needed. The registrations will be removed automatically
|
||||||
|
// so there is no need to do that manually.
|
||||||
|
|
||||||
|
game_log = NULL; |
||||||
|
finish_log(); |
||||||
|
} |
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
|
||||||
|
#ifdef _WIN32 |
||||||
|
BOOL APIENTRY DllMain( |
||||||
|
HMODULE module, |
||||||
|
DWORD reason_for_call, |
||||||
|
LPVOID reseved |
||||||
|
) |
||||||
|
{ |
||||||
|
if (reason_for_call == DLL_PROCESS_DETACH) { |
||||||
|
finish_log(); |
||||||
|
} |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef __linux__ |
||||||
|
void __attribute__ ((destructor)) unload(void) |
||||||
|
{ |
||||||
|
finish_log(); |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,4 @@ |
|||||||
|
LIBRARY telemetry_position |
||||||
|
EXPORTS |
||||||
|
scs_telemetry_init=scs_telemetry_init |
||||||
|
scs_telemetry_shutdown=scs_telemetry_shutdown |
@ -0,0 +1,22 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_ats.h |
||||||
|
* |
||||||
|
* @brief ATS specific constants. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_ATS_H |
||||||
|
#define SCSSDK_ATS_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Value used in the scs_sdk_init_params_t::game_id to identify this game. |
||||||
|
*/ |
||||||
|
#define SCS_GAME_ID_ATS "ats" |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_ATS_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,31 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_input_ats.h |
||||||
|
* |
||||||
|
* @brief ATS input specific constants. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_INPUT_ATS_H |
||||||
|
#define SCSSDK_INPUT_ATS_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Value used in the scs_sdk_init_params_t::game_version |
||||||
|
* |
||||||
|
* Changes in the major version indicate incompatible changes. |
||||||
|
* Changes in the minor version indicate compatible changes (e.g. added more types) |
||||||
|
* |
||||||
|
* Changes: |
||||||
|
* 1.00 - initial version |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
#define SCS_INPUT_ATS_GAME_VERSION_1_00 SCS_MAKE_VERSION(1, 0) |
||||||
|
#define SCS_INPUT_ATS_GAME_VERSION_CURRENT SCS_INPUT_ATS_GAME_VERSION_1_00 |
||||||
|
//@}
|
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_INPUT_ATS_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,77 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_ats.h |
||||||
|
* |
||||||
|
* @brief ATS telemetry specific constants. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_ATS_H |
||||||
|
#define SCSSDK_TELEMETRY_ATS_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
#include "../common/scssdk_telemetry_common_configs.h" |
||||||
|
#include "../common/scssdk_telemetry_common_channels.h" |
||||||
|
#include "../common/scssdk_telemetry_truck_common_channels.h" |
||||||
|
#include "../common/scssdk_telemetry_trailer_common_channels.h" |
||||||
|
#include "../common/scssdk_telemetry_job_common_channels.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Value used in the scs_sdk_init_params_t::game_version |
||||||
|
* |
||||||
|
* Changes in the major version indicate incompatible changes (e.g. changed interpretation |
||||||
|
* of the channel value). Change of major version is highly discouraged, creation of |
||||||
|
* alternative channel is preferred solution if necessary. |
||||||
|
* Changes in the minor version indicate compatible changes (e.g. added channel, more supported |
||||||
|
* value types). Removal of channel is also compatible change however it is recommended |
||||||
|
* to keep the channel with some default value. |
||||||
|
* |
||||||
|
* Changes: |
||||||
|
* 1.00 - initial version - corresponds to 1.12 in ETS2 |
||||||
|
* 1.01 - added support for multiple trailers (doubles, triples), trailer ownership support, |
||||||
|
* gameplay events support added |
||||||
|
* 1.02 - added planned_distance_km to active job info |
||||||
|
* 1.03 - added support for 'avoid_inspection', 'illegal_border_crossing' and 'hard_shoulder_violation' offence type in 'player.fined' gameplay event |
||||||
|
* 1.04 - added differential lock, lift axle and hazard warning channels |
||||||
|
* 1.05 - added multiplayer time offset and trailer body wear channel, fixed trailer chassis wear channel |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
#define SCS_TELEMETRY_ATS_GAME_VERSION_1_00 SCS_MAKE_VERSION(1, 0) |
||||||
|
#define SCS_TELEMETRY_ATS_GAME_VERSION_1_01 SCS_MAKE_VERSION(1, 1) |
||||||
|
#define SCS_TELEMETRY_ATS_GAME_VERSION_1_02 SCS_MAKE_VERSION(1, 2) // Patch 1.36
|
||||||
|
#define SCS_TELEMETRY_ATS_GAME_VERSION_1_03 SCS_MAKE_VERSION(1, 3) // Patch 1.36
|
||||||
|
#define SCS_TELEMETRY_ATS_GAME_VERSION_1_04 SCS_MAKE_VERSION(1, 4) // Patch 1.41
|
||||||
|
#define SCS_TELEMETRY_ATS_GAME_VERSION_1_05 SCS_MAKE_VERSION(1, 5) // Patch 1.45
|
||||||
|
#define SCS_TELEMETRY_ATS_GAME_VERSION_CURRENT SCS_TELEMETRY_ATS_GAME_VERSION_1_05 |
||||||
|
//@}
|
||||||
|
|
||||||
|
// Game specific units.
|
||||||
|
//
|
||||||
|
// @li The game uses US Dolars as internal currency provided
|
||||||
|
// by the telemetry unless documented otherwise.
|
||||||
|
|
||||||
|
// Channels defined in scssdk_telemetry_common_channels.h,
|
||||||
|
// scssdk_telemetry_job_common_channels.h,
|
||||||
|
// scssdk_telemetry_truck_common_channels.h and
|
||||||
|
// scssdk_telemetry_trailer_common_channels.h are supported
|
||||||
|
// with following exceptions and limitations as of v1.00:
|
||||||
|
//
|
||||||
|
// @li Adblue related channels are not supported.
|
||||||
|
// @li The fuel_average_consumption is currently mostly static and depends
|
||||||
|
// on presence of the trailer and skills of the driver instead
|
||||||
|
// of the workload of the engine.
|
||||||
|
// @li Rolling rotation of trailer wheels is determined from linear
|
||||||
|
// movement.
|
||||||
|
// @li The pressures, temperatures and voltages are not simulated.
|
||||||
|
// They are very loosely approximated.
|
||||||
|
|
||||||
|
// Configurations defined in scssdk_telemetry_common_configs.h are
|
||||||
|
// supported with following exceptions and limitations as of v1.00:
|
||||||
|
//
|
||||||
|
// @li The localized strings are not updated when different in-game
|
||||||
|
// language is selected.
|
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_ATS_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,67 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_common_channels.h |
||||||
|
* |
||||||
|
* @brief Telemetry specific channels which might be used by more than one game. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_COMMON_CHANNELS_H |
||||||
|
#define SCSSDK_TELEMETRY_COMMON_CHANNELS_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scale applied to distance and time to compensate |
||||||
|
* for the scale of the map (e.g. 1s of real time corresponds to local_scale |
||||||
|
* seconds of simulated game time). |
||||||
|
* |
||||||
|
* Games which use real 1:1 maps will not provide this |
||||||
|
* channel. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CHANNEL_local_scale "local.scale" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Absolute in-game time. |
||||||
|
* |
||||||
|
* Represented in number of in-game minutes since beginning (i.e. 00:00) |
||||||
|
* of the first in-game day. |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CHANNEL_game_time "game.time" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Offset from the game_time simulated in the local economy to the |
||||||
|
* game time of the Convoy multiplayer server. |
||||||
|
* |
||||||
|
* The value of this channel can change frequently during the Convoy |
||||||
|
* session. For example when the user enters the desktop, the local |
||||||
|
* economy time stops however the multiplayer time continues to run |
||||||
|
* so the value will start to change. |
||||||
|
* |
||||||
|
* Represented in in-game minutes. Set to 0 when multiplayer is not active. |
||||||
|
* |
||||||
|
* Type: s32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CHANNEL_multiplayer_time_offset "multiplayer.time.offset" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Time until next rest stop. |
||||||
|
* |
||||||
|
* When the fatique simulation is disabled, the behavior of this channel |
||||||
|
* is implementation dependent. The game might provide the value which would |
||||||
|
* apply if it was enabled or provide no value at all. |
||||||
|
* |
||||||
|
* Represented in in-game minutes. |
||||||
|
* |
||||||
|
* Type: s32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CHANNEL_next_rest_stop "rest.stop" |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_COMMON_CHANNELS_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,654 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_common_configs.h |
||||||
|
* |
||||||
|
* @brief Telemetry specific constants for configs. |
||||||
|
* |
||||||
|
* This file defines truck specific telemetry constants which |
||||||
|
* might be used by more than one SCS game. See game-specific |
||||||
|
* file to determine which constants are supported by specific |
||||||
|
* game. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_COMMON_CONFIGS_H |
||||||
|
#define SCSSDK_TELEMETRY_COMMON_CONFIGS_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The count of the trailers supported by SDK. |
||||||
|
* |
||||||
|
* The maximum number of trailers that can be returned by the telemetry SDK. |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_trailers_count 10 |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configuration of the substances. |
||||||
|
* |
||||||
|
* Attribute index is index of the substance. |
||||||
|
* |
||||||
|
* Supported attributes: |
||||||
|
* @li id |
||||||
|
* TODO: Whatever additional info necessary. |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_substances "substances" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Static configuration of the controls. |
||||||
|
* |
||||||
|
* @li shifter_type |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_controls "controls" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configuration of the h-shifter. |
||||||
|
* |
||||||
|
* When evaluating the selected gear, find slot which matches |
||||||
|
* the handle position and bitmask of on/off state of selectors. |
||||||
|
* If one is found, it contains the resulting gear. Otherwise |
||||||
|
* a neutral is assumed. |
||||||
|
* |
||||||
|
* Supported attributes: |
||||||
|
* @li selector_count |
||||||
|
* @li resulting gear index for each slot |
||||||
|
* @li handle position index for each slot |
||||||
|
* @li bitmask of selectors for each slot |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_hshifter "hshifter" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Static configuration of the truck. |
||||||
|
* |
||||||
|
* If empty set of attributes is returned, there is no configured truck. |
||||||
|
* |
||||||
|
* Supported attributes: |
||||||
|
* @li brand_id |
||||||
|
* @li brand |
||||||
|
* @li id |
||||||
|
* @li name |
||||||
|
* @li fuel_capacity |
||||||
|
* @li fuel_warning_factor |
||||||
|
* @li adblue_capacity |
||||||
|
* @li ablue_warning_factor |
||||||
|
* @li air_pressure_warning |
||||||
|
* @li air_pressure_emergency |
||||||
|
* @li oil_pressure_warning |
||||||
|
* @li water_temperature_warning |
||||||
|
* @li battery_voltage_warning |
||||||
|
* @li rpm_limit |
||||||
|
* @li foward_gear_count |
||||||
|
* @li reverse_gear_count |
||||||
|
* @li retarder_step_count |
||||||
|
* @li cabin_position |
||||||
|
* @li head_position |
||||||
|
* @li hook_position |
||||||
|
* @li license_plate |
||||||
|
* @li license_plate_country |
||||||
|
* @li license_plate_country_id |
||||||
|
* @li wheel_count |
||||||
|
* @li wheel positions for wheel_count wheels |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_truck "truck" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Backward compatibility static configuration of the first trailer (attributes are equal to trailer.0). |
||||||
|
* |
||||||
|
* The trailers configurations are returned using trailer.[index] |
||||||
|
* (e.g. trailer.0, trailer.1, ... trailer.9 ...) |
||||||
|
* |
||||||
|
* SDK currently can return up to @c SCS_TELEMETRY_trailers_count trailers. |
||||||
|
* |
||||||
|
* If there are less trailers in game than @c SCS_TELEMETRY_trailers_count |
||||||
|
* telemetry will return all configurations however starting from the trailer after last |
||||||
|
* existing one its attributes will be empty. |
||||||
|
* |
||||||
|
* Supported attributes: |
||||||
|
* @li id |
||||||
|
* @li cargo_accessory_id |
||||||
|
* @li hook_position |
||||||
|
* @li brand_id |
||||||
|
* @li brand |
||||||
|
* @li name |
||||||
|
* @li chain_type (reported only for first trailer) |
||||||
|
* @li body_type (reported only for first trailer) |
||||||
|
* @li license_plate |
||||||
|
* @li license_plate_country |
||||||
|
* @li license_plate_country_id |
||||||
|
* @li wheel_count |
||||||
|
* @li wheel offsets for wheel_count wheels |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_trailer "trailer" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Static configuration of the job. |
||||||
|
* |
||||||
|
* If empty set of attributes is returned, there is no job. |
||||||
|
* |
||||||
|
* Supported attributes: |
||||||
|
* @li cargo_id |
||||||
|
* @li cargo |
||||||
|
* @li cargo_mass |
||||||
|
* @li destination_city_id |
||||||
|
* @li destination_city |
||||||
|
* @li source_city_id |
||||||
|
* @li source_city |
||||||
|
* @li destination_company_id (only available for non special transport jobs) |
||||||
|
* @li destination_company (only available for non special transport jobs) |
||||||
|
* @li source_company_id (only available for non special transport jobs) |
||||||
|
* @li source_company (only available for non special transport jobs) |
||||||
|
* @li income - represents expected income for the job without any penalties |
||||||
|
* @li delivery_time |
||||||
|
* @li is_cargo_loaded |
||||||
|
* @li job_market |
||||||
|
* @li special_job |
||||||
|
* @li planned_distance_km |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_job "job" |
||||||
|
|
||||||
|
// Attributes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brand id for configuration purposes. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_brand_id "brand_id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brand for display purposes. |
||||||
|
* |
||||||
|
* Localized using the current in-game language. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_brand "brand" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name for internal use by code. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters and dots. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_id "id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of cargo accessory for internal use by code. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters and dots. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_cargo_accessory_id "cargo.accessory.id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of trailer chain type. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters and dots. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_chain_type "chain.type" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of trailer body type. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters and dots. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_body_type "body.type" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vehicle license plate. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_license_plate "license.plate" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The id representing license plate country. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_license_plate_country_id "license.plate.country.id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The name of the license plate country. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_license_plate_country "license.plate.country" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name for display purposes. |
||||||
|
* |
||||||
|
* Localized using the current in-game language. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_name "name" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fuel tank capacity in litres. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_fuel_capacity "fuel.capacity" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fraction of the fuel capacity below which |
||||||
|
* is activated the fuel warning. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_fuel_warning_factor "fuel.warning.factor" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AdBlue tank capacity in litres. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_adblue_capacity "adblue.capacity" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fraction of the adblue capacity below which |
||||||
|
* is activated the adblue warning. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_adblue_warning_factor "adblue.warning.factor" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pressure of the air in the tank below which |
||||||
|
* the warning activates. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_air_pressure_warning "brake.air.pressure.warning" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pressure of the air in the tank below which |
||||||
|
* the emergency brakes activate. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_air_pressure_emergency "brake.air.pressure.emergency" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pressure of the oil below which the warning activates. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_oil_pressure_warning "oil.pressure.warning" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Temperature of the water above which the warning activates. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_water_temperature_warning "water.temperature.warning" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Voltage of the battery below which the warning activates. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_battery_voltage_warning "battery.voltage.warning" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum rpm value. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_rpm_limit "rpm.limit" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of forward gears on undamaged truck. |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_forward_gear_count "gears.forward" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of reversee gears on undamaged truck. |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_reverse_gear_count "gears.reverse" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Differential ratio of the truck. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_differential_ratio "differential.ratio" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of steps in the retarder. |
||||||
|
* |
||||||
|
* Set to zero if retarder is not mounted to the truck. |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_retarder_step_count "retarder.steps" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Forward transmission ratios. |
||||||
|
* |
||||||
|
* Type: indexed float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_forward_ratio "forward.ratio" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reverse transmission ratios. |
||||||
|
* |
||||||
|
* Type: indexed float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_reverse_ratio "reverse.ratio" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Position of the cabin in the vehicle space. |
||||||
|
* |
||||||
|
* This is position of the joint around which the cabin rotates. |
||||||
|
* This attribute might be not present if the vehicle does not |
||||||
|
* have a separate cabin. |
||||||
|
* |
||||||
|
* Type: fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_cabin_position "cabin.position" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default position of the head in the cabin space. |
||||||
|
* |
||||||
|
* Type: fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_head_position "head.position" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Position of the trailer connection hook in vehicle |
||||||
|
* space. |
||||||
|
* |
||||||
|
* Type: fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_hook_position "hook.position" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of wheels |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_wheel_count "wheels.count" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Position of respective wheels in the vehicle space. |
||||||
|
* |
||||||
|
* Type: indexed fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_wheel_position "wheel.position" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the wheel steerable? |
||||||
|
* |
||||||
|
* Type: indexed bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_wheel_steerable "wheel.steerable" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the wheel physicaly simulated? |
||||||
|
* |
||||||
|
* Type: indexed bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_wheel_simulated "wheel.simulated" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Radius of the wheel |
||||||
|
* |
||||||
|
* Type: indexed float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_wheel_radius "wheel.radius" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the wheel powered? |
||||||
|
* |
||||||
|
* Type: indexed bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_wheel_powered "wheel.powered" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the wheel liftable? |
||||||
|
* |
||||||
|
* Type: indexed bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_wheel_liftable "wheel.liftable" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of selectors (e.g. range/splitter toggles). |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_selector_count "selector.count" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gear selected when requirements for this h-shifter slot are meet. |
||||||
|
* |
||||||
|
* Type: indexed s32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_slot_gear "slot.gear" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Position of h-shifter handle. |
||||||
|
* |
||||||
|
* Zero corresponds to neutral position. Mapping to physical position of |
||||||
|
* the handle depends on input setup. |
||||||
|
* |
||||||
|
* Type: indexed u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_slot_handle_position "slot.handle.position" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Bitmask of required on/off state of selectors. |
||||||
|
* |
||||||
|
* Only first selector_count bits are relevant. |
||||||
|
* |
||||||
|
* Type: indexed u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_slot_selectors "slot.selectors" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of the shifter. |
||||||
|
* |
||||||
|
* One from SCS_SHIFTER_TYPE_* values. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_shifter_type "shifter.type" |
||||||
|
|
||||||
|
#define SCS_SHIFTER_TYPE_arcade "arcade" |
||||||
|
#define SCS_SHIFTER_TYPE_automatic "automatic" |
||||||
|
#define SCS_SHIFTER_TYPE_manual "manual" |
||||||
|
#define SCS_SHIFTER_TYPE_hshifter "hshifter" |
||||||
|
|
||||||
|
// Attributes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Id of the cargo for internal use by code. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters and dots. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_cargo_id "cargo.id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of the cargo for display purposes. |
||||||
|
* |
||||||
|
* Localized using the current in-game language. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_cargo "cargo" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mass of the cargo in kilograms. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_cargo_mass "cargo.mass" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mass of the single unit of the cargo in kilograms. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_cargo_unit_mass "cargo.unit.mass" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief How many units of the cargo the job consist of. |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_cargo_unit_count "cargo.unit.count" |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Id of the destination city for internal use by code. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters and dots. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_destination_city_id "destination.city.id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of the destination city for display purposes. |
||||||
|
* |
||||||
|
* Localized using the current in-game language. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_destination_city "destination.city" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Id of the destination company for internal use by code. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters and dots. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_destination_company_id "destination.company.id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of the destination company for display purposes. |
||||||
|
* |
||||||
|
* Localized using the current in-game language. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_destination_company "destination.company" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Id of the source city for internal use by code. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters and dots. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_source_city_id "source.city.id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of the source city for display purposes. |
||||||
|
* |
||||||
|
* Localized using the current in-game language. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_source_city "source.city" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Id of the source company for internal use by code. |
||||||
|
* |
||||||
|
* Limited to C-identifier characters and dots. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_source_company_id "source.company.id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of the source company for display purposes. |
||||||
|
* |
||||||
|
* Localized using the current in-game language. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_source_company "source.company" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reward in internal game-specific currency. |
||||||
|
* |
||||||
|
* For detailed information about the currency see "Game specific units" |
||||||
|
* documentation in scssdk_telemetry_<game_id>.h |
||||||
|
* |
||||||
|
* Type: u64 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_income "income" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Absolute in-game time of end of job delivery window. |
||||||
|
* |
||||||
|
* Delivering the job after this time will cause it be late. |
||||||
|
* |
||||||
|
* See SCS_TELEMETRY_CHANNEL_game_time for more info about absolute time. |
||||||
|
* Time remaining for delivery can be obtained like (delivery_time - game_time). |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_delivery_time "delivery.time" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Planned job distance in simulated kilometers. |
||||||
|
* |
||||||
|
* Does not include distance driven using ferry. |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_planned_distance_km "planned_distance.km" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is cargo loaded on the trailer? |
||||||
|
* |
||||||
|
* For non cargo market jobs this is always true |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_is_cargo_loaded "cargo.loaded" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The job market this job is from. |
||||||
|
* |
||||||
|
* The value is a string representing the type of the job market. |
||||||
|
* Possible values: |
||||||
|
* @li cargo_market |
||||||
|
* @li quick_job |
||||||
|
* @li freight_market |
||||||
|
* @li external_contracts |
||||||
|
* @li external_market |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_job_market "job.market" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flag indicating that the job is special transport job. |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_CONFIG_ATTRIBUTE_special_job "is.special.job" |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_COMMON_CONFIGS_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,203 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_common_gameplay_events.h |
||||||
|
* |
||||||
|
* @brief Telemetry specific gameplay events which might be used by more than one game. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_COMMON_GAMEPLAY_EVENTS_H |
||||||
|
#define SCSSDK_TELEMETRY_COMMON_GAMEPLAY_EVENTS_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Event called when job is cancelled. |
||||||
|
* |
||||||
|
* Attributes: |
||||||
|
* @li cancel_penalty |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_job_cancelled "job.cancelled" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Event called when job is delivered. |
||||||
|
* |
||||||
|
* Attributes: |
||||||
|
* @li revenue |
||||||
|
* @li earned_xp |
||||||
|
* @li cargo_damage |
||||||
|
* @li distance_km |
||||||
|
* @li delivery_time |
||||||
|
* @li autopark_used |
||||||
|
* @li autoload_used |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_job_delivered "job.delivered" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Event called when player gets fined. |
||||||
|
* |
||||||
|
* Attributes: |
||||||
|
* @li fine_offence |
||||||
|
* @li fine_amount |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_player_fined "player.fined" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Event called when player pays for a tollgate. |
||||||
|
* |
||||||
|
* Attributes: |
||||||
|
* @li pay_amount |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_player_tollgate_paid "player.tollgate.paid" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Event called when player uses a ferry. |
||||||
|
* |
||||||
|
* Attributes: |
||||||
|
* @li pay_amount |
||||||
|
* @li source_name |
||||||
|
* @li target_name |
||||||
|
* @li source_id |
||||||
|
* @li target_id |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_player_use_ferry "player.use.ferry" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Event called when player uses a train. |
||||||
|
* |
||||||
|
* Attributes: |
||||||
|
* @li pay_amount |
||||||
|
* @li source_name |
||||||
|
* @li target_name |
||||||
|
* @li source_id |
||||||
|
* @li target_id |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_player_use_train "player.use.train" |
||||||
|
|
||||||
|
// Attributes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The penalty for cancelling the job in native game currency. (Can be 0) |
||||||
|
* |
||||||
|
* Type: s64 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_cancel_penalty "cancel.penalty" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The job revenue in native game currency. |
||||||
|
* |
||||||
|
* Type: s64 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_revenue "revenue" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief How much XP player received for the job. |
||||||
|
* |
||||||
|
* Type: s32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_earned_xp "earned.xp" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Total cargo damage. (Range <0.0, 1.0>) |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_cargo_damage "cargo.damage" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The real distance in km on the job. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_distance_km "distance.km" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Total time spend on the job in game minutes. |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_delivery_time "delivery.time" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Was auto parking used on this job? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_auto_park_used "auto.park.used" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Was auto loading used on this job? (always @c true for non cargo market jobs) |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_auto_load_used "auto.load.used" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fine offence type. |
||||||
|
* |
||||||
|
* Possible values: |
||||||
|
* @li crash |
||||||
|
* @li avoid_sleeping |
||||||
|
* @li wrong_way |
||||||
|
* @li speeding_camera |
||||||
|
* @li no_lights |
||||||
|
* @li red_signal |
||||||
|
* @li speeding |
||||||
|
* @li avoid_weighing |
||||||
|
* @li illegal_trailer |
||||||
|
* @li avoid_inspection |
||||||
|
* @li illegal_border_crossing |
||||||
|
* @li hard_shoulder_violation |
||||||
|
* @li damaged_vehicle_usage |
||||||
|
* @li generic |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_fine_offence "fine.offence" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fine offence amount in native game currency. |
||||||
|
* |
||||||
|
* Type: s64 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_fine_amount "fine.amount" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief How much player was charged for this action (in native game currency) |
||||||
|
* |
||||||
|
* Type: s64 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_pay_amount "pay.amount" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The name of the transportation source. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_source_name "source.name" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The name of the transportation target. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_target_name "target.name" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The id of the transportation source. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_source_id "source.id" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The id of the transportation target. |
||||||
|
* |
||||||
|
* Type: string |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_target_id "target.id" |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_COMMON_GAMEPLAY_EVENTS_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,24 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_job_common_channels.h |
||||||
|
* |
||||||
|
* @brief Job telemetry specific constants for channels. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_JOB_COMMON_CHANNELS_H |
||||||
|
#define SCSSDK_TELEMETRY_JOB_COMMON_CHANNELS_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The total damage of the cargo in range 0.0 to 1.0. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_JOB_CHANNEL_cargo_damage "job.cargo.damage" |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_JOB_COMMON_CHANNELS_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,80 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_trailer_common_channels.h |
||||||
|
* |
||||||
|
* @brief Trailer telemetry specific constants for channels. |
||||||
|
* |
||||||
|
* See scssdk_telemetry_truck_common_channels.h for more info. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_TRAILER_COMMON_CHANNELS_H |
||||||
|
#define SCSSDK_TELEMETRY_TRAILER_COMMON_CHANNELS_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* Telemetry SDK supports multiple trailers. |
||||||
|
* |
||||||
|
* To get information about more trailers replace "trailer." with "trailer.[index].". |
||||||
|
* Connected state for trailers would be: |
||||||
|
* |
||||||
|
* First trailer: "trailer.0.connected" |
||||||
|
* Second trailer: "trailer.1.connected" |
||||||
|
* ... |
||||||
|
* Six-th trailer: "trailer.5.connected" |
||||||
|
* etc |
||||||
|
* |
||||||
|
* Maximum number of trailers that can be reported by telemetry SDK |
||||||
|
* is defined by @c SCS_TELEMETRY_trailers_count. |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the trailer connected to the truck? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_connected "trailer.connected" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief How much is the cargo damaged that is loaded to this trailer in <0.0, 1.0> range. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_cargo_damage "trailer.cargo.damage" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Channels similar to the truck ones |
||||||
|
* |
||||||
|
* See scssdk_telemetry_truck_common_channels.h for description of |
||||||
|
* corresponding truck channels |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_world_placement "trailer.world.placement" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_local_linear_velocity "trailer.velocity.linear" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_local_angular_velocity "trailer.velocity.angular" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_local_linear_acceleration "trailer.acceleration.linear" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_local_angular_acceleration "trailer.acceleration.angular" |
||||||
|
|
||||||
|
// Damage.
|
||||||
|
|
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wear_body "trailer.wear.body" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wear_chassis "trailer.wear.chassis" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wear_wheels "trailer.wear.wheels" |
||||||
|
|
||||||
|
// Wheels.
|
||||||
|
|
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wheel_susp_deflection "trailer.wheel.suspension.deflection" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wheel_on_ground "trailer.wheel.on_ground" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wheel_substance "trailer.wheel.substance" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wheel_velocity "trailer.wheel.angular_velocity" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wheel_steering "trailer.wheel.steering" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wheel_rotation "trailer.wheel.rotation" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wheel_lift "trailer.wheel.lift" |
||||||
|
#define SCS_TELEMETRY_TRAILER_CHANNEL_wheel_lift_offset "trailer.wheel.lift.offset" |
||||||
|
//@}
|
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_TRAILER_COMMON_CHANNELS_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,766 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_truck_common_channels.h |
||||||
|
* |
||||||
|
* @brief Truck telemetry specific constants for channels. |
||||||
|
* |
||||||
|
* This file defines truck specific telemetry constants which |
||||||
|
* might be used by more than one SCS game. See game-specific |
||||||
|
* file to determine which constants are supported by specific |
||||||
|
* game. |
||||||
|
* |
||||||
|
* Unless state otherwise, following rules apply. |
||||||
|
* @li Whenever channel has float based type (float, fvector, fplacement) |
||||||
|
* is can also provide double based values (double, dvector, dplacement) |
||||||
|
* and vice versa. Note that using the non-native type might incur |
||||||
|
* conversion costs or cause precision loss (double->float in |
||||||
|
* world-space context). |
||||||
|
* @li Whenever channel has u32 type is can also provide u64 value. |
||||||
|
* Note that using the non-native type might incur conversion costs. |
||||||
|
* @li Whenever channel uses placement based type (dplacement, fplacement), |
||||||
|
* it also supports euler type containg just the rotational part and |
||||||
|
* dvector/fvector type containing just the positional part. |
||||||
|
* @li Indexed entries are using zero-based indices. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_TRUCK_COMMON_CHANNELS_H |
||||||
|
#define SCSSDK_TELEMETRY_TRUCK_COMMON_CHANNELS_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
// Movement.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents world space position and orientation of the truck. |
||||||
|
* |
||||||
|
* Type: dplacement |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_world_placement "truck.world.placement" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents vehicle space linear velocity of the truck measured |
||||||
|
* in meters per second. |
||||||
|
* |
||||||
|
* Type: fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_local_linear_velocity "truck.local.velocity.linear" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents vehicle space angular velocity of the truck measured |
||||||
|
* in rotations per second. |
||||||
|
* |
||||||
|
* Type: fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_local_angular_velocity "truck.local.velocity.angular" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents vehicle space linear acceleration of the truck measured |
||||||
|
* in meters per second^2 |
||||||
|
* |
||||||
|
* Type: fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_local_linear_acceleration "truck.local.acceleration.linear" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents vehicle space angular acceleration of the truck meassured |
||||||
|
* in rotations per second^2 |
||||||
|
* |
||||||
|
* Type: fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_local_angular_acceleration "truck.local.acceleration.angular" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a vehicle space position and orientation delta |
||||||
|
* of the cabin from its default position. |
||||||
|
* |
||||||
|
* Type: fplacement |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_cabin_offset "truck.cabin.offset" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents cabin space angular velocity of the cabin measured |
||||||
|
* in rotations per second. |
||||||
|
* |
||||||
|
* Type: fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_cabin_angular_velocity "truck.cabin.velocity.angular" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents cabin space angular acceleration of the cabin |
||||||
|
* measured in rotations per second^2 |
||||||
|
* |
||||||
|
* Type: fvector |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_cabin_angular_acceleration "truck.cabin.acceleration.angular" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a cabin space position and orientation delta |
||||||
|
* of the driver head from its default position. |
||||||
|
* |
||||||
|
* Note that this value might change rapidly as result of |
||||||
|
* the user switching between cameras or camera presets. |
||||||
|
* |
||||||
|
* Type: fplacement |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_head_offset "truck.head.offset" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Speedometer speed in meters per second. |
||||||
|
* |
||||||
|
* Uses negative value to represent reverse movement. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_speed "truck.speed" |
||||||
|
|
||||||
|
// Powertrain related
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RPM of the engine. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_engine_rpm "truck.engine.rpm" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gear currently selected in the engine. |
||||||
|
* |
||||||
|
* @li >0 - Forwad gears |
||||||
|
* @li 0 - Neutral |
||||||
|
* @li <0 - Reverse gears |
||||||
|
* |
||||||
|
* Type: s32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_engine_gear "truck.engine.gear" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gear currently displayed on dashboard. |
||||||
|
* |
||||||
|
* @li >0 - Forwad gears |
||||||
|
* @li 0 - Neutral |
||||||
|
* @li <0 - Reverse gears |
||||||
|
* |
||||||
|
* Type: s32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_displayed_gear "truck.displayed.gear" |
||||||
|
|
||||||
|
// Driving
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Steering received from input <-1;1>. |
||||||
|
* |
||||||
|
* Note that it is interpreted counterclockwise. |
||||||
|
* |
||||||
|
* If the user presses the steer right button on digital input |
||||||
|
* (e.g. keyboard) this value goes immediatelly to -1.0 |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_input_steering "truck.input.steering" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Throttle received from input <0;1> |
||||||
|
* |
||||||
|
* If the user presses the forward button on digital input |
||||||
|
* (e.g. keyboard) this value goes immediatelly to 1.0 |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_input_throttle "truck.input.throttle" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brake received from input <0;1> |
||||||
|
* |
||||||
|
* If the user presses the brake button on digital input |
||||||
|
* (e.g. keyboard) this value goes immediatelly to 1.0 |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_input_brake "truck.input.brake" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clutch received from input <0;1> |
||||||
|
* |
||||||
|
* If the user presses the clutch button on digital input |
||||||
|
* (e.g. keyboard) this value goes immediatelly to 1.0 |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_input_clutch "truck.input.clutch" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Steering as used by the simulation <-1;1> |
||||||
|
* |
||||||
|
* Note that it is interpreted counterclockwise. |
||||||
|
* |
||||||
|
* Accounts for interpolation speeds and simulated |
||||||
|
* counterfoces for digital inputs. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_effective_steering "truck.effective.steering" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Throttle pedal input as used by the simulation <0;1> |
||||||
|
* |
||||||
|
* Accounts for the press attack curve for digital inputs |
||||||
|
* or cruise-control input. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_effective_throttle "truck.effective.throttle" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brake pedal input as used by the simulation <0;1> |
||||||
|
* |
||||||
|
* Accounts for the press attack curve for digital inputs. Does |
||||||
|
* not contain retarder, parking or engine brake. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_effective_brake "truck.effective.brake" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clutch pedal input as used by the simulation <0;1> |
||||||
|
* |
||||||
|
* Accounts for the automatic shifting or interpolation of |
||||||
|
* player input. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_effective_clutch "truck.effective.clutch" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Speed selected for the cruise control in m/s |
||||||
|
* |
||||||
|
* Is zero if cruise control is disabled. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_cruise_control "truck.cruise_control" |
||||||
|
|
||||||
|
// Gearbox related
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gearbox slot the h-shifter handle is currently in. |
||||||
|
* |
||||||
|
* 0 means that no slot is selected. |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_hshifter_slot "truck.hshifter.slot" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enabled state of range/splitter selector toggles. |
||||||
|
* |
||||||
|
* Mapping between the range/splitter functionality and |
||||||
|
* selector index is described by HSHIFTER configuration. |
||||||
|
* |
||||||
|
* Type: indexed bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_hshifter_selector "truck.hshifter.select" |
||||||
|
|
||||||
|
// Brakes.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the parking brake enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_parking_brake "truck.brake.parking" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the engine brake enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_motor_brake "truck.brake.motor" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Current level of the retarder. |
||||||
|
* |
||||||
|
* <0;max> where 0 is disabled retarder and max is maximum |
||||||
|
* value found in TRUCK configuration. |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_retarder_level "truck.brake.retarder" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pressure in the brake air tank in psi |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_brake_air_pressure "truck.brake.air.pressure" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the air pressure warning active? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_brake_air_pressure_warning "truck.brake.air.pressure.warning" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Are the emergency brakes active as result of low air pressure? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_brake_air_pressure_emergency "truck.brake.air.pressure.emergency" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Temperature of the brakes in degrees celsius. |
||||||
|
* |
||||||
|
* Aproximated for entire truck, not at the wheel level. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_brake_temperature "truck.brake.temperature" |
||||||
|
|
||||||
|
// Various "consumables"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Amount of fuel in liters |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_fuel "truck.fuel.amount" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the low fuel warning active? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_fuel_warning "truck.fuel.warning" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Average consumption of the fuel in liters/km |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_fuel_average_consumption "truck.fuel.consumption.average" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Estimated range of truck with current amount of fuel in km |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_fuel_range "truck.fuel.range" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Amount of AdBlue in liters |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_adblue "truck.adblue" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the low adblue warning active? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_adblue_warning "truck.adblue.warning" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Average consumption of the adblue in liters/km |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_adblue_average_consumption "truck.adblue.consumption.average" |
||||||
|
|
||||||
|
// Oil
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pressure of the oil in psi |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_oil_pressure "truck.oil.pressure" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the oil pressure warning active? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_oil_pressure_warning "truck.oil.pressure.warning" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Temperature of the oil in degrees celsius. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_oil_temperature "truck.oil.temperature" |
||||||
|
|
||||||
|
// Temperature in various systems.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Temperature of the water in degrees celsius. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_water_temperature "truck.water.temperature" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the water temperature warning active? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_water_temperature_warning "truck.water.temperature.warning" |
||||||
|
|
||||||
|
// Battery
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Voltage of the battery in volts. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_battery_voltage "truck.battery.voltage" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the battery voltage/not charging warning active? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_battery_voltage_warning "truck.battery.voltage.warning" |
||||||
|
|
||||||
|
// Enabled state of various elements.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the electric enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_electric_enabled "truck.electric.enabled" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the engine enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_engine_enabled "truck.engine.enabled" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the left blinker enabled? |
||||||
|
* |
||||||
|
* This represents the logical enable state of the blinker. It |
||||||
|
* it is true as long the blinker is enabled regardless of the |
||||||
|
* physical enabled state of the light (i.e. it does not blink |
||||||
|
* and ignores enable state of electric). |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_lblinker "truck.lblinker" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the right blinker enabled? |
||||||
|
* |
||||||
|
* This represents the logical enable state of the blinker. It |
||||||
|
* it is true as long the blinker is enabled regardless of the |
||||||
|
* physical enabled state of the light (i.e. it does not blink |
||||||
|
* and ignores enable state of electric). |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_rblinker "truck.rblinker" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Are the hazard warning light enabled? |
||||||
|
* |
||||||
|
* This represents the logical enable state of the hazard warning. |
||||||
|
* It it is true as long it is enabled regardless of the physical |
||||||
|
* enabled state of the light (i.e. it does not blink). |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_hazard_warning "truck.hazard.warning" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the light in the left blinker currently on? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_lblinker "truck.light.lblinker" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the light in the right blinker currently on? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_rblinker "truck.light.rblinker" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Are the parking lights enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_parking "truck.light.parking" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Are the low beam lights enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_low_beam "truck.light.beam.low" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Are the high beam lights enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_high_beam "truck.light.beam.high" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Are the auxiliary front lights active? |
||||||
|
* |
||||||
|
* Those lights have several intensity levels: |
||||||
|
* @li 1 - dimmed state |
||||||
|
* @li 2 - full state |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_aux_front "truck.light.aux.front" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Are the auxiliary roof lights active? |
||||||
|
* |
||||||
|
* Those lights have several intensity levels: |
||||||
|
* @li 1 - dimmed state |
||||||
|
* @li 2 - full state |
||||||
|
* |
||||||
|
* Type: u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_aux_roof "truck.light.aux.roof" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Are the beacon lights enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_beacon "truck.light.beacon" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the brake light active? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_brake "truck.light.brake" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the reverse light active? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_light_reverse "truck.light.reverse" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Are the wipers enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wipers "truck.wipers" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Intensity of the dashboard backlight as factor <0;1> |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_dashboard_backlight "truck.dashboard.backlight" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the differential lock enabled? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_differential_lock "truck.differential_lock" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the lift axle control set to lifted state? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_lift_axle "truck.lift_axle" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the lift axle indicator lit? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_lift_axle_indicator "truck.lift_axle.indicator" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the trailer lift axle control set to lifted state? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_trailer_lift_axle "truck.trailer.lift_axle" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the trailer lift axle indicator lit? |
||||||
|
* |
||||||
|
* Type: bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_trailer_lift_axle_indicator "truck.trailer.lift_axle.indicator" |
||||||
|
|
||||||
|
// Wear info.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wear of the engine accessory as <0;1> |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wear_engine "truck.wear.engine" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wear of the transmission accessory as <0;1> |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wear_transmission "truck.wear.transmission" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wear of the cabin accessory as <0;1> |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wear_cabin "truck.wear.cabin" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wear of the chassis accessory as <0;1> |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wear_chassis "truck.wear.chassis" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Average wear across the wheel accessories as <0;1> |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wear_wheels "truck.wear.wheels" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The value of the odometer in km. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_odometer "truck.odometer" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The value of truck's navigation distance (in meters). |
||||||
|
* |
||||||
|
* This is the value used by the advisor. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_navigation_distance "truck.navigation.distance" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The value of truck's navigation eta (in second). |
||||||
|
* |
||||||
|
* This is the value used by the advisor. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_navigation_time "truck.navigation.time" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The value of truck's navigation speed limit (in m/s). |
||||||
|
* |
||||||
|
* This is the value used by the advisor and respects the |
||||||
|
* current state of the "Route Advisor speed limit" option. |
||||||
|
* |
||||||
|
* Type: float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_navigation_speed_limit "truck.navigation.speed.limit" |
||||||
|
|
||||||
|
// Wheels.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vertical displacement of the wheel from its |
||||||
|
* axis in meters. |
||||||
|
* |
||||||
|
* Type: indexed float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wheel_susp_deflection "truck.wheel.suspension.deflection" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the wheel in contact with ground? |
||||||
|
* |
||||||
|
* Type: indexed bool |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wheel_on_ground "truck.wheel.on_ground" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Substance below the whell. |
||||||
|
* |
||||||
|
* Index of substance as delivered trough SUBSTANCE config. |
||||||
|
* |
||||||
|
* Type: indexed u32 |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wheel_substance "truck.wheel.substance" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Angular velocity of the wheel in rotations per |
||||||
|
* second. |
||||||
|
* |
||||||
|
* Positive velocity corresponds to forward movement. |
||||||
|
* |
||||||
|
* Type: indexed float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wheel_velocity "truck.wheel.angular_velocity" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Steering rotation of the wheel in rotations. |
||||||
|
* |
||||||
|
* Value is from <-0.25,0.25> range in counterclockwise direction |
||||||
|
* when looking from top (e.g. 0.25 corresponds to left and |
||||||
|
* -0.25 corresponds to right). |
||||||
|
* |
||||||
|
* Set to zero for non-steered wheels. |
||||||
|
* |
||||||
|
* Type: indexed float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wheel_steering "truck.wheel.steering" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rolling rotation of the wheel in rotations. |
||||||
|
* |
||||||
|
* Value is from <0.0,1.0) range in which value |
||||||
|
* increase corresponds to forward movement. |
||||||
|
* |
||||||
|
* Type: indexed float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wheel_rotation "truck.wheel.rotation" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lift state of the wheel <0;1> |
||||||
|
* |
||||||
|
* For use with simple lifted/non-lifted test or logical |
||||||
|
* visualization of the lifting progress. |
||||||
|
* |
||||||
|
* Value of 0 corresponds to non-lifted axle. |
||||||
|
* Value of 1 corresponds to fully lifted axle. |
||||||
|
* |
||||||
|
* Set to zero or not provided for non-liftable axles. |
||||||
|
* |
||||||
|
* Type: indexed float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wheel_lift "truck.wheel.lift" |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vertical displacement of the wheel axle |
||||||
|
* from its normal position in meters as result of |
||||||
|
* lifting. |
||||||
|
* |
||||||
|
* Might have non-linear relation to lift ratio. |
||||||
|
* |
||||||
|
* Set to zero or not provided for non-liftable axles. |
||||||
|
* |
||||||
|
* Type: indexed float |
||||||
|
*/ |
||||||
|
#define SCS_TELEMETRY_TRUCK_CHANNEL_wheel_lift_offset "truck.wheel.lift.offset" |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_TRUCK_COMMON_CHANNELS_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,22 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_eut2.h |
||||||
|
* |
||||||
|
* @brief ETS 2 specific constants. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_EUT2_H |
||||||
|
#define SCSSDK_EUT2_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Value used in the scs_sdk_init_params_t::game_id to identify this game. |
||||||
|
*/ |
||||||
|
#define SCS_GAME_ID_EUT2 "eut2" |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_EUT2_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,31 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_input_eut2.h |
||||||
|
* |
||||||
|
* @brief ETS2 input specific constants. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_INPUT_EUT2_H |
||||||
|
#define SCSSDK_INPUT_EUT2_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Value used in the scs_sdk_init_params_t::game_version |
||||||
|
* |
||||||
|
* Changes in the major version indicate incompatible changes. |
||||||
|
* Changes in the minor version indicate compatible changes (e.g. added more types) |
||||||
|
* |
||||||
|
* Changes: |
||||||
|
* 1.00 - initial version |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
#define SCS_INPUT_EUT2_GAME_VERSION_1_00 SCS_MAKE_VERSION(1, 0) |
||||||
|
#define SCS_INPUT_EUT2_GAME_VERSION_CURRENT SCS_INPUT_EUT2_GAME_VERSION_1_00 |
||||||
|
//@}
|
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_INPUT_EUT2_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,107 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_eut2.h |
||||||
|
* |
||||||
|
* @brief ETS 2 telemetry specific constants. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_EUT2_H |
||||||
|
#define SCSSDK_TELEMETRY_EUT2_H |
||||||
|
|
||||||
|
#include "../scssdk.h" |
||||||
|
#include "../common/scssdk_telemetry_common_configs.h" |
||||||
|
#include "../common/scssdk_telemetry_common_channels.h" |
||||||
|
#include "../common/scssdk_telemetry_truck_common_channels.h" |
||||||
|
#include "../common/scssdk_telemetry_trailer_common_channels.h" |
||||||
|
#include "../common/scssdk_telemetry_job_common_channels.h" |
||||||
|
#include "../common/scssdk_telemetry_common_gameplay_events.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Value used in the scs_sdk_init_params_t::game_version |
||||||
|
* |
||||||
|
* Changes in the major version indicate incompatible changes (e.g. changed interpretation |
||||||
|
* of the channel value). Change of major version is highly discouraged, creation of |
||||||
|
* alternative channel is preferred solution if necessary. |
||||||
|
* Changes in the minor version indicate compatible changes (e.g. added channel, more supported |
||||||
|
* value types). Removal of channel is also compatible change however it is recommended |
||||||
|
* to keep the channel with some default value. |
||||||
|
* |
||||||
|
* Changes: |
||||||
|
* 1.01 - added brake_air_pressure_emergency channel and air_pressure_emergency config |
||||||
|
* 1.02 - replaced cabin_orientation channel with cabin_offset channel |
||||||
|
* 1.03 - fixed reporting of invalid index value for wheels.count attribute |
||||||
|
* 1.04 - added lblinker_light and rblinker_light channels |
||||||
|
* 1.05 - fixed content of brand_id and brand attributes |
||||||
|
* 1.06 - fixed index value for selector_count attribute. It is now SCS_U32_NIL as the |
||||||
|
* attribute is not indexed. For backward compatibility additional copy with |
||||||
|
* index 0 is also present however it will be removed in the future. |
||||||
|
* 1.07 - fixed calculation of cabin_angular_acceleration channel. |
||||||
|
* 1.08 - a empty truck/trailer configuration event is generated when truck is removed |
||||||
|
* (e.g. after completion of quick job) |
||||||
|
* 1.09 - added time and job related info |
||||||
|
* 1.10 - added information about liftable axes |
||||||
|
* 1.11 - u32 channels can provide u64 as documented, added displayed_gear channel, increased |
||||||
|
* maximum number of supported wheel channels to 14 |
||||||
|
* 1.12 - added information about transmission (differential_ratio, forward_ratio, reverse_ratio), |
||||||
|
* navigation channels (navigation_distance, navigation_time, navigation_speed_limit) |
||||||
|
* and adblue related data are now provided. |
||||||
|
* 1.13 - fixed values of id and cargo_accessory_id attributes in trailer config broken by |
||||||
|
* ETS2 1.25 update. Note that the new values will be different from the ones returned |
||||||
|
* by ETS2 1.24 and older. |
||||||
|
* 1.14 - added support for multiple trailers (doubles, triples), trailer ownership support, |
||||||
|
* gameplay events support added |
||||||
|
* 1.15 - added planned_distance_km to active job info |
||||||
|
* 1.16 - added support for 'avoid_inspection', 'illegal_border_crossing' and 'hard_shoulder_violation' offence type in 'player.fined' gameplay event |
||||||
|
* 1.17 - added differential lock, lift axle and hazard warning channels |
||||||
|
* 1.18 - added multiplayer time offset and trailer body wear channel, fixed trailer chassis wear channel |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_00 SCS_MAKE_VERSION(1, 0) |
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_01 SCS_MAKE_VERSION(1, 1) |
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_02 SCS_MAKE_VERSION(1, 2) |
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_03 SCS_MAKE_VERSION(1, 3) |
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_04 SCS_MAKE_VERSION(1, 4) |
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_05 SCS_MAKE_VERSION(1, 5) // Patch 1.4
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_06 SCS_MAKE_VERSION(1, 6) |
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_07 SCS_MAKE_VERSION(1, 7) // Patch 1.6
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_08 SCS_MAKE_VERSION(1, 8) // Patch 1.9
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_09 SCS_MAKE_VERSION(1, 9) // Patch 1.14 beta
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_10 SCS_MAKE_VERSION(1, 10) // Patch 1.14
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_11 SCS_MAKE_VERSION(1, 11) |
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_12 SCS_MAKE_VERSION(1, 12) // Patch 1.17
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_13 SCS_MAKE_VERSION(1, 13) // Patch 1.27
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_14 SCS_MAKE_VERSION(1, 14) // Patch 1.35
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_15 SCS_MAKE_VERSION(1, 15) // Patch 1.36
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_16 SCS_MAKE_VERSION(1, 16) // Patch 1.36
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_17 SCS_MAKE_VERSION(1, 17) // Patch 1.41
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_1_18 SCS_MAKE_VERSION(1, 18) // Patch 1.45
|
||||||
|
#define SCS_TELEMETRY_EUT2_GAME_VERSION_CURRENT SCS_TELEMETRY_EUT2_GAME_VERSION_1_18 |
||||||
|
//@}
|
||||||
|
|
||||||
|
// Game specific units.
|
||||||
|
//
|
||||||
|
// @li The game uses Euro as internal currency provided
|
||||||
|
// by the telemetry unless documented otherwise.
|
||||||
|
|
||||||
|
// Channels defined in scssdk_telemetry_common_channels.h,
|
||||||
|
// scssdk_telemetry_job_common_channels.h,
|
||||||
|
// scssdk_telemetry_truck_common_channels.h and
|
||||||
|
// scssdk_telemetry_trailer_common_channels.h are supported
|
||||||
|
// with following exceptions and limitations as of v1.00:
|
||||||
|
//
|
||||||
|
// @li Rolling rotation of trailer wheels is determined from linear
|
||||||
|
// movement.
|
||||||
|
// @li The pressures, temperatures and voltages are not simulated.
|
||||||
|
// They are very loosely approximated.
|
||||||
|
|
||||||
|
// Configurations defined in scssdk_telemetry_common_configs.h are
|
||||||
|
// supported with following exceptions and limitations as of v1.00:
|
||||||
|
//
|
||||||
|
// @li The localized strings are not updated when different in-game
|
||||||
|
// language is selected.
|
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_EUT2_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,202 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk.h |
||||||
|
* |
||||||
|
* @brief Common SDK types and structures. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_H |
||||||
|
#define SCSSDK_H |
||||||
|
|
||||||
|
#define SCSSDK_HEADER extern "C" { |
||||||
|
#define SCSSDK_FOOTER } |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
// Types used trough the SDK.
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) |
||||||
|
|
||||||
|
typedef unsigned __int8 scs_u8_t; |
||||||
|
typedef unsigned __int16 scs_u16_t; |
||||||
|
typedef signed __int32 scs_s32_t; |
||||||
|
typedef unsigned __int32 scs_u32_t; |
||||||
|
typedef unsigned __int64 scs_u64_t; |
||||||
|
typedef signed __int64 scs_s64_t; |
||||||
|
typedef float scs_float_t; |
||||||
|
typedef double scs_double_t; |
||||||
|
typedef const char * scs_string_t; |
||||||
|
#define SCSAPIFUNC __stdcall |
||||||
|
|
||||||
|
#if defined(_WIN64) |
||||||
|
#define SCS_ARCHITECTURE_x64 |
||||||
|
#else |
||||||
|
#define SCS_ARCHITECTURE_x86 |
||||||
|
#endif |
||||||
|
|
||||||
|
#define SCS_PF_U64 "I64u" |
||||||
|
#define SCS_PF_S64 "I64d" |
||||||
|
|
||||||
|
#elif defined(__GNUG__) |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
typedef uint8_t scs_u8_t; |
||||||
|
typedef uint16_t scs_u16_t; |
||||||
|
typedef int32_t scs_s32_t; |
||||||
|
typedef uint32_t scs_u32_t; |
||||||
|
typedef uint64_t scs_u64_t; |
||||||
|
typedef int64_t scs_s64_t; |
||||||
|
typedef float scs_float_t; |
||||||
|
typedef double scs_double_t; |
||||||
|
typedef const char * scs_string_t; |
||||||
|
#define SCSAPIFUNC |
||||||
|
|
||||||
|
#if defined(__x86_64__) |
||||||
|
#define SCS_ARCHITECTURE_x64 |
||||||
|
#define SCS_PF_U64 "lu" |
||||||
|
#define SCS_PF_S64 "ld" |
||||||
|
#elif defined(__i386__) |
||||||
|
#define SCS_ARCHITECTURE_x86 |
||||||
|
#define SCS_PF_U64 "llu" |
||||||
|
#define SCS_PF_S64 "lld" |
||||||
|
#else |
||||||
|
#error "Unknown architecture." |
||||||
|
#endif |
||||||
|
|
||||||
|
#else |
||||||
|
#error "Unknown compiler." |
||||||
|
#endif |
||||||
|
|
||||||
|
const scs_u32_t SCS_U32_NIL = static_cast<scs_u32_t>(-1); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of value provided during callback registration and passed back |
||||||
|
* to the callback. |
||||||
|
*/ |
||||||
|
typedef void *scs_context_t; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Timestamp value. |
||||||
|
* |
||||||
|
* Value is expressed in microseconds. |
||||||
|
*/ |
||||||
|
typedef scs_u64_t scs_timestamp_t; |
||||||
|
|
||||||
|
// Common return codes.
|
||||||
|
|
||||||
|
typedef scs_s32_t scs_result_t; |
||||||
|
const scs_result_t SCS_RESULT_ok = 0; // Operation succeeded.
|
||||||
|
const scs_result_t SCS_RESULT_unsupported = -1; // Operation or specified parameters are not supported. (e.g. the plugin does not support the requested version of the API)
|
||||||
|
const scs_result_t SCS_RESULT_invalid_parameter = -2; // Specified parameter is not valid (e.g. null value of callback, invalid combination of flags).
|
||||||
|
const scs_result_t SCS_RESULT_already_registered = -3; // There is already a registered conflicting object (e.g. callback for the specified event/channel, input device with the same name).
|
||||||
|
const scs_result_t SCS_RESULT_not_found = -4; // Specified item (e.g. channel) was not found.
|
||||||
|
const scs_result_t SCS_RESULT_unsupported_type = -5; // Specified value type is not supported (e.g. channel does not provide that value type).
|
||||||
|
const scs_result_t SCS_RESULT_not_now = -6; // Action (event/callback registration) is not allowed in the current state. Indicates incorrect use of the api.
|
||||||
|
const scs_result_t SCS_RESULT_generic_error = -7; // Error not covered by other existing code.
|
||||||
|
|
||||||
|
// Function definition macros.
|
||||||
|
|
||||||
|
#define SCSAPI_RESULT scs_result_t SCSAPIFUNC |
||||||
|
#define SCSAPI_VOID void SCSAPIFUNC |
||||||
|
|
||||||
|
#define SCSAPI_RESULT_FPTR(function_name) scs_result_t (SCSAPIFUNC *function_name) |
||||||
|
#define SCSAPI_VOID_FPTR(function_name) void (SCSAPIFUNC *function_name) |
||||||
|
|
||||||
|
// Compile time checks.
|
||||||
|
|
||||||
|
#define SCS_CONCAT2(prefix, suffix) prefix##suffix |
||||||
|
#define SCS_CONCAT(prefix, suffix) SCS_CONCAT2(prefix, suffix) |
||||||
|
#define scs_static_check(expr) typedef int SCS_CONCAT(some_requirement_failed_at_, __LINE__)[(expr) ? 1 : -1] |
||||||
|
|
||||||
|
#if defined(SCS_ARCHITECTURE_x86) |
||||||
|
#define scs_check_size(structure, expected_32, expected_64) scs_static_check(sizeof(structure) == expected_32) |
||||||
|
#elif defined(SCS_ARCHITECTURE_x64) |
||||||
|
#define scs_check_size(structure, expected_32, expected_64) scs_static_check(sizeof(structure) == expected_64) |
||||||
|
#endif |
||||||
|
|
||||||
|
// Types of messages printed to log.
|
||||||
|
|
||||||
|
typedef scs_s32_t scs_log_type_t; |
||||||
|
const scs_log_type_t SCS_LOG_TYPE_message = 0; |
||||||
|
const scs_log_type_t SCS_LOG_TYPE_warning = 1; |
||||||
|
const scs_log_type_t SCS_LOG_TYPE_error = 2; |
||||||
|
|
||||||
|
// Version support.
|
||||||
|
|
||||||
|
#define SCS_MAKE_VERSION(major, minor) (((major) << 16) | (minor)) |
||||||
|
#define SCS_GET_MAJOR_VERSION(version) (((version) >> 16) & 0xffff) |
||||||
|
#define SCS_GET_MINOR_VERSION(version) ((version) & 0xffff) |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Logs specified message to the game log. |
||||||
|
* |
||||||
|
* @param type Type of message. Controls generated prefixes and colors in console. |
||||||
|
* @param message Message to log. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_VOID_FPTR(scs_log_t)(const scs_log_type_t type, const scs_string_t message); |
||||||
|
|
||||||
|
// Common initialization structures.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization parameters common to most APIs provided |
||||||
|
* by the SDK. |
||||||
|
*/ |
||||||
|
struct scs_sdk_init_params_v100_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Name of the game for display purposes. |
||||||
|
* |
||||||
|
* This is UTF8 encoded string containing name of the game |
||||||
|
* for display to the user. The exact format is not defined, |
||||||
|
* might be changed between versions and should be not parsed. |
||||||
|
* |
||||||
|
* This pointer will be never NULL. |
||||||
|
*/ |
||||||
|
scs_string_t game_name; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Identification of the game. |
||||||
|
* |
||||||
|
* If the library wants to identify the game to do any |
||||||
|
* per-game configuration, this is the field which should |
||||||
|
* be used. |
||||||
|
* |
||||||
|
* This string contains only following characters: |
||||||
|
* @li lower-cased letters |
||||||
|
* @li digits |
||||||
|
* @li underscore |
||||||
|
* |
||||||
|
* This pointer will be never NULL. |
||||||
|
*/ |
||||||
|
scs_string_t game_id; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Version of the game for purpose of the specific api |
||||||
|
* which is being initialized. |
||||||
|
* |
||||||
|
* Does NOT match the patch level of the game. |
||||||
|
*/ |
||||||
|
scs_u32_t game_version; |
||||||
|
|
||||||
|
#ifdef SCS_ARCHITECTURE_x64 |
||||||
|
/**
|
||||||
|
* @brief Explicit alignment for the 64 bit pointer. |
||||||
|
*/ |
||||||
|
scs_u32_t _padding; |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function used to write messages to the game log. |
||||||
|
* |
||||||
|
* Each message is printed on a separate line. |
||||||
|
* |
||||||
|
* This pointer will be never NULL. |
||||||
|
*/ |
||||||
|
scs_log_t log; |
||||||
|
}; |
||||||
|
|
||||||
|
scs_check_size(scs_sdk_init_params_v100_t, 16, 32); |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,84 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_input.h |
||||||
|
* |
||||||
|
* @brief Input SDK. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_INPUT_H |
||||||
|
#define SCSSDK_INPUT_H |
||||||
|
|
||||||
|
#include "scssdk.h" |
||||||
|
#include "scssdk_value.h" |
||||||
|
#include "scssdk_input_device.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Versions of the input SDK |
||||||
|
* |
||||||
|
* Changes in the major version indicate incompatible changes in the API. |
||||||
|
* Changes in the minor version indicate additions. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
#define SCS_INPUT_VERSION_1_00 SCS_MAKE_VERSION(1, 0) |
||||||
|
#define SCS_INPUT_VERSION_CURRENT SCS_INPUT_VERSION_1_00 |
||||||
|
//@}
|
||||||
|
|
||||||
|
// Structures used to pass additional data to the initialization function.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Common ancestor to all structures providing parameters to the input |
||||||
|
* initialization. |
||||||
|
*/ |
||||||
|
struct scs_input_init_params_t |
||||||
|
{ |
||||||
|
void method_indicating_this_is_not_a_c_struct(void); |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization parameters for the 1.00 version of the input API. |
||||||
|
*/ |
||||||
|
struct scs_input_init_params_v100_t : public scs_input_init_params_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Common initialization parameters. |
||||||
|
*/ |
||||||
|
scs_sdk_init_params_v100_t common; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Function used to register input device. |
||||||
|
*/ |
||||||
|
scs_input_register_device_t register_device; |
||||||
|
}; |
||||||
|
scs_check_size(scs_input_init_params_v100_t, 20, 40); |
||||||
|
|
||||||
|
// Functions which should be exported by the dynamic library serving as
|
||||||
|
// recipient of the input.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes input support. |
||||||
|
* |
||||||
|
* This function must be provided by the library if it wants to support input API. |
||||||
|
* |
||||||
|
* The engine will call this function with API versions it supports starting from the latest |
||||||
|
* until the function returns SCS_RESULT_ok or error other than SCS_RESULT_unsupported or it |
||||||
|
* runs out of supported versions. |
||||||
|
* |
||||||
|
* @param version Version of the API to initialize. |
||||||
|
* @param params Structure with additional initialization data specific to the specified API version. |
||||||
|
* @return SCS_RESULT_ok if version is supported and library was initialized. Error code otherwise. |
||||||
|
*/ |
||||||
|
SCSAPI_RESULT scs_input_init (const scs_u32_t version, const scs_input_init_params_t *const params); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shuts down the input support. |
||||||
|
* |
||||||
|
* The engine will call this function if available and if the scs_input_init indicated |
||||||
|
* success. |
||||||
|
*/ |
||||||
|
SCSAPI_VOID scs_input_shutdown (void); |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_INPUT_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,188 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_input_device.h |
||||||
|
* |
||||||
|
* @brief Input SDK - devices. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_INPUT_DEVICE_H |
||||||
|
#define SCSSDK_INPUT_DEVICE_H |
||||||
|
|
||||||
|
#include "scssdk.h" |
||||||
|
#include "scssdk_value.h" |
||||||
|
#include "scssdk_input_event.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Types of input devices. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
|
||||||
|
typedef scs_u32_t scs_input_device_type_t; |
||||||
|
const scs_input_device_type_t SCS_INPUT_DEVICE_TYPE_INVALID = 0; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generic device bindable in the game UI. |
||||||
|
*/ |
||||||
|
const scs_input_device_type_t SCS_INPUT_DEVICE_TYPE_generic = 1; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Semantical device. |
||||||
|
* |
||||||
|
* The inputs of this device map directly to mixes with the same |
||||||
|
* name the same way the Steam Input works. No binding UI is |
||||||
|
* supported. This allows the device to work without user having |
||||||
|
* to do any configuration however it also means that if the |
||||||
|
* game mixes change, the user will be unable to adjust the binding |
||||||
|
* and a plugin update will be required. |
||||||
|
* |
||||||
|
* Note that only subset of mixes are supported. If mix expression |
||||||
|
* in a fresh controls.sii references something like "semantical.<mixname>?0", |
||||||
|
* then semantical input is likely supported for that mix. |
||||||
|
*/ |
||||||
|
const scs_input_device_type_t SCS_INPUT_DEVICE_TYPE_semantical = 2; |
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximal number of inputs allowed on a single device. |
||||||
|
*/ |
||||||
|
const scs_u32_t SCS_INPUT_MAX_INPUT_COUNT = 400; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Information about a single input of the input device. |
||||||
|
*/ |
||||||
|
struct scs_input_device_input_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Name of this input used in the configuration file |
||||||
|
* |
||||||
|
* This string can contain only the following characters: |
||||||
|
* @li lower-cased english letters |
||||||
|
* @li digits |
||||||
|
* @li underscore |
||||||
|
*/ |
||||||
|
scs_string_t name; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of the input shown to the user. |
||||||
|
* |
||||||
|
* Currently only the following characters are allowed: |
||||||
|
* @li English letters |
||||||
|
* @li digits |
||||||
|
* @li underscore |
||||||
|
* @li space |
||||||
|
* @li dot |
||||||
|
*/ |
||||||
|
scs_string_t display_name; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of the value provided by this input. |
||||||
|
* |
||||||
|
* Only the following value types are supported: |
||||||
|
* @li SCS_VALUE_TYPE_bool |
||||||
|
* @li SCS_VALUE_TYPE_float |
||||||
|
*/ |
||||||
|
scs_value_type_t value_type; |
||||||
|
|
||||||
|
#ifdef SCS_ARCHITECTURE_x64 |
||||||
|
/**
|
||||||
|
* @brief Explicit 8-byte alignment for structure size. |
||||||
|
*/ |
||||||
|
scs_u32_t _padding; |
||||||
|
#endif |
||||||
|
}; |
||||||
|
scs_check_size(scs_input_device_input_t, 12, 24); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of function called to notify about changes in device activity state |
||||||
|
* |
||||||
|
* @param active Nonzero if the device is active and processing events. |
||||||
|
* @param context Context information passed during device registration. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_VOID_FPTR(scs_input_active_callback_t)(const scs_u8_t active, const scs_context_t context); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input device. |
||||||
|
*/ |
||||||
|
struct scs_input_device_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Name of this device used in the configuration file |
||||||
|
* |
||||||
|
* Must be unique among all input plugins. |
||||||
|
* |
||||||
|
* This string can contain only the following characters: |
||||||
|
* @li lower-cased English letters |
||||||
|
* @li digits |
||||||
|
* @li underscore |
||||||
|
*/ |
||||||
|
scs_string_t name; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name of the device shown to the user. |
||||||
|
* |
||||||
|
* Currently only the following characters are allowed: |
||||||
|
* @li English letters |
||||||
|
* @li digits |
||||||
|
* @li underscore |
||||||
|
* @li space |
||||||
|
* @li dot |
||||||
|
*/ |
||||||
|
scs_string_t display_name; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of this device. |
||||||
|
*/ |
||||||
|
scs_input_device_type_t type; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of inputs in the inputs array. |
||||||
|
* |
||||||
|
* There must be at least one input. |
||||||
|
*/ |
||||||
|
scs_u32_t input_count; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Individual inputs. |
||||||
|
*/ |
||||||
|
const scs_input_device_input_t *inputs; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Context value to provide to the callbacks. |
||||||
|
*/ |
||||||
|
scs_context_t callback_context; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback called when device activity state changes |
||||||
|
* |
||||||
|
* Optional |
||||||
|
*/ |
||||||
|
scs_input_active_callback_t input_active_callback; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback to call to retrieve input events. |
||||||
|
* |
||||||
|
* Only called when the device is active. |
||||||
|
* |
||||||
|
* Required |
||||||
|
*/ |
||||||
|
scs_input_event_callback_t input_event_callback; |
||||||
|
}; |
||||||
|
scs_check_size(scs_input_device_t, 32, 56); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers a input device |
||||||
|
* |
||||||
|
* This function can be only called from scs_input_init. Devices are automatically unregistered before |
||||||
|
* calling scs_input_shutdown. |
||||||
|
* |
||||||
|
* @param device_info Information about the device. The structure is fully processed during the call. |
||||||
|
* @return SCS_RESULT_ok on successful registration. Error code otherwise. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_RESULT_FPTR(scs_input_register_device_t)(const scs_input_device_t *const device_info); |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_INPUT_DEVICE_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,68 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_input_event.h |
||||||
|
* |
||||||
|
* @brief Input SDK - events. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_INPUT_EVENT_H |
||||||
|
#define SCSSDK_INPUT_EVENT_H |
||||||
|
|
||||||
|
#include "scssdk.h" |
||||||
|
#include "scssdk_value.h" |
||||||
|
#include "scssdk_input_event.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Information about a input event. |
||||||
|
*/ |
||||||
|
struct scs_input_event_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Zero-based index of input this event is for. |
||||||
|
*/ |
||||||
|
scs_u32_t input_index; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The event value. |
||||||
|
* |
||||||
|
* Must use the value type corresponding to the value_type the input was registered with. |
||||||
|
*/ |
||||||
|
union { |
||||||
|
scs_value_bool_t value_bool; |
||||||
|
scs_value_float_t value_float; |
||||||
|
float _sizing_for_future_extensions[6]; |
||||||
|
}; |
||||||
|
}; |
||||||
|
scs_check_size(scs_input_event_t, 28, 28); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Indicates that this is the first call of this callback for the current device in the current frame. |
||||||
|
*/ |
||||||
|
const scs_u32_t SCS_INPUT_EVENT_CALLBACK_FLAG_first_in_frame = 0x00000001; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Indicates that this is the first call of this callback after device became active. |
||||||
|
* |
||||||
|
* When this flag is set, the first_in_frame flag will be set as well. |
||||||
|
*/ |
||||||
|
const scs_u32_t SCS_INPUT_EVENT_CALLBACK_FLAG_first_after_activation = 0x00000002; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of function called to retrieve next event from the input device |
||||||
|
* |
||||||
|
* This function is called on the main thread and must be quick. In each frame where the |
||||||
|
* device is active, this function will be called repeatedly until it returns SCS_RESULT_not_found. |
||||||
|
* |
||||||
|
* @param[out] event_info Store the event info here. Ignored if the function returns anything other than SCS_RESULT_ok. |
||||||
|
* @param flags Combination of relevant SCS_INPUT_EVENT_CALLBACK_FLAG_* flags. |
||||||
|
* @param context Context information passed during device registration. |
||||||
|
* @return SCS_RESULT_ok when event was retrieved, SCS_RESULT_not_found when there was no event. Any other value |
||||||
|
* will disconnect the device and prevent future related callbacks. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_RESULT_FPTR(scs_input_event_callback_t)(scs_input_event_t *const event_info, const scs_u32_t flags, const scs_context_t context); |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_INPUT_EVENT_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,107 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry.h |
||||||
|
* |
||||||
|
* @brief Telemetry SDK. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_H |
||||||
|
#define SCSSDK_TELEMETRY_H |
||||||
|
|
||||||
|
#include "scssdk.h" |
||||||
|
#include "scssdk_value.h" |
||||||
|
#include "scssdk_telemetry_event.h" |
||||||
|
#include "scssdk_telemetry_channel.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Versions of the telemetry SDK |
||||||
|
* |
||||||
|
* Changes in the major version indicate incompatible changes in the API. |
||||||
|
* Changes in the minor version indicate additions (e.g. more events, defined |
||||||
|
* types as long layout of existing fields in scs_value_t does not change). |
||||||
|
* |
||||||
|
* 1.01 version - added s64 type support, added gameplay events |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
#define SCS_TELEMETRY_VERSION_1_00 SCS_MAKE_VERSION(1, 0) |
||||||
|
#define SCS_TELEMETRY_VERSION_1_01 SCS_MAKE_VERSION(1, 1) |
||||||
|
#define SCS_TELEMETRY_VERSION_CURRENT SCS_TELEMETRY_VERSION_1_01 |
||||||
|
//@}
|
||||||
|
|
||||||
|
// Structures used to pass additional data to the initialization function.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Common ancestor to all structures providing parameters to the telemetry |
||||||
|
* initialization. |
||||||
|
*/ |
||||||
|
struct scs_telemetry_init_params_t |
||||||
|
{ |
||||||
|
void method_indicating_this_is_not_a_c_struct(void); |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization parameters for the 1.00 version of the telemetry API. |
||||||
|
*/ |
||||||
|
struct scs_telemetry_init_params_v100_t : public scs_telemetry_init_params_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Common initialization parameters. |
||||||
|
*/ |
||||||
|
scs_sdk_init_params_v100_t common; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Functions used to handle registration of event callbacks. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
scs_telemetry_register_for_event_t register_for_event; |
||||||
|
scs_telemetry_unregister_from_event_t unregister_from_event; |
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Functions used to handle registration of telemetry callbacks. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
scs_telemetry_register_for_channel_t register_for_channel; |
||||||
|
scs_telemetry_unregister_from_channel_t unregister_from_channel; |
||||||
|
//@}
|
||||||
|
}; |
||||||
|
scs_check_size(scs_telemetry_init_params_v100_t, 32, 64); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization parameters for the 1.01 version of the telemetry API. |
||||||
|
*/ |
||||||
|
typedef scs_telemetry_init_params_v100_t scs_telemetry_init_params_v101_t; |
||||||
|
|
||||||
|
// Functions which should be exported by the dynamic library serving as
|
||||||
|
// recipient of the telemetry.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes telemetry support. |
||||||
|
* |
||||||
|
* This function must be provided by the library if it wants to support telemetry API. |
||||||
|
* |
||||||
|
* The engine will call this function with API versions it supports starting from the latest |
||||||
|
* until the function returns SCS_RESULT_ok or error other than SCS_RESULT_unsupported or it |
||||||
|
* runs out of supported versions. |
||||||
|
* |
||||||
|
* At the time this function is called, the telemetry is in the paused state. |
||||||
|
* |
||||||
|
* @param version Version of the API to initialize. |
||||||
|
* @param params Structure with additional initialization data specific to the specified API version. |
||||||
|
* @return SCS_RESULT_ok if version is supported and library was initialized. Error code otherwise. |
||||||
|
*/ |
||||||
|
SCSAPI_RESULT scs_telemetry_init (const scs_u32_t version, const scs_telemetry_init_params_t *const params); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shuts down the telemetry support. |
||||||
|
* |
||||||
|
* The engine will call this function if available and if the scs_telemetry_init indicated |
||||||
|
* success. |
||||||
|
*/ |
||||||
|
SCSAPI_VOID scs_telemetry_shutdown (void); |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,104 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_channel.h |
||||||
|
* |
||||||
|
* @brief Telemetry SDK - channels. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_CHANNEL_H |
||||||
|
#define SCSSDK_TELEMETRY_CHANNEL_H |
||||||
|
|
||||||
|
#include "scssdk.h" |
||||||
|
#include "scssdk_value.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Telemetry channel flags. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief No specific flags. |
||||||
|
*/ |
||||||
|
const scs_u32_t SCS_TELEMETRY_CHANNEL_FLAG_none = 0x00000000; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Call the callback even if the value did not change. |
||||||
|
* |
||||||
|
* The default behavior is to only call the callback if the |
||||||
|
* value changes. Note that there might be some special situations |
||||||
|
* where the callback might be called even if the value did not |
||||||
|
* change and this flag is not present. For example when the |
||||||
|
* provider of the channel value is reconfigured or when the value |
||||||
|
* changes so frequently that filtering would be only waste of time. |
||||||
|
* |
||||||
|
* Note that even this flag does not guarantee that the |
||||||
|
* callback will be called. For example it might be not called |
||||||
|
* when the value is currently unavailable and the |
||||||
|
* SCS_TELEMETRY_CHANNEL_FLAG_no_value flag was not provided. |
||||||
|
*/ |
||||||
|
const scs_u32_t SCS_TELEMETRY_CHANNEL_FLAG_each_frame = 0x00000001; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Call the callback even if the value is currently |
||||||
|
* unavailable. |
||||||
|
* |
||||||
|
* By default the callback is only called when the value is |
||||||
|
* available. If this flag is specified, the callback will be |
||||||
|
* called even when the value is unavailable. In that case |
||||||
|
* the value parameter of the callback will be set to NULL. |
||||||
|
*/ |
||||||
|
const scs_u32_t SCS_TELEMETRY_CHANNEL_FLAG_no_value = 0x00000002; |
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of function registered to be called with value of single telemetry channel. |
||||||
|
* |
||||||
|
* @param name Name of the channel. Intended for debugging purposes only. |
||||||
|
* @param index Index of entry for array-like channels. |
||||||
|
* @param value Current value of the channel. Will use the type provided during the registration. |
||||||
|
* Will be NULL if and only if the SCS_TELEMETRY_CHANNEL_FLAG_no_value flag was specified |
||||||
|
* during registration and the value is currently unavailable. |
||||||
|
* @param context Context information passed during callback registration. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_VOID_FPTR(scs_telemetry_channel_callback_t)(const scs_string_t name, const scs_u32_t index, const scs_value_t *const value, const scs_context_t context); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers callback to be called with value of specified telemetry channel. |
||||||
|
* |
||||||
|
* At most one callback can be registered for each combination of channel name, index and type. |
||||||
|
* |
||||||
|
* Note that order in which the registered callbacks are called is undefined. |
||||||
|
* |
||||||
|
* This funtion can be called from scs_telemetry_init or from within any |
||||||
|
* event (NOT channel) callback. |
||||||
|
* |
||||||
|
* @param name Name of channel to register to. |
||||||
|
* @param index Index of entry for array-like channels. Set to SCS_U32_NIL for normal channels. |
||||||
|
* @param type Desired type of the value. Only some types are supported (see documentation of specific channel). If the channel can not be returned using that type a SCS_RESULT_unsupported_type will be returned. |
||||||
|
* @param flags Flags controlling delivery of the channel. |
||||||
|
* @param callback Callback to register. |
||||||
|
* @param context Context value passed to the callback. |
||||||
|
* @return SCS_RESULT_ok on successful registration. Error code otherwise. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_RESULT_FPTR(scs_telemetry_register_for_channel_t)(const scs_string_t name, const scs_u32_t index, const scs_value_type_t type, const scs_u32_t flags, const scs_telemetry_channel_callback_t callback, const scs_context_t context); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unregisters callback registered for specified telemetry channel. |
||||||
|
* |
||||||
|
* This function can be called from scs_telemetry_shutdown, scs_telemetry_init |
||||||
|
* or from within any event (NOT channel) callback. Any channel left registered |
||||||
|
* after scs_telemetry_shutdown ends will be unregistered automatically. |
||||||
|
* |
||||||
|
* @param name Name of channel to register from. |
||||||
|
* @param index Index of entry for array-like channels. Set to SCS_U32_NIL for normal channels. |
||||||
|
* @param type Type of value to unregister from. |
||||||
|
* @return SCS_RESULT_ok on successful unregistration. Error code otherwise. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_RESULT_FPTR(scs_telemetry_unregister_from_channel_t)(const scs_string_t name, const scs_u32_t index, const scs_value_type_t type); |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_CHANNEL_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,239 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_telemetry_event.h |
||||||
|
* |
||||||
|
* @brief Telemetry SDK - events. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_TELEMETRY_EVENT_H |
||||||
|
#define SCSSDK_TELEMETRY_EVENT_H |
||||||
|
|
||||||
|
#include "scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
typedef scs_u32_t scs_event_t; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Telemetry event types. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Used to mark invalid value of event type. |
||||||
|
*/ |
||||||
|
const scs_event_t SCS_TELEMETRY_EVENT_invalid = 0; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generated before any telemetry data for current frame. |
||||||
|
* |
||||||
|
* The event_info parameter for this event points to |
||||||
|
* scs_telemetry_frame_start_t structure. |
||||||
|
*/ |
||||||
|
const scs_event_t SCS_TELEMETRY_EVENT_frame_start = 1; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generated after all telemetry data for current frame. |
||||||
|
*/ |
||||||
|
const scs_event_t SCS_TELEMETRY_EVENT_frame_end = 2; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Indicates that the game entered paused state (e.g. menu) |
||||||
|
* |
||||||
|
* If the recipient generates some form of force feedback effects, |
||||||
|
* it should probably stop them until SCS_TELEMETRY_EVENT_started |
||||||
|
* event is received. |
||||||
|
* |
||||||
|
* After sending this event, the game stop sending telemetry data |
||||||
|
* unless specified otherwise in description of specific telemetry. |
||||||
|
* The frame start and event events are still generated. |
||||||
|
*/ |
||||||
|
const scs_event_t SCS_TELEMETRY_EVENT_paused = 3; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Indicates that the player is now driving. |
||||||
|
*/ |
||||||
|
const scs_event_t SCS_TELEMETRY_EVENT_started = 4; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provides set of attributes which change only |
||||||
|
* in special situations (e.g. parameters of the vehicle). |
||||||
|
* |
||||||
|
* The event_info parameter for this event points to |
||||||
|
* scs_telemetry_configuration_t structure. |
||||||
|
* |
||||||
|
* The initial configuration info is delivered to the plugin |
||||||
|
* after its scs_telemetry_init() function succeeds and before |
||||||
|
* any other callback is called. If the the plugin is interested |
||||||
|
* in the configuration info, it must register for this event |
||||||
|
* during its initialization call to ensure that it does |
||||||
|
* not miss it. Future changes in configuration are |
||||||
|
* delivered as described in the event sequence below. |
||||||
|
*/ |
||||||
|
const scs_event_t SCS_TELEMETRY_EVENT_configuration = 5; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief An event called when a gameplay event such as job finish happens. |
||||||
|
* |
||||||
|
* The event_info parameter for this event points to scs_telemetry_gameplay_event_t structure. |
||||||
|
*/ |
||||||
|
const scs_event_t SCS_TELEMETRY_EVENT_gameplay = 6; |
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
// Sequence of events during frame.
|
||||||
|
//
|
||||||
|
// @li Optionally one or more CONFIGURATION events if the configuration changed.
|
||||||
|
// @li Optionally one from PAUSED or STARTED if there was change since last frame.
|
||||||
|
// @li FRAME_START
|
||||||
|
// @li Optionally one or more GAMEPLAY events.
|
||||||
|
// @li Channel callbacks
|
||||||
|
// @li FRAME_END
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Indicates that timers providing the frame timing info |
||||||
|
* were restarted since last frame. |
||||||
|
* |
||||||
|
* When timer is restarted, it will start counting from zero. |
||||||
|
*/ |
||||||
|
const scs_u32_t SCS_TELEMETRY_FRAME_START_FLAG_timer_restart = 0x00000001; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parameters the for SCS_TELEMETRY_EVENT_frame_start event callback. |
||||||
|
*/ |
||||||
|
struct scs_telemetry_frame_start_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Additional information about this event. |
||||||
|
* |
||||||
|
* Combination of SCS_TELEMETRY_FRAME_START_FLAG_* values. |
||||||
|
*/ |
||||||
|
scs_u32_t flags; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Explicit alignment for the 64 bit timestamps. |
||||||
|
*/ |
||||||
|
scs_u32_t _padding; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Time controlling the visualization. |
||||||
|
* |
||||||
|
* Its step changes depending on rendering FPS. |
||||||
|
*/ |
||||||
|
scs_timestamp_t render_time; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Time controlling the physical simulation. |
||||||
|
* |
||||||
|
* Usually changes with fixed size steps so it oscilates |
||||||
|
* around the render time. This value changes even if the |
||||||
|
* physics simulation is currently paused. |
||||||
|
*/ |
||||||
|
scs_timestamp_t simulation_time; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Similar to simulation time however it stops |
||||||
|
* when the physics simulation is paused. |
||||||
|
*/ |
||||||
|
scs_timestamp_t paused_simulation_time; |
||||||
|
}; |
||||||
|
|
||||||
|
scs_check_size(scs_telemetry_frame_start_t, 32, 32); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parameters for the SCS_TELEMETRY_EVENT_configuration event callback. |
||||||
|
*/ |
||||||
|
struct scs_telemetry_configuration_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Set of logically grouped configuration parameters this |
||||||
|
* event describes (e.g. truck configuration, trailer configuration). |
||||||
|
* |
||||||
|
* See SCS_TELEMETRY_CONFIGURATION_ID_* constants for the game in question. |
||||||
|
* |
||||||
|
* This pointer will be never NULL. |
||||||
|
*/ |
||||||
|
scs_string_t id; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Array of individual attributes. |
||||||
|
* |
||||||
|
* The array is terminated by entry whose name pointer is set to NULL. |
||||||
|
* |
||||||
|
* Names of the attributes are the SCS_TELEMETRY_CONFIG_ATTRIBUTE_* constants |
||||||
|
* for the game in question. |
||||||
|
* |
||||||
|
* This pointer will be never NULL. |
||||||
|
*/ |
||||||
|
const scs_named_value_t *attributes; |
||||||
|
}; |
||||||
|
|
||||||
|
scs_check_size(scs_telemetry_configuration_t, 8, 16); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parameters for the SCS_TELEMETRY_EVENT_gameplay event callback. |
||||||
|
*/ |
||||||
|
struct scs_telemetry_gameplay_event_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief The event id. |
||||||
|
* |
||||||
|
* The event ID name - check SCS_TELEMETRY_GAMEPLAY_EVENT_* for possible names. |
||||||
|
*/ |
||||||
|
scs_string_t id; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Array of individual attributes. |
||||||
|
* |
||||||
|
* The array is terminated by entry whose name pointer is set to NULL. |
||||||
|
* |
||||||
|
* Names of the attributes are the SCS_TELEMETRY_GAMEPLAY_EVENT_ATTRIBUTE_* constants |
||||||
|
* for the game in question. |
||||||
|
* |
||||||
|
* This pointer will be never NULL. |
||||||
|
*/ |
||||||
|
const scs_named_value_t *attributes; |
||||||
|
}; |
||||||
|
|
||||||
|
scs_check_size(scs_telemetry_gameplay_event_t, 8, 16); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of function registered to be called for event. |
||||||
|
* |
||||||
|
* @param event Event in question. Allows use of single callback with more than one event. |
||||||
|
* @param event_info Structure with additional event information about the event. |
||||||
|
* @param context Context information passed during callback registration. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_VOID_FPTR(scs_telemetry_event_callback_t)(const scs_event_t event, const void *const event_info, const scs_context_t context); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers callback to be called when specified event happens. |
||||||
|
* |
||||||
|
* At most one callback can be registered for each event. |
||||||
|
* |
||||||
|
* This funtion can be called from scs_telemetry_init or from within any |
||||||
|
* event callback other than the callback for the event itself. |
||||||
|
* |
||||||
|
* @param event Event to register for. |
||||||
|
* @param callback Callback to register. |
||||||
|
* @param context Context value passed to the callback. |
||||||
|
* @return SCS_RESULT_ok on successful registration. Error code otherwise. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_RESULT_FPTR(scs_telemetry_register_for_event_t)(const scs_event_t event, const scs_telemetry_event_callback_t callback, const scs_context_t context); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unregisters callback registered for specified event. |
||||||
|
* |
||||||
|
* This function can be called from scs_telemetry_shutdown, scs_telemetry_init |
||||||
|
* or from within any event callback. Including callback of the event itself. |
||||||
|
* Any event left registered after scs_telemetry_shutdown ends will |
||||||
|
* be unregistered automatically. |
||||||
|
* |
||||||
|
* @param event Event to unregister from. |
||||||
|
* @return SCS_RESULT_ok on successful unregistration. Error code otherwise. |
||||||
|
*/ |
||||||
|
typedef SCSAPI_RESULT_FPTR(scs_telemetry_unregister_from_event_t)(const scs_event_t event); |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_TELEMETRY_EVENT_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,247 @@ |
|||||||
|
/**
|
||||||
|
* @file scssdk_value.h |
||||||
|
* |
||||||
|
* @brief Structures representing varying type values in the SDK. |
||||||
|
*/ |
||||||
|
#ifndef SCSSDK_VALUE_H |
||||||
|
#define SCSSDK_VALUE_H |
||||||
|
|
||||||
|
#include "scssdk.h" |
||||||
|
|
||||||
|
SCSSDK_HEADER |
||||||
|
|
||||||
|
typedef scs_u32_t scs_value_type_t; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_INVALID = 0; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_bool = 1; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_s32 = 2; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_u32 = 3; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_u64 = 4; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_float = 5; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_double = 6; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_fvector = 7; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_dvector = 8; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_euler = 9; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_fplacement = 10; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_dplacement = 11; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_string = 12; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_s64 = 13; |
||||||
|
const scs_value_type_t SCS_VALUE_TYPE_LAST = SCS_VALUE_TYPE_s64; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Simple data types. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
struct scs_value_bool_t |
||||||
|
{ |
||||||
|
scs_u8_t value; //< Nonzero value is true, zero false.
|
||||||
|
}; |
||||||
|
|
||||||
|
struct scs_value_s32_t |
||||||
|
{ |
||||||
|
scs_s32_t value; |
||||||
|
}; |
||||||
|
|
||||||
|
struct scs_value_u32_t |
||||||
|
{ |
||||||
|
scs_u32_t value; |
||||||
|
}; |
||||||
|
|
||||||
|
struct scs_value_u64_t |
||||||
|
{ |
||||||
|
scs_u64_t value; |
||||||
|
}; |
||||||
|
|
||||||
|
struct scs_value_s64_t |
||||||
|
{ |
||||||
|
scs_s64_t value; |
||||||
|
}; |
||||||
|
|
||||||
|
struct scs_value_float_t |
||||||
|
{ |
||||||
|
scs_float_t value; |
||||||
|
}; |
||||||
|
|
||||||
|
struct scs_value_double_t |
||||||
|
{ |
||||||
|
scs_double_t value; |
||||||
|
}; |
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief String value. |
||||||
|
* |
||||||
|
* The provided value is UTF8 encoded however in some documented |
||||||
|
* cases only limited ASCII compatible subset might be present. |
||||||
|
* |
||||||
|
* The pointer is never NULL. |
||||||
|
*/ |
||||||
|
struct scs_value_string_t |
||||||
|
{ |
||||||
|
scs_string_t value; |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Vector types. |
||||||
|
* |
||||||
|
* In local space the X points to right, Y up and Z backwards. |
||||||
|
* In world space the X points to east, Y up and Z south. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
struct scs_value_fvector_t |
||||||
|
{ |
||||||
|
scs_float_t x; |
||||||
|
scs_float_t y; |
||||||
|
scs_float_t z; |
||||||
|
}; |
||||||
|
|
||||||
|
struct scs_value_dvector_t |
||||||
|
{ |
||||||
|
scs_double_t x; |
||||||
|
scs_double_t y; |
||||||
|
scs_double_t z; |
||||||
|
}; |
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Orientation of object. |
||||||
|
*/ |
||||||
|
struct scs_value_euler_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Heading. |
||||||
|
* |
||||||
|
* Stored in unit range where <0,1) corresponds to <0,360). |
||||||
|
* |
||||||
|
* The angle is measured counterclockwise in horizontal plane when looking |
||||||
|
* from top where 0 corresponds to forward (north), 0.25 to left (west), |
||||||
|
* 0.5 to backward (south) and 0.75 to right (east). |
||||||
|
*/ |
||||||
|
scs_float_t heading; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pitch |
||||||
|
* |
||||||
|
* Stored in unit range where <-0.25,0.25> corresponds to <-90,90>. |
||||||
|
* |
||||||
|
* The pitch angle is zero when in horizontal direction, |
||||||
|
* with positive values pointing up (0.25 directly to zenith), |
||||||
|
* and negative values pointing down (-0.25 directly to nadir). |
||||||
|
*/ |
||||||
|
scs_float_t pitch; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Roll |
||||||
|
* |
||||||
|
* Stored in unit range where <-0.5,0.5> corresponds to <-180,180>. |
||||||
|
* |
||||||
|
* The angle is measured in counterclockwise when looking in direction of |
||||||
|
* the roll axis. |
||||||
|
*/ |
||||||
|
scs_float_t roll; |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Combination of position and orientation. |
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
struct scs_value_fplacement_t |
||||||
|
{ |
||||||
|
scs_value_fvector_t position; |
||||||
|
scs_value_euler_t orientation; |
||||||
|
}; |
||||||
|
|
||||||
|
struct scs_value_dplacement_t |
||||||
|
{ |
||||||
|
scs_value_dvector_t position; |
||||||
|
scs_value_euler_t orientation; |
||||||
|
scs_u32_t _padding; // Explicit padding.
|
||||||
|
}; |
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Varying type storage for values. |
||||||
|
*/ |
||||||
|
struct scs_value_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Type of the value. |
||||||
|
*/ |
||||||
|
scs_value_type_t type; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Explicit alignment for the union. |
||||||
|
*/ |
||||||
|
scs_u32_t _padding; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Storage. |
||||||
|
*/ |
||||||
|
union { |
||||||
|
scs_value_bool_t value_bool; |
||||||
|
scs_value_s32_t value_s32; |
||||||
|
scs_value_u32_t value_u32; |
||||||
|
scs_value_u64_t value_u64; |
||||||
|
scs_value_s64_t value_s64; |
||||||
|
scs_value_float_t value_float; |
||||||
|
scs_value_double_t value_double; |
||||||
|
scs_value_fvector_t value_fvector; |
||||||
|
scs_value_dvector_t value_dvector; |
||||||
|
scs_value_euler_t value_euler; |
||||||
|
scs_value_fplacement_t value_fplacement; |
||||||
|
scs_value_dplacement_t value_dplacement; |
||||||
|
scs_value_string_t value_string; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
scs_check_size(scs_value_s32_t, 4, 4); |
||||||
|
scs_check_size(scs_value_u32_t, 4, 4); |
||||||
|
scs_check_size(scs_value_u64_t, 8, 8); |
||||||
|
scs_check_size(scs_value_s64_t, 8, 8); |
||||||
|
scs_check_size(scs_value_float_t, 4, 4); |
||||||
|
scs_check_size(scs_value_double_t, 8, 8); |
||||||
|
scs_check_size(scs_value_fvector_t, 12, 12); |
||||||
|
scs_check_size(scs_value_dvector_t, 24, 24); |
||||||
|
scs_check_size(scs_value_fplacement_t, 24, 24); |
||||||
|
scs_check_size(scs_value_dplacement_t, 40, 40); |
||||||
|
scs_check_size(scs_value_string_t, 4, 8); |
||||||
|
scs_check_size(scs_value_t, 48, 48); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Combination of value and its name. |
||||||
|
*/ |
||||||
|
struct scs_named_value_t |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief Name of this value. |
||||||
|
* |
||||||
|
* ASCII subset of UTF-8. |
||||||
|
*/ |
||||||
|
scs_string_t name; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Zero-based index of the value for array-like values. |
||||||
|
* |
||||||
|
* For non-array values it is set to SCS_U32_NIL. |
||||||
|
*/ |
||||||
|
scs_u32_t index; |
||||||
|
|
||||||
|
#ifdef SCS_ARCHITECTURE_x64 |
||||||
|
/**
|
||||||
|
* @brief Explicit 8-byte alignment for the value part. |
||||||
|
*/ |
||||||
|
scs_u32_t _padding; |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The value itself. |
||||||
|
*/ |
||||||
|
scs_value_t value; |
||||||
|
}; |
||||||
|
|
||||||
|
scs_check_size(scs_named_value_t, 56, 64); |
||||||
|
|
||||||
|
SCSSDK_FOOTER |
||||||
|
|
||||||
|
#endif // SCSSDK_VALUE_H
|
||||||
|
|
||||||
|
/* eof */ |
@ -0,0 +1,20 @@ |
|||||||
|
SCS SDK |
||||||
|
Copyright (C) 2016 SCS Software |
||||||
|
|
||||||
|
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 the Software. |
||||||
|
|
||||||
|
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. |
Loading…
Reference in new issue