From 9ca3e6556b4b52e51f179de599c2d8235a6eec4e Mon Sep 17 00:00:00 2001 From: ShiralynDev Date: Tue, 20 Jan 2026 04:29:48 +0100 Subject: [PATCH 1/9] Don't track vscode --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a193ac6..887e293 100644 --- a/.gitignore +++ b/.gitignore @@ -362,4 +362,5 @@ MigrationBackup/ # Fody - auto-generated XML schema FodyWeavers.xsd -build \ No newline at end of file +build +.vscode \ No newline at end of file From 4b97e6f6418ee6e25a42acd4f9b0a3ef638a026f Mon Sep 17 00:00:00 2001 From: Shiralyn <68858896+ShiralynDev@users.noreply.github.com> Date: Tue, 20 Jan 2026 04:30:03 +0100 Subject: [PATCH 2/9] Delete .vscode directory --- .vscode/settings.json | 80 ------------------------------------------- 1 file changed, 80 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 14c1bc1..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "files.associations": { - "atc.h": "c", - "stdbool.h": "c", - "iostream": "cpp", - "cstdlib": "c", - "unistd.h": "c", - "atcdata.h": "c", - "runatc.h": "c", - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdio": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "charconv": "cpp", - "compare": "cpp", - "complex": "cpp", - "concepts": "cpp", - "cstdint": "cpp", - "deque": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "format": "cpp", - "fstream": "cpp", - "initializer_list": "cpp", - "iosfwd": "cpp", - "istream": "cpp", - "limits": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "semaphore": "cpp", - "span": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "text_encoding": "cpp", - "thread": "cpp", - "cinttypes": "cpp", - "typeinfo": "cpp", - "variant": "cpp", - "time.h": "c", - "*.m": "c", - "cstring": "cpp", - "condition_variable": "cpp", - "source_location": "cpp", - "mutex": "cpp", - "cfenv": "cpp", - "atcstartup.h": "c", - "chrono": "cpp", - "__nullptr": "cpp", - "__verbose_abort": "cpp", - "atcerrors.h": "c" - }, - "cmake.sourceDirectory": "/home/sparkles/Coding/ATC/Examples/C++" -} \ No newline at end of file From f1cdb7ae8a56d64b3ec6f00438df41b216f17468 Mon Sep 17 00:00:00 2001 From: ShiralynDev Date: Thu, 22 Jan 2026 15:05:29 +0100 Subject: [PATCH 3/9] Start of rewrite --- ATC/JSWrapper/JSWarpper.js | 14 --- ATC/JSWrapper/package-lock.json | 109 ------------------ ATC/JSWrapper/package.json | 5 - ATC/PythonWrapper/ATC.dll | Bin 104960 -> 0 bytes ATC/PythonWrapper/PythonWrapper.py | 10 -- ATC_Dator/CMakeLists.txt | 38 ++++++ ATC_Dator/build.sh | 9 ++ ATC_Dator/src/main.cpp | 8 ++ .../C++/ExtendedDebugPanel/CMakeLists.txt | 33 ++++++ ATC_Panel/C++/ExtendedDebugPanel/build.sh | 9 ++ ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp | 5 + Examples/JS/package-lock.json | 109 ------------------ Examples/JS/package.json | 5 - Examples/JS/test.js | 5 - Examples/Python/main.py | 6 - .../networking/sockets/tcpSocket.cpp | 17 +++ .../networking/sockets/tcpSocket.hpp | 26 +++++ UniversalFunctions/readme.md | 4 + UniversalFunctions/utils.hpp | 10 ++ Utils/build_all.sh | 11 ++ Utils/clear_build_all.sh | 9 ++ Utils/clear_rebuild_all.sh | 2 + Utils/readme.md | 10 ++ 23 files changed, 191 insertions(+), 263 deletions(-) delete mode 100644 ATC/JSWrapper/JSWarpper.js delete mode 100644 ATC/JSWrapper/package-lock.json delete mode 100644 ATC/JSWrapper/package.json delete mode 100644 ATC/PythonWrapper/ATC.dll delete mode 100644 ATC/PythonWrapper/PythonWrapper.py create mode 100644 ATC_Dator/CMakeLists.txt create mode 100644 ATC_Dator/build.sh create mode 100644 ATC_Dator/src/main.cpp create mode 100644 ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt create mode 100644 ATC_Panel/C++/ExtendedDebugPanel/build.sh create mode 100644 ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp delete mode 100644 Examples/JS/package-lock.json delete mode 100644 Examples/JS/package.json delete mode 100644 Examples/JS/test.js delete mode 100644 Examples/Python/main.py create mode 100644 UniversalFunctions/networking/sockets/tcpSocket.cpp create mode 100644 UniversalFunctions/networking/sockets/tcpSocket.hpp create mode 100644 UniversalFunctions/readme.md create mode 100644 UniversalFunctions/utils.hpp create mode 100644 Utils/build_all.sh create mode 100644 Utils/clear_build_all.sh create mode 100644 Utils/clear_rebuild_all.sh create mode 100644 Utils/readme.md diff --git a/ATC/JSWrapper/JSWarpper.js b/ATC/JSWrapper/JSWarpper.js deleted file mode 100644 index a26c62b..0000000 --- a/ATC/JSWrapper/JSWarpper.js +++ /dev/null @@ -1,14 +0,0 @@ -const ffi = require('ffi-napi'); - -path = '' -if (process.platform === 'win32') { - path = '../../ATC/build/ATC.dll' -} else { - path = '../../ATC/build/ATC.so' -} - -const ATC = ffi.Library(path, { //Change path after the working path of the file you include this from - 'thisReturnsOne': ['int', []] -}); - -module.exports = { ATC }; \ No newline at end of file diff --git a/ATC/JSWrapper/package-lock.json b/ATC/JSWrapper/package-lock.json deleted file mode 100644 index 053c1e5..0000000 --- a/ATC/JSWrapper/package-lock.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "name": "JSWrapper", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "ffi-napi": "^4.0.3" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/ffi-napi": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/ffi-napi/-/ffi-napi-4.0.3.tgz", - "integrity": "sha512-PMdLCIvDY9mS32RxZ0XGb95sonPRal8aqRhLbeEtWKZTe2A87qRFG9HjOhvG8EX2UmQw5XNRMIOT+1MYlWmdeg==", - "hasInstallScript": true, - "dependencies": { - "debug": "^4.1.1", - "get-uv-event-loop-napi-h": "^1.0.5", - "node-addon-api": "^3.0.0", - "node-gyp-build": "^4.2.1", - "ref-napi": "^2.0.1 || ^3.0.2", - "ref-struct-di": "^1.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-symbol-from-current-process-h": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", - "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" - }, - "node_modules/get-uv-event-loop-napi-h": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", - "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", - "dependencies": { - "get-symbol-from-current-process-h": "^1.0.1" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" - }, - "node_modules/node-gyp-build": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", - "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/ref-napi": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-3.0.3.tgz", - "integrity": "sha512-LiMq/XDGcgodTYOMppikEtJelWsKQERbLQsYm0IOOnzhwE9xYZC7x8txNnFC9wJNOkPferQI4vD4ZkC0mDyrOA==", - "hasInstallScript": true, - "dependencies": { - "debug": "^4.1.1", - "get-symbol-from-current-process-h": "^1.0.2", - "node-addon-api": "^3.0.0", - "node-gyp-build": "^4.2.1" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/ref-struct-di": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ref-struct-di/-/ref-struct-di-1.1.1.tgz", - "integrity": "sha512-2Xyn/0Qgz89VT+++WP0sTosdm9oeowLP23wRJYhG4BFdMUrLj3jhwHZNEytYNYgtPKLNTP3KJX4HEgBvM1/Y2g==", - "dependencies": { - "debug": "^3.1.0" - } - }, - "node_modules/ref-struct-di/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - } - } -} diff --git a/ATC/JSWrapper/package.json b/ATC/JSWrapper/package.json deleted file mode 100644 index 953fd2c..0000000 --- a/ATC/JSWrapper/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "ffi-napi": "^4.0.3" - } -} diff --git a/ATC/PythonWrapper/ATC.dll b/ATC/PythonWrapper/ATC.dll deleted file mode 100644 index 0f8a8d17d39723355c5d23944ae2fc4f5bde39b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104960 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 +#include "networking/sockets/tcpSocket.hpp" + +int main() { + std::cout << "Hello world\n"; + + Networking::TcpSocket tcpSocket; +} \ No newline at end of file diff --git a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt new file mode 100644 index 0000000..1219ffd --- /dev/null +++ b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.20) + +set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build) + +project(ATC_Panel_ExDebug) +set(CMAKE_CXX_STANDARD 20) # Use C++ 20 +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Enable Release mode +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +set(BUILD_SHARED_LIBS ON) +set(BUILD_EXAMPLES OFF) + +file(GLOB SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) + +set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") + +# Create the executable +add_executable(ATC_Panel_ExDebug ${SOURCES} ${RAYLIB_ADDITIONS_SOURCES}) + +# Apply Release mode specific settings +if(CMAKE_BUILD_TYPE STREQUAL "Release") + # Add optimization flags + target_compile_options(ATC_Panel_ExDebug PRIVATE -O3) + + # Optionally, strip symbols to reduce binary size + if (NOT WIN32) + target_link_options(ATC_Panel_ExDebug PRIVATE -s) + endif() +endif() diff --git a/ATC_Panel/C++/ExtendedDebugPanel/build.sh b/ATC_Panel/C++/ExtendedDebugPanel/build.sh new file mode 100644 index 0000000..a14bb36 --- /dev/null +++ b/ATC_Panel/C++/ExtendedDebugPanel/build.sh @@ -0,0 +1,9 @@ +set -e + +BUILD_DIR=build + +mkdir -p "$BUILD_DIR" +cd "$BUILD_DIR" + +cmake .. +cmake --build . diff --git a/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp new file mode 100644 index 0000000..55f5b30 --- /dev/null +++ b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp @@ -0,0 +1,5 @@ +#include + +int main() { + std::cout << "Hello world\n"; +} \ No newline at end of file diff --git a/Examples/JS/package-lock.json b/Examples/JS/package-lock.json deleted file mode 100644 index 053c1e5..0000000 --- a/Examples/JS/package-lock.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "name": "JSWrapper", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "ffi-napi": "^4.0.3" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/ffi-napi": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/ffi-napi/-/ffi-napi-4.0.3.tgz", - "integrity": "sha512-PMdLCIvDY9mS32RxZ0XGb95sonPRal8aqRhLbeEtWKZTe2A87qRFG9HjOhvG8EX2UmQw5XNRMIOT+1MYlWmdeg==", - "hasInstallScript": true, - "dependencies": { - "debug": "^4.1.1", - "get-uv-event-loop-napi-h": "^1.0.5", - "node-addon-api": "^3.0.0", - "node-gyp-build": "^4.2.1", - "ref-napi": "^2.0.1 || ^3.0.2", - "ref-struct-di": "^1.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-symbol-from-current-process-h": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", - "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" - }, - "node_modules/get-uv-event-loop-napi-h": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", - "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", - "dependencies": { - "get-symbol-from-current-process-h": "^1.0.1" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" - }, - "node_modules/node-gyp-build": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", - "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/ref-napi": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-3.0.3.tgz", - "integrity": "sha512-LiMq/XDGcgodTYOMppikEtJelWsKQERbLQsYm0IOOnzhwE9xYZC7x8txNnFC9wJNOkPferQI4vD4ZkC0mDyrOA==", - "hasInstallScript": true, - "dependencies": { - "debug": "^4.1.1", - "get-symbol-from-current-process-h": "^1.0.2", - "node-addon-api": "^3.0.0", - "node-gyp-build": "^4.2.1" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/ref-struct-di": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ref-struct-di/-/ref-struct-di-1.1.1.tgz", - "integrity": "sha512-2Xyn/0Qgz89VT+++WP0sTosdm9oeowLP23wRJYhG4BFdMUrLj3jhwHZNEytYNYgtPKLNTP3KJX4HEgBvM1/Y2g==", - "dependencies": { - "debug": "^3.1.0" - } - }, - "node_modules/ref-struct-di/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - } - } -} diff --git a/Examples/JS/package.json b/Examples/JS/package.json deleted file mode 100644 index 953fd2c..0000000 --- a/Examples/JS/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "ffi-napi": "^4.0.3" - } -} diff --git a/Examples/JS/test.js b/Examples/JS/test.js deleted file mode 100644 index 5f62d5b..0000000 --- a/Examples/JS/test.js +++ /dev/null @@ -1,5 +0,0 @@ -const Wrapper = require('../../ATC/JSWrapper/JSWarpper.js'); - -if (Wrapper.ATC.thisReturnsOne()) { - console.log("this works") -} \ No newline at end of file diff --git a/Examples/Python/main.py b/Examples/Python/main.py deleted file mode 100644 index 49d552a..0000000 --- a/Examples/Python/main.py +++ /dev/null @@ -1,6 +0,0 @@ -import sys -sys.path.append('../../ATC/PythonWrapper') -import PythonWrapper - -if PythonWrapper.ATC.thisReturnsOne(): - print ("This works woooo") \ No newline at end of file diff --git a/UniversalFunctions/networking/sockets/tcpSocket.cpp b/UniversalFunctions/networking/sockets/tcpSocket.cpp new file mode 100644 index 0000000..0f5d7ca --- /dev/null +++ b/UniversalFunctions/networking/sockets/tcpSocket.cpp @@ -0,0 +1,17 @@ +#include "tcpSocket.hpp" +#include + +namespace Networking { + TcpSocket::TcpSocket(int SocketDomain, int SocketType, int Protocol) { + socketFd = socket(SocketDomain, SocketType, Protocol); + + if (socketFd == -1) { + std::cerr << "Failed to open socket: " << errno << std::endl; + return; + } + + socketAddress.sin_family = SocketDomain; + socketAddress.sin_addr.s_addr = htonl(address); + socketAddress.sin_port = htons(port); + } +} \ No newline at end of file diff --git a/UniversalFunctions/networking/sockets/tcpSocket.hpp b/UniversalFunctions/networking/sockets/tcpSocket.hpp new file mode 100644 index 0000000..e570958 --- /dev/null +++ b/UniversalFunctions/networking/sockets/tcpSocket.hpp @@ -0,0 +1,26 @@ +#ifdef __linux__ + #include + #include + #include + #include +#elif _WIN32 + #include +#endif + +#include "../../utils.hpp" + +namespace Networking { + + class TcpSocket : private Utils::NoCopy { // add windows support + private: + sockaddr_in socketAddress; + in_port_t port = 1337; + in_addr_t address = INADDR_LOOPBACK; + int socketFd; + public: + TcpSocket(int SocketDomain = AF_INET, int SocketType = SOCK_STREAM | SOCK_NONBLOCK, int Protocol = 0); // AF_UNIX = local communication, allow other types later + TcpSocket(const TcpSocket&) = delete; + int bind(); + int connect(); + }; +} \ No newline at end of file diff --git a/UniversalFunctions/readme.md b/UniversalFunctions/readme.md new file mode 100644 index 0000000..b66ba6a --- /dev/null +++ b/UniversalFunctions/readme.md @@ -0,0 +1,4 @@ +## Folder explanation + +### Networking +Contains the code for sockets, ect needed by both the "dator" and the "panel" \ No newline at end of file diff --git a/UniversalFunctions/utils.hpp b/UniversalFunctions/utils.hpp new file mode 100644 index 0000000..dd6d294 --- /dev/null +++ b/UniversalFunctions/utils.hpp @@ -0,0 +1,10 @@ +namespace Utils { + + class NoCopy { + public: + NoCopy(const NoCopy&) = delete; + NoCopy& operator=(const NoCopy&) = delete; + NoCopy() = default; + }; + +} \ No newline at end of file diff --git a/Utils/build_all.sh b/Utils/build_all.sh new file mode 100644 index 0000000..f0fd6fe --- /dev/null +++ b/Utils/build_all.sh @@ -0,0 +1,11 @@ +set -e + +cd .. +cd ATC_Dator +bash build.sh + +cd .. +cd ATC_Panel +cd C++ +cd ExtendedDebugPanel +bash build.sh \ No newline at end of file diff --git a/Utils/clear_build_all.sh b/Utils/clear_build_all.sh new file mode 100644 index 0000000..5b73872 --- /dev/null +++ b/Utils/clear_build_all.sh @@ -0,0 +1,9 @@ +cd .. +cd ATC_Dator +rm -rf ./build + +cd .. +cd ATC_Panel +cd C++ +cd ExtendedDebugPanel +rm -rf ./build \ No newline at end of file diff --git a/Utils/clear_rebuild_all.sh b/Utils/clear_rebuild_all.sh new file mode 100644 index 0000000..bacd682 --- /dev/null +++ b/Utils/clear_rebuild_all.sh @@ -0,0 +1,2 @@ +bash ./clear_build_all.sh +bash ./build_all.sh \ No newline at end of file diff --git a/Utils/readme.md b/Utils/readme.md new file mode 100644 index 0000000..53de680 --- /dev/null +++ b/Utils/readme.md @@ -0,0 +1,10 @@ +# Scripts description + +### build_all.sh +build all the projects, runs the build.sh script in all the folders for diffrent sub-projects + +### clear_build_all.sh +deletes all build directories in the diffrent sub-projects + +### clear_rebuild_all.sh +runs clear_build_all.sh and build_all.sh \ No newline at end of file From d2a7b7f95b273541ca6cf44227f5b38331023c81 Mon Sep 17 00:00:00 2001 From: ShiralynDev Date: Fri, 23 Jan 2026 05:46:20 +0100 Subject: [PATCH 4/9] Raylib start --- .gitmodules | 12 +- ATC_Panel/C++/DebugPanel/readme.md | 5 + .../C++/ExtendedDebugPanel/CMakeLists.txt | 14 +++ ATC_Panel/C++/ExtendedDebugPanel/build.sh | 10 +- ATC_Panel/C++/ExtendedDebugPanel/readme.md | 5 + ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp | 110 +++++++++++++++++- ATC_Panel/C++/SimplePanel/readme.md | 6 + ATC_Panel/res/ATC1.wav | Bin 0 -> 96028 bytes ATC_Panel/res/ATC2.wav | Bin 0 -> 102616 bytes ATC_Panel/res/atcpanel2.png | Bin 0 -> 53866 bytes ATC_Panel/res/cleanATC.png | Bin 0 -> 30248 bytes ATC_Panel/res/down_arrow.png | Bin 0 -> 169 bytes ATC_Panel/res/f1.wav | Bin 0 -> 56584 bytes ATC_Panel/res/f2.wav | Bin 0 -> 76320 bytes ATC_Panel/res/temp.png | Bin 0 -> 102 bytes ATC_Panel/res/up_arrow.png | Bin 0 -> 160 bytes Examples/C++/extern/RaylibAdditions | 1 - .../networking/sockets/tcpSocket.hpp | 1 - extern/RaylibAdditions | 1 + {Examples/C++/extern => extern}/raylib | 0 20 files changed, 154 insertions(+), 11 deletions(-) create mode 100644 ATC_Panel/C++/DebugPanel/readme.md create mode 100644 ATC_Panel/C++/ExtendedDebugPanel/readme.md create mode 100644 ATC_Panel/C++/SimplePanel/readme.md create mode 100644 ATC_Panel/res/ATC1.wav create mode 100644 ATC_Panel/res/ATC2.wav create mode 100644 ATC_Panel/res/atcpanel2.png create mode 100644 ATC_Panel/res/cleanATC.png create mode 100644 ATC_Panel/res/down_arrow.png create mode 100644 ATC_Panel/res/f1.wav create mode 100644 ATC_Panel/res/f2.wav create mode 100644 ATC_Panel/res/temp.png create mode 100644 ATC_Panel/res/up_arrow.png delete mode 160000 Examples/C++/extern/RaylibAdditions create mode 160000 extern/RaylibAdditions rename {Examples/C++/extern => extern}/raylib (100%) diff --git a/.gitmodules b/.gitmodules index ede7762..eafe351 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ -[submodule "Examples/C++/extern/raylib"] - path = Examples/C++/extern/raylib - url = https://github.com/raysan5/raylib -[submodule "Examples/C++/extern/RaylibAdditions"] - path = Examples/C++/extern/RaylibAdditions - url = https://github.com/ShiralynDev/RaylibAdditions +[submodule "extern/raylib"] + path = extern/raylib + url = https://github.com/raysan5/raylib.git +[submodule "extern/RaylibAdditions"] + path = extern/RaylibAdditions + url = https://github.com/ShiralynDev/RaylibAdditions.git diff --git a/ATC_Panel/C++/DebugPanel/readme.md b/ATC_Panel/C++/DebugPanel/readme.md new file mode 100644 index 0000000..8cd272b --- /dev/null +++ b/ATC_Panel/C++/DebugPanel/readme.md @@ -0,0 +1,5 @@ +## About +This panel is made in C++ and shows the data sent from the ATC_Dator, this acts in listen mode, listen mode only displays data sent from server. + +## Type +read \ No newline at end of file diff --git a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt index 1219ffd..3db6acd 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt +++ b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt @@ -14,12 +14,26 @@ endif() set(BUILD_SHARED_LIBS ON) set(BUILD_EXAMPLES OFF) +# Raylib +set(SUPPORT_X11 ON CACHE BOOL "Use X11 for windowing" FORCE) +set(SUPPORT_WAYLAND OFF CACHE BOOL "Disable Wayland support" FORCE) # wayland may work good now but I did not when I made the cmake I copied this from +add_subdirectory( + ${CMAKE_CURRENT_LIST_DIR}/../../../extern/raylib + ${CMAKE_BINARY_DIR}/raylib +) +include_directories(../../../extern/raylib/) + +# RaylibAdditions +include_directories(../../../extern/RaylibAdditions) +file(GLOB RAYLIB_ADDITIONS_SOURCES ../../../extern/RaylibAdditions/*.cpp) + file(GLOB SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") # Create the executable add_executable(ATC_Panel_ExDebug ${SOURCES} ${RAYLIB_ADDITIONS_SOURCES}) +target_link_libraries(ATC_Panel_ExDebug PRIVATE raylib) # Apply Release mode specific settings if(CMAKE_BUILD_TYPE STREQUAL "Release") diff --git a/ATC_Panel/C++/ExtendedDebugPanel/build.sh b/ATC_Panel/C++/ExtendedDebugPanel/build.sh index a14bb36..051b9ab 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/build.sh +++ b/ATC_Panel/C++/ExtendedDebugPanel/build.sh @@ -5,5 +5,11 @@ BUILD_DIR=build mkdir -p "$BUILD_DIR" cd "$BUILD_DIR" -cmake .. -cmake --build . +if [ ! -f CMakeCache.txt ]; then + echo "Configuring project..." + cmake .. +else + echo "Build system already configured. Skipping cmake..." +fi + +cmake --build . --parallel \ No newline at end of file diff --git a/ATC_Panel/C++/ExtendedDebugPanel/readme.md b/ATC_Panel/C++/ExtendedDebugPanel/readme.md new file mode 100644 index 0000000..a3ac4d0 --- /dev/null +++ b/ATC_Panel/C++/ExtendedDebugPanel/readme.md @@ -0,0 +1,5 @@ +## About +This panel is made in C++ and shows the ATC panel with all interactive buttons, showing all data sent to/from the server aswell as allowing you to change stuff like speed, brake pressure and send balise information. This is only recommended to be used for debugging of the ATC_Dator, this will most likley interfere with the data of another client. + +## Type +read/write \ No newline at end of file diff --git a/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp index 55f5b30..028b7d2 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp +++ b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp @@ -1,5 +1,113 @@ #include +#include +#include +#include int main() { - std::cout << "Hello world\n"; + const std::string resPath = "../../res"; // should be ./ when built for "release" or packaged, also adjust for windows, also use filesystem path for ease of use + + RaylibAdditions::WindowClass window{"ATC_Panel_Extended_Debug", 1024, 500}; // read screen size from config later + + SetTargetFPS(60); + SetWindowMonitor(0); + SetExitKey(KEY_NULL); + + InitAudioDevice(); + Sound ATC1 = LoadSound((resPath + "/f1.wav").c_str()); // Better f1 tone // 1. f1 med 2,5 kHz ± 20 %. f1 aktiveras endast vid ATC-larm (verkligt eller simulerat) och är helt oberoende av om ATC-systemets matningsdon fungerar eller inte. Ljudstyrkan hos f1 kan inte regleras. + Sound ATC2 = LoadSound((resPath + "/f2.wav").c_str()); // f2 med 400 Hz ± 10 % fyrkantvåg. f2 är styrbar från datorerna under normal drift. Den aktiveras dessutom vid ATC-larm och är härvid oberoende av om ATC-systemets matningsdon fungerar eller inte. Ljudstyrkan är reglerbar med en potentiometer på panelen. + Texture2D ATCPanelTexture = LoadTexture((resPath + "/cleanATC.png").c_str()); + + Rectangle preInd = {61, 28, 59, 24}; + Rectangle mainInd = {234, 23, 75, 30}; + Rectangle startup = {0, float(ATCPanelTexture.height), 200, 50}; + RaylibAdditions::ButtonClass startupButton = {startup, "Start ATC", 20, GRAY, WHITE, WHITE, 5, 1}; + + Rectangle shunting = {17, 38, 18, 18}; + RaylibAdditions::ButtonClass shuntingButton = {shunting, "", 0, BLANK, BLANK, BLANK, 0, 1}; + Rectangle release = {333, 39, 18, 18}; + RaylibAdditions::ButtonClass releaseButton = {release, "", 0, BLANK, BLANK, BLANK, 0, 1}; + Rectangle increase = {384, 39, 18, 18}; + RaylibAdditions::ButtonClass increaseButton = {increase, "", 0, BLANK, BLANK, BLANK, 0, 1}; + Rectangle stopPassage = {484, 39, 18, 18}; + RaylibAdditions::ButtonClass stopPassageButton = {stopPassage, "", 0, BLANK, BLANK, BLANK, 0, 1}; + Rectangle dataEntry = {642, 40, 20, 20}; + RaylibAdditions::ButtonClass dataEntryButton = {dataEntry, "", 0, BLANK, BLANK, BLANK, 0, 1}; + + RaylibAdditions::SpeedometerClass speedometer = {{0, float(ATCPanelTexture.height), 300, 300}, 0, 200, 160, 380, 21, "km/h", WHITE, YELLOW}; + Rectangle speedButtonRect = {0, 300, 50, 50}; + RaylibAdditions::ButtonClass speedRemove = {speedButtonRect, "-10", 20, GRAY, WHITE, WHITE, 5, 1}; + speedButtonRect.x += 300 - 50; + RaylibAdditions::ButtonClass speedAdd = {speedButtonRect, "+10", 20, GRAY, WHITE, WHITE, 5, 1}; + Rectangle speedButtonRectSmall = {50, 300, 50, 50}; + RaylibAdditions::ButtonClass speedRemoveSmall = {speedButtonRectSmall, "-1", 20, GRAY, WHITE, WHITE, 5, 1}; + speedButtonRectSmall.x += 200 - 50; + RaylibAdditions::ButtonClass speedAddSmall = {speedButtonRectSmall, "+1", 20, GRAY, WHITE, WHITE, 5, 1}; + + RaylibAdditions::SpeedometerClass brakePressure = {{300, float(ATCPanelTexture.height), 300, 300}, 0, 10, 160, 380, 11, "kPa", WHITE, RED}; + Rectangle brakePressureButtonRect = {300, 300, 50, 50}; + RaylibAdditions::ButtonClass brakePressureRemove = {brakePressureButtonRect, "-0,5", 20, GRAY, WHITE, WHITE, 5, 1}; + brakePressureButtonRect.x += 300 - 50; + RaylibAdditions::ButtonClass brakePressureAdd = {brakePressureButtonRect, "+0,5", 20, GRAY, WHITE, WHITE, 5, 1}; + + std::vector> thumbWheels = { + {{691, 21}, 0}, // STH/V-MAX + {{712, 21}, 0}, + + {{752, 21}, 0}, // length (100m) + + {{795, 21}, 0}, // tillsättningstid / brake apply time + {{817, 21}, 0}, + + {{861, 21}, 0}, // redartationstalet / deacelerationnumber (converted by some formula, locos have a guide) (bromsprocent på 76 = 061) + {{882, 21}, 0}, + {{903, 21}, 0}, + + {{949, 21}, 0}, // procentuell överskridning / procentual override, X2000 has 30% due to boggies design and tilting + }; + + while(!WindowShouldClose()) { + //update + // this button code sucks, fix it + shuntingButton.updateState(); + releaseButton.updateState(); + increaseButton.updateState(); + stopPassageButton.updateState(); + dataEntryButton.updateState(); + speedRemove.updateState(); + speedRemoveSmall.updateState(); + speedAdd.updateState(); + speedAddSmall.updateState(); + brakePressureRemove.updateState(); + brakePressureAdd.updateState(); + + if (speedRemove.state == 2) + speedometer.value -= 10; + if (speedRemoveSmall.state == 2) + speedometer.value -= 1; + if (speedAdd.state == 2) + speedometer.value += 10; + if (speedAddSmall.state == 2) + speedometer.value += 1; + + if (brakePressureRemove.state == 2) + brakePressure.value -= 0.5; + if (brakePressureAdd.state == 2) + brakePressure.value += 0.5; + + // draw + BeginDrawing(); + ClearBackground(BLACK); + + DrawTexture(ATCPanelTexture, 0, 0, WHITE); + speedometer.drawSpeedometer(); + brakePressure.drawSpeedometer(); + speedRemove.draw(); + speedRemoveSmall.draw(); + speedAdd.draw(); + speedAddSmall.draw(); + brakePressureRemove.draw(); + brakePressureAdd.draw(); + + EndDrawing(); + } } \ No newline at end of file diff --git a/ATC_Panel/C++/SimplePanel/readme.md b/ATC_Panel/C++/SimplePanel/readme.md new file mode 100644 index 0000000..691b1fb --- /dev/null +++ b/ATC_Panel/C++/SimplePanel/readme.md @@ -0,0 +1,6 @@ +## About +This panel is made in C++ and shows the ATC panel with all interactive buttons, this can be switched between listen mode and interactive mode, interactive mode allows you do send data when pressing buttons whilst listen mode only displays data sent from server. + +## Type +read
+read/write \ No newline at end of file diff --git a/ATC_Panel/res/ATC1.wav b/ATC_Panel/res/ATC1.wav new file mode 100644 index 0000000000000000000000000000000000000000..553681a1fed12646a44b5d2659c938aba5a1bff0 GIT binary patch literal 96028 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 X@$L9_(MzH&*e2{B!Y*Mq|3Ci!)R!)& literal 0 HcmV?d00001 diff --git a/ATC_Panel/res/f2.wav b/ATC_Panel/res/f2.wav new file mode 100644 index 0000000000000000000000000000000000000000..c1a9e3ba636e1419ea3537434b4bd3baac46f964 GIT binary patch literal 76320 zcmeI*zf06{9LMpmS`J2Ka(JfaU1M5MQ{ZG`i4B1{Xw(ovwe$mmh9DhsXlQ5>8iJs$ zA%}jg;?mYER70m;-Y-2vv&;V|eoU-tZkiH!{-I-;_)aO`N@P z``(fEBuSc*=H$$)Bx!%$oa{;3lWSM+UES(ys(&-tGue|IX{@u5UC7>Sx!KZD>L?}o z#yfq#`hLx%W>Sr%_V?EewGFkEYNcA^sU`XG&GF5-{d4;p(Jg%_eQ17re!CIfrmNG{ z#n#2vMs!71jbpmmIHp^ywsA~5 z8^?6BaZEQG$8?L;HjZg$1N}YZZ?kT7OQO>)6T{*-E17w&Big^ zVzrH9+Sxd!n~h_-**KM zY#h_g#xdP&9MdgU+c>73jbpmmIHsG8W4gs^8^^S>aZEQG$8?Lv)nBdSyLIZ#pdA}W z6Z^Z@#xdP&9MjEv9MdgU+c>73jbpmmIHsHTIHp^ywsA~58^?6BaZESwaZI;ZZR41B zHje3LMY#h_g#xdQz$1&YvwT)xi**K<~jbpmmIHp^ywsA~58^?6B zaZEQG$8?L;HjZg$1N}YZZ?kT7OQO>)6T{*-E17w&Big^VzrH9 z+Sxd!n~h_-MdN($0MpLKG2Lt&)6K>)-E17wEmqq&rk#yry4g6Uo6jnlZn4_NG3{&| z)6K>)-E17wEmqq&rk#yry4g6Un~h_-#cCVJw6k$cHyg)v^Zz)eTdcNmOgkILbhB|x zH}7#ww^(iCn07Xf>1N}YZZ?kT7OQO>)6T{*-E17w&1aQNw^(iCn07Xf>1N}YZZ?kT z7OQO>)6T{*-E17w&1aQNw^(iCn07Xf>1N}YZZ?kT7OQO>)6T{*-E17w&1aQNw^(iC zn07Xf>1N}YZr)-TwE+?dEoKUvpn_PjgRl1G&E3$Lzc8SoUQ0 zL+`WRqrE>eQ<>A5`JVedweIKL`?}v8?mYaq>p<6w^j7C|=T_=|>U{HH^TY3j@29Ho ztDh@l)mxQMm9_F%Ymm1;=y93lqvO>`^y8Bfy!ugv^udi Sv37m^+WOtv-P(hVsf|DKR}|#{ literal 0 HcmV?d00001 diff --git a/ATC_Panel/res/temp.png b/ATC_Panel/res/temp.png new file mode 100644 index 0000000000000000000000000000000000000000..5b57fc753e5666840d6ec719b991088bc7256d90 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9F3${@^GvDCf{C@A6S v;usSI25S7-8TxH$-fsVRt7`zrJ3UhlM= zo^HqZO6u|Lv$hUeayRatn!0wX!p+=YyBL43J6`hO%UNluV0E6|TX|K1wlH|Q`njxg HN@xNA8Iv_O literal 0 HcmV?d00001 diff --git a/Examples/C++/extern/RaylibAdditions b/Examples/C++/extern/RaylibAdditions deleted file mode 160000 index 9d392f5..0000000 --- a/Examples/C++/extern/RaylibAdditions +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9d392f5cf71b79c76b82c317d503475e5e26e216 diff --git a/UniversalFunctions/networking/sockets/tcpSocket.hpp b/UniversalFunctions/networking/sockets/tcpSocket.hpp index e570958..b85de59 100644 --- a/UniversalFunctions/networking/sockets/tcpSocket.hpp +++ b/UniversalFunctions/networking/sockets/tcpSocket.hpp @@ -19,7 +19,6 @@ namespace Networking { int socketFd; public: TcpSocket(int SocketDomain = AF_INET, int SocketType = SOCK_STREAM | SOCK_NONBLOCK, int Protocol = 0); // AF_UNIX = local communication, allow other types later - TcpSocket(const TcpSocket&) = delete; int bind(); int connect(); }; diff --git a/extern/RaylibAdditions b/extern/RaylibAdditions new file mode 160000 index 0000000..d2f0381 --- /dev/null +++ b/extern/RaylibAdditions @@ -0,0 +1 @@ +Subproject commit d2f038164d2252c985d184e67e2970e4991128ab diff --git a/Examples/C++/extern/raylib b/extern/raylib similarity index 100% rename from Examples/C++/extern/raylib rename to extern/raylib From 7cde9136afda08ba5d5e36bed0337b0ec9b9341c Mon Sep 17 00:00:00 2001 From: ShiralynDev Date: Tue, 26 May 2026 18:58:50 +0200 Subject: [PATCH 5/9] Restruct and use sockets --- .gitignore | 4 +- .gitmodules | 3 + ATC/API_C_CPP/CMakeLists.txt | 43 --- ATC/API_C_CPP/include/ATC.h | 99 ------- ATC/API_C_CPP/src/ATC.c | 68 ----- ATC/API_C_CPP/src/ATCData.h | 5 - ATC/API_C_CPP/src/ATCDataInput.c | 34 --- ATC/API_C_CPP/src/ATCDataInput.h | 3 - ATC/API_C_CPP/src/ATCErrors.c | 89 ------ ATC/API_C_CPP/src/ATCErrors.h | 3 - ATC/API_C_CPP/src/ATCInternalFunctions.c | 42 --- ATC/API_C_CPP/src/ATCInternalFunctions.h | 4 - ATC/API_C_CPP/src/ATCStartup.c | 190 ------------- ATC/API_C_CPP/src/ATCStartup.h | 3 - ATC_Dator/CMakeLists.txt | 11 +- ATC_Dator/src/ATCData.hpp | 169 +++++++++++ ATC_Dator/src/ATCStartup/errors.cpp | 89 ++++++ ATC_Dator/src/ATCStartup/startup.cpp | 210 ++++++++++++++ ATC_Dator/src/ATCStartup/startup.hpp | 14 + ATC_Dator/src/Utils/utils.cpp | 41 +++ ATC_Dator/src/Utils/utils.hpp | 8 + ATC_Dator/src/main.cpp | 78 ++++- .../C++/ExtendedDebugPanel/CMakeLists.txt | 15 +- ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp | 97 ++++++- .../networking/networking.cpp | 24 ++ .../networking/networking.hpp | 13 + Examples/C++/CMakeLists.txt | 46 --- Examples/C++/res/ATC.gui | 31 -- Examples/C++/res/audio/ATC1.wav | Bin 96028 -> 0 bytes Examples/C++/res/audio/ATC2.wav | Bin 102616 -> 0 bytes Examples/C++/res/audio/f1.wav | Bin 56584 -> 0 bytes Examples/C++/res/audio/f2.wav | Bin 76320 -> 0 bytes Examples/C++/res/textures/atcpanel2.png | Bin 53866 -> 0 bytes Examples/C++/res/textures/cleanATC.png | Bin 30248 -> 0 bytes Examples/C++/res/textures/down_arrow.png | Bin 169 -> 0 bytes Examples/C++/res/textures/temp.png | Bin 102 -> 0 bytes Examples/C++/res/textures/up_arrow.png | Bin 160 -> 0 bytes Examples/C++/src/main.cpp | 267 ------------------ .../networking/sockets/tcpSocket.cpp | 17 -- .../networking/sockets/tcpSocket.hpp | 25 -- UniversalFunctions/readme.md | 4 - UniversalFunctions/utils.hpp | 10 - 42 files changed, 760 insertions(+), 999 deletions(-) delete mode 100644 ATC/API_C_CPP/CMakeLists.txt delete mode 100644 ATC/API_C_CPP/include/ATC.h delete mode 100644 ATC/API_C_CPP/src/ATC.c delete mode 100644 ATC/API_C_CPP/src/ATCData.h delete mode 100644 ATC/API_C_CPP/src/ATCDataInput.c delete mode 100644 ATC/API_C_CPP/src/ATCDataInput.h delete mode 100644 ATC/API_C_CPP/src/ATCErrors.c delete mode 100644 ATC/API_C_CPP/src/ATCErrors.h delete mode 100644 ATC/API_C_CPP/src/ATCInternalFunctions.c delete mode 100644 ATC/API_C_CPP/src/ATCInternalFunctions.h delete mode 100644 ATC/API_C_CPP/src/ATCStartup.c delete mode 100644 ATC/API_C_CPP/src/ATCStartup.h create mode 100644 ATC_Dator/src/ATCData.hpp create mode 100644 ATC_Dator/src/ATCStartup/errors.cpp create mode 100644 ATC_Dator/src/ATCStartup/startup.cpp create mode 100644 ATC_Dator/src/ATCStartup/startup.hpp create mode 100644 ATC_Dator/src/Utils/utils.cpp create mode 100644 ATC_Dator/src/Utils/utils.hpp create mode 100644 ATC_Panel/C++/UniversalFunctions/networking/networking.cpp create mode 100644 ATC_Panel/C++/UniversalFunctions/networking/networking.hpp delete mode 100644 Examples/C++/CMakeLists.txt delete mode 100644 Examples/C++/res/ATC.gui delete mode 100644 Examples/C++/res/audio/ATC1.wav delete mode 100644 Examples/C++/res/audio/ATC2.wav delete mode 100644 Examples/C++/res/audio/f1.wav delete mode 100644 Examples/C++/res/audio/f2.wav delete mode 100644 Examples/C++/res/textures/atcpanel2.png delete mode 100644 Examples/C++/res/textures/cleanATC.png delete mode 100644 Examples/C++/res/textures/down_arrow.png delete mode 100644 Examples/C++/res/textures/temp.png delete mode 100644 Examples/C++/res/textures/up_arrow.png delete mode 100644 Examples/C++/src/main.cpp delete mode 100644 UniversalFunctions/networking/sockets/tcpSocket.cpp delete mode 100644 UniversalFunctions/networking/sockets/tcpSocket.hpp delete mode 100644 UniversalFunctions/readme.md delete mode 100644 UniversalFunctions/utils.hpp diff --git a/.gitignore b/.gitignore index 887e293..961d158 100644 --- a/.gitignore +++ b/.gitignore @@ -363,4 +363,6 @@ MigrationBackup/ FodyWeavers.xsd build -.vscode \ No newline at end of file +.vscode +.clangd +.taskig \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index eafe351..2d57f82 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "extern/RaylibAdditions"] path = extern/RaylibAdditions url = https://github.com/ShiralynDev/RaylibAdditions.git +[submodule "extern/ShiraNet"] + path = extern/ShiraNet + url = https://github.com/ShiralynDev/ShiraNet diff --git a/ATC/API_C_CPP/CMakeLists.txt b/ATC/API_C_CPP/CMakeLists.txt deleted file mode 100644 index 512d3bb..0000000 --- a/ATC/API_C_CPP/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(ATCAPI) - -add_library(ATCAPI SHARED) - -target_sources(ATCAPI - PRIVATE - src/ATC.c - src/ATCStartup.c - src/ATCDataInput.c - src/ATCInternalFunctions.c -) - -target_include_directories(ATCAPI - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/src - PUBLIC - $ - $ -) - -if(DEFINED CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - message( - STATUS - "CMAKE_INSTALL_PREFIX is not set\n" - "Default value: ${CMAKE_INSTALL_PREFIX}\n" - "Will set it to ${CMAKE_SOURCE_DIR}/install" - ) - set(CMAKE_INSTALL_PREFIX - "${CMAKE_SOURCE_DIR}/install" - CACHE PATH "Where the library will be installed to" FORCE - ) -else() - message( - STATUS - "CMAKE_INSTALL_PREFIX was already set\n" - "Current value: ${CMAKE_INSTALL_PREFIX}" - ) -endif() - -set(public_headers - include/ATC.h -) \ No newline at end of file diff --git a/ATC/API_C_CPP/include/ATC.h b/ATC/API_C_CPP/include/ATC.h deleted file mode 100644 index 96a6a0b..0000000 --- a/ATC/API_C_CPP/include/ATC.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/* -#define växling shunting -#define förIndikator preIndicator -#define balis balise -#define bromsverksomkopplare brakeSystemSwitch -#define stoppassage dangerPass -#define STH Vmax //Största Tillåtna Hastighet -#define retardationstal redardationRate -#define Överskridande exceedance -#define lossningsKnapp releaseButton -Ignore for now, might be added back later -*/ - -// "Translating" The Swedish railway terms to the general English railway terms to make it work with both -// Also this is a programming warcrime I believe - -/* -Plan: -Use a "callback" function to run everything -Allow using functions to set ATC aswell as allowing passing it trough the runCallbacks function, data should be null-able in the callbacks function incase... -the developer want to set the data in their functions for pressing a button ect -*/ - -struct internalATCData { - int startup; // 0 = off, 1 = startup, 2 = running/data input, 3 = running, data inputed - int ms; - bool dataEntryButtonPressed; - bool ABBVersion; // SRT/ATSS/Ansaldo on false, ABB on true - bool achived; // Used as a general varible to save data - bool achived1; // Used as a general varible to save data - bool achived2; // Used as a general varible to save data - bool failed; - int vmax; // in km/h - int length; // in x * 10²m 100m = 1, 900m = 9; -}; - -struct ATCData { - int currentSpeed; - - bool shuntingButton; - bool releaseButton; - bool increaseButton; - bool stopPassageButton; - bool dataEntryButton; - - float brakePressure; - - int STHDial1; // *2 of pos for simulation of positions between for error; - int STHDial2; // *2 of pos for simulation of positions between for error; - int lengthDial; // *2 of pos for simulation of positions between for error; - int applyTimeDial1; // *2 of pos for simulation of positions between for error; - int applyTimeDial2; // *2 of pos for simulation of positions between for error; - int retardationDial1; // *2 of pos for simulation of positions between for error; - int retardationDial2; // *2 of pos for simulation of positions between for error; - int retardationDial3; // *2 of pos for simulation of positions between for error; - int overrideDial; // *2 of pos for simulation of positions between for error; -}; - -struct ATCReturnData { - int ATCStatus; // 0 = off, 1 = on - bool toneF1; - bool toneF2; - bool shuntingLamp; - char preIndicator0; - char preIndicator1; - char preIndicator2; - bool ATCError; - bool BaliseError; - bool speeding; - char mainIndicator0; - char mainIndicator1; - char mainIndicator2; - bool releaseLamp; - bool increaseLamp; - bool dataEntryLamp; - bool smallError; - float requestedBrakePressure; -}; - -int thisReturnsOne(); -long long getCurrentTimeMS(); - -void initATC(); -void setATCData(struct ATCData data); // Updates the ATC's data with the inputed data, will not update to null values -struct ATCReturnData runATC(struct ATCData data); // The function to process ATC data (preferably ran on another thread) -void toggleATC(int on); // Toggle startup, 1 = startup/started, 0 = off/turn off, 2 = skip startup/started -void toggleSystemType(bool useABB); // true = use ABB, false = use SRT/ATSS/Ansaldo -bool getSystemType(); - -#ifdef __cplusplus -} -#endif diff --git a/ATC/API_C_CPP/src/ATC.c b/ATC/API_C_CPP/src/ATC.c deleted file mode 100644 index f782f26..0000000 --- a/ATC/API_C_CPP/src/ATC.c +++ /dev/null @@ -1,68 +0,0 @@ -#ifdef _WIN32 -#define ATC_API __declspec(dllexport) -#else -#define ATC_API __attribute__((visibility("default"))) -#endif -#include -#include -#include "ATCData.h" -#include "ATCStartup.h" -#include "ATCDataInput.h" - -// https://bransch.trafikverket.se/contentassets/438381cb6c794b85a28d090b0c280b70/handbok--trvinfra-90001-v1_0.pdf - -struct internalATCData internalData = { 0 }; -struct ATCData ATC = { 0 }; -struct ATCReturnData ATCReturn = { 0 }; - -long long getCurrentTimeMS() { - struct timespec ts; - timespec_get(&ts, TIME_UTC); - return (long long)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; -} - -int thisReturnsOne() { - return 1; -} - -void initATC() { // Run this before using the ATC - internalData.ABBVersion = false; - internalData.achived2 = false; - internalData.achived1 = false; - internalData.achived = false; - internalData.dataEntryButtonPressed = false; - internalData.ms = 0; - internalData.startup = 0; -} - -void setATCData(struct ATCData data) { - ATC = data; -} - -struct ATCReturnData runATC(struct ATCData data) { - setATCData(data); - if (internalData.startup == 0) { // This gets skipped when started cus internalData.startup == 2 at that point - ATCReturn.ATCStatus = 0; - return ATCReturn; - } - - if (internalData.startup == 1) - startupSequence(); - if (internalData.startup == 2) - dataInputSequence(); - - return ATCReturn; -} - -void toggleATC(int on) { - if (on >= 0 && on <= 2) - internalData.startup = on; -} - -void toggleSystemType(bool useABB) { - internalData.ABBVersion = useABB; -} - -bool getSystemType() { - return internalData.ABBVersion; -} \ No newline at end of file diff --git a/ATC/API_C_CPP/src/ATCData.h b/ATC/API_C_CPP/src/ATCData.h deleted file mode 100644 index 7f99af3..0000000 --- a/ATC/API_C_CPP/src/ATCData.h +++ /dev/null @@ -1,5 +0,0 @@ -#include "ATC.h" - -extern struct internalATCData internalData; -extern struct ATCData ATC; -extern struct ATCReturnData ATCReturn; \ No newline at end of file diff --git a/ATC/API_C_CPP/src/ATCDataInput.c b/ATC/API_C_CPP/src/ATCDataInput.c deleted file mode 100644 index 98a8a4c..0000000 --- a/ATC/API_C_CPP/src/ATCDataInput.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "ATCDataInput.h" -#include "ATCData.h" -#include "ATCInternalFunctions.h" - -void dataInputSequence() { - int ms = getCurrentTimeMS(); - if (internalData.ms == 0) { - internalData.ms = ms; - ATCReturn.increaseLamp = false; - ATCReturn.dataEntryLamp = false; - internalData.dataEntryButtonPressed = false; - } - - if (ms - internalData.ms >= 500) { - ATCReturn.increaseLamp = !ATCReturn.increaseLamp; - ATCReturn.dataEntryLamp = !ATCReturn.dataEntryLamp; - internalData.ms = ms; - } - - if (ATC.dataEntryButton) { - internalData.dataEntryButtonPressed = true; - turnOnAll(); - ATCReturn.ATCError = false; - ATCReturn.toneF1 = false; - } - if (!ATC.dataEntryButton && internalData.dataEntryButtonPressed) { - turnOffAll(); - internalData.ms = 0; - internalData.dataEntryButtonPressed = false; - internalData.startup = 3; - } - - return; -} \ No newline at end of file diff --git a/ATC/API_C_CPP/src/ATCDataInput.h b/ATC/API_C_CPP/src/ATCDataInput.h deleted file mode 100644 index 9c02d80..0000000 --- a/ATC/API_C_CPP/src/ATCDataInput.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void dataInputSequence(); \ No newline at end of file diff --git a/ATC/API_C_CPP/src/ATCErrors.c b/ATC/API_C_CPP/src/ATCErrors.c deleted file mode 100644 index 44d84a9..0000000 --- a/ATC/API_C_CPP/src/ATCErrors.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "ATCErrors.h" -#include "ATCData.h" - -void startupErrors() { - if (ATC.STHDial2 % 2) { // move to error check function or something // only in phase 0 of startup? - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '1'; - ATCReturn.preIndicator2 = '1'; - } - if (ATC.STHDial1 % 2) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '1'; - ATCReturn.preIndicator2 = '2'; - } - if (ATC.lengthDial % 2) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '1'; - ATCReturn.preIndicator2 = '3'; - } - if (ATC.retardationDial3 % 2) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '1'; - ATCReturn.preIndicator2 = '4'; - } - if (ATC.retardationDial2 % 2) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '1'; - ATCReturn.preIndicator2 = '5'; - } - if (ATC.retardationDial1 % 2) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '1'; - ATCReturn.preIndicator2 = '6'; - } - if (ATC.applyTimeDial2 % 2) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '1'; - ATCReturn.preIndicator2 = '7'; - } - if (ATC.applyTimeDial1 % 2) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '1'; - ATCReturn.preIndicator2 = '8'; - } - if (ATC.overrideDial % 2) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '1'; - ATCReturn.preIndicator2 = '9'; - } - if (ATC.stopPassageButton) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '3'; - ATCReturn.preIndicator2 = '2'; - } - if (ATC.dataEntryButton) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '4'; - ATCReturn.preIndicator2 = '1'; - } - if (ATC.shuntingButton) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '4'; - ATCReturn.preIndicator2 = '2'; - } - if (ATC.increaseButton) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '4'; - ATCReturn.preIndicator2 = '3'; - } - if (ATC.releaseButton) { - internalData.failed = true; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.preIndicator1 = '4'; - ATCReturn.preIndicator2 = '4'; - } -} \ No newline at end of file diff --git a/ATC/API_C_CPP/src/ATCErrors.h b/ATC/API_C_CPP/src/ATCErrors.h deleted file mode 100644 index f60bf2c..0000000 --- a/ATC/API_C_CPP/src/ATCErrors.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void startupErrors(); \ No newline at end of file diff --git a/ATC/API_C_CPP/src/ATCInternalFunctions.c b/ATC/API_C_CPP/src/ATCInternalFunctions.c deleted file mode 100644 index 1e090a3..0000000 --- a/ATC/API_C_CPP/src/ATCInternalFunctions.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "ATCInternalFunctions.h" -#include "ATCData.h" - -void turnOffAll() { - ATCReturn.ATCError = false; - ATCReturn.toneF1 = false; - ATCReturn.toneF2 = false; - ATCReturn.shuntingLamp = false; - ATCReturn.preIndicator0 = ' '; - ATCReturn.preIndicator1 = ' '; - ATCReturn.preIndicator2 = ' '; - ATCReturn.ATCError = false; - ATCReturn.BaliseError = false; - ATCReturn.speeding = false; - ATCReturn.mainIndicator0 = ' '; - ATCReturn.mainIndicator1 = ' '; - ATCReturn.mainIndicator2 = ' '; - ATCReturn.releaseLamp = false; - ATCReturn.increaseLamp = false; - ATCReturn.dataEntryLamp = false; - ATCReturn.smallError = false; -} - -void turnOnAll() { - ATCReturn.ATCError = true; - ATCReturn.toneF1 = true; - ATCReturn.toneF2 = true; - ATCReturn.shuntingLamp = true; - ATCReturn.preIndicator0 = '8'; - ATCReturn.preIndicator1 = '8'; - ATCReturn.preIndicator2 = '8'; - ATCReturn.ATCError = true; - ATCReturn.BaliseError = true; - ATCReturn.speeding = true; - ATCReturn.mainIndicator0 = '8'; - ATCReturn.mainIndicator1 = '8'; - ATCReturn.mainIndicator2 = '8'; - ATCReturn.releaseLamp = true; - ATCReturn.increaseLamp = true; - ATCReturn.dataEntryLamp = true; - ATCReturn.smallError = true; -} \ No newline at end of file diff --git a/ATC/API_C_CPP/src/ATCInternalFunctions.h b/ATC/API_C_CPP/src/ATCInternalFunctions.h deleted file mode 100644 index c5e1a5d..0000000 --- a/ATC/API_C_CPP/src/ATCInternalFunctions.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -void turnOffAll(); -void turnOnAll(); \ No newline at end of file diff --git a/ATC/API_C_CPP/src/ATCStartup.c b/ATC/API_C_CPP/src/ATCStartup.c deleted file mode 100644 index fbf6119..0000000 --- a/ATC/API_C_CPP/src/ATCStartup.c +++ /dev/null @@ -1,190 +0,0 @@ -#include "ATCStartup.h" -#include "ATCData.h" -#include -#include -#include "ATCInternalFunctions.h" -#include "ATCErrors.h" - -bool floatCompare(float a, float b) { - return fabsf(a - b) < 0.1; -} - -void startupSequence() { // Rewrite for better "stages" system and better times aswell as use the brake during startup - // https://bransch.trafikverket.se/contentassets/438381cb6c794b85a28d090b0c280b70/handbok--trvinfra-90001-v1_0.pdf // Page 18 for error codes - /* - To be added: - Preind 01 MainInd 0 2 cabs activated - Preind 02 MainInd 0 No contact with the panel - Preind 03 MainInd 0 No contact with the "manöverenheten" - - // translate - 1 Hastighetsmätarkonstanter - 2 Hastighetsmätaringångar - 02 2 Lokanpassningsfel - 3 Transmissionstest (Transmission = sändare/mottagare + antenn) - 02 3 Fel i antenn / kabel / transmissionskassett. - 06 3 Balisupptäckt med sändaren frånslagen - - 4 Bromstryck m.m. - 01 4 Tryckgivarfel - 02 4 Tryckgivarfel - 03 4 Systembroms obehörigt aktiv - 04 4 Nödbromsreläkontakt obehörigt öppen - 05 4 Huvudledningstrycket < 4,0 bar - 06 4 Huvudledningstrycket > 5,5 bar - 07 4 Huvudledningstrycket har ej stabiliserats (får variera högst 0,2 bar på 3 sekunder) - - 6 Systemnödbromsning - 01 6 Någon reläkontakt öppnar ej - 07 6 Trycksänkning på 0,6 bar har ej uppmätts inom 0,5 sekunder efter prov av systemnödbroms - - Alredy added: - 5 Systembromsning - 01 5 Trycksänkningen < 0,25 bar - 06 5 Efter lossning har trycket ej stigit minst 0,12 bar - - 11 0 "thumb wheel" Vmax, right, wrong/wrongly - 12 0 "thumb wheel" Vmax, left, wrong/wrongly - 13 0 "thumb wheel" train length, wrong/wrongly - 14 0 Tumhjul Retardation, höger felaktigt - 15 0 Tumhjul Retardation, mitten felaktigt - 16 0 Tumhjul Retardation, vänster felaktigt - 17 0 Tumhjul Bromstillsättningstid, höger felaktigt - 18 0 Tumhjul Bromstillsättningstid, vänster - 32 0 Button Stop passage pressed - 41 0 Button Input pressed - 42 0 Button Shunting pressed - 43 0 Button Increase pressed - 44 0 Button Release pressed - */ - - ATCReturn.ATCStatus = 1; - - int startupTime = 0; - int ms = getCurrentTimeMS(); - if (internalData.ms == 0) { - internalData.ms = ms; - } - if (startupTime == 0) { - if (internalData.ABBVersion) startupTime = 5000; - if (!internalData.ABBVersion) startupTime = 8000; - } - - if (ms - internalData.ms <= 100) { - turnOnAll(); - ATCReturn.toneF1 = false; - ATCReturn.toneF2 = false; - return; - } - turnOffAll(); - - if (ms - internalData.ms <= 300) return; - - if (ms - internalData.ms <= 500) { - ATCReturn.ATCError = true; - ATCReturn.toneF1 = true; - return; - } - ATCReturn.ATCError = false; - ATCReturn.toneF1 = false; - - if (internalData.ABBVersion) { - ATCReturn.mainIndicator0 = '4'; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.mainIndicator2 = '1'; - - if (ms - internalData.ms >= 700) { - ATCReturn.mainIndicator0 = '4'; - ATCReturn.mainIndicator1 = '0'; - ATCReturn.mainIndicator2 = '0'; - } - - if (ms - internalData.ms >= 3000) { - ATCReturn.mainIndicator0 = '4'; - ATCReturn.mainIndicator1 = '1'; - ATCReturn.mainIndicator2 = '0'; - } - - if (ms - internalData.ms >= 4000) { - ATCReturn.mainIndicator0 = '4'; - ATCReturn.mainIndicator1 = '1'; - ATCReturn.mainIndicator2 = '1'; - } - } else { - ATCReturn.mainIndicator1 = '0'; - - if (ms - internalData.ms >= 1000) ATCReturn.mainIndicator1 = '1'; - if (ms - internalData.ms >= 1500) ATCReturn.mainIndicator1 = '2'; - if (ms - internalData.ms >= 1600) ATCReturn.mainIndicator1 = '3'; - if (ms - internalData.ms >= 2300) ATCReturn.mainIndicator1 = '4'; - if (ms - internalData.ms >= 3000) ATCReturn.mainIndicator1 = '5'; - - if (ms - internalData.ms >= 1000) // phase 1 - startupErrors(); - - if (!internalData.achived) - ATCReturn.requestedBrakePressure = 5.0f; - - if (floatCompare(ATC.brakePressure, 5.0f) && !internalData.achived && ms - internalData.ms >= 3000) { - ATCReturn.requestedBrakePressure = 4.0f; - internalData.achived = true; - } - - if (internalData.achived && floatCompare(ATC.brakePressure, 4.0f) && !internalData.achived1) { - internalData.achived1 = true; - ATCReturn.requestedBrakePressure = 5.0f; - } - - if (internalData.achived1 && floatCompare(ATC.brakePressure, 5.0f) && !internalData.achived2) - internalData.achived2 = true; - - if (ms - internalData.ms >= 7000 && !internalData.achived2) { // startup failed - internalData.failed = true; - if (ATC.brakePressure < 4.12f) { // Failed to increase pressure by 0.12 bar, error code 06 5 - ATCReturn.preIndicator1 = '0'; - ATCReturn.preIndicator2 = '6'; - } - if (ATC.brakePressure > 4.75f) { // Failed to lower pressure by 0.25 or more bar, error code 01 5 - ATCReturn.preIndicator1 = '0'; - ATCReturn.preIndicator2 = '1'; - } - } - - if (ms - internalData.ms >= 7000 && internalData.achived2) { // no fail - ATCReturn.mainIndicator1 = '6'; - ATCReturn.requestedBrakePressure = 0.0f; - } - - if (internalData.failed) { - ATCReturn.ATCStatus = 0; - internalData.startup = 0; - internalData.ms = 0; - internalData.dataEntryButtonPressed = false; - internalData.failed = false; - } - } - - if (ms - internalData.ms >= startupTime) { - ATCReturn.mainIndicator0 = ' '; - ATCReturn.mainIndicator1 = ' '; - ATCReturn.mainIndicator2 = ' '; - ATCReturn.ATCError = true; - ATCReturn.toneF1 = true; - ATCReturn.toneF2 = true; - if (ATC.dataEntryButton) { - internalData.dataEntryButtonPressed = true; - turnOnAll(); - ATCReturn.ATCError = false; - ATCReturn.toneF1 = false; - } - if (!ATC.dataEntryButton && internalData.dataEntryButtonPressed) { - turnOffAll(); - internalData.startup = 2; - internalData.ms = 0; - internalData.dataEntryButtonPressed = false; - internalData.achived = false; - internalData.achived1 = false; - internalData.achived2 = false; - } - } -} \ No newline at end of file diff --git a/ATC/API_C_CPP/src/ATCStartup.h b/ATC/API_C_CPP/src/ATCStartup.h deleted file mode 100644 index f729a51..0000000 --- a/ATC/API_C_CPP/src/ATCStartup.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void startupSequence(); \ No newline at end of file diff --git a/ATC_Dator/CMakeLists.txt b/ATC_Dator/CMakeLists.txt index b9973cd..bbe3b53 100644 --- a/ATC_Dator/CMakeLists.txt +++ b/ATC_Dator/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.20) - +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build) project(ATC_Dator) @@ -14,13 +14,20 @@ endif() set(BUILD_SHARED_LIBS ON) set(BUILD_EXAMPLES OFF) -file(GLOB SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) +add_subdirectory( + ${CMAKE_CURRENT_LIST_DIR}/../extern/ShiraNet + ${CMAKE_BINARY_DIR}/ShiraNet +) +include_directories(../extern/ShiraNet/include) + +file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) file(GLOB_RECURSE UniversalFunctionsSources ${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/*.cpp) set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") # Create the executable add_executable(ATC_Dator ${SOURCES} ${UniversalFunctionsSources}) +target_link_libraries(ATC_Dator PRIVATE ShiraNet) target_include_directories(ATC_Dator PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions diff --git a/ATC_Dator/src/ATCData.hpp b/ATC_Dator/src/ATCData.hpp new file mode 100644 index 0000000..8e24d14 --- /dev/null +++ b/ATC_Dator/src/ATCData.hpp @@ -0,0 +1,169 @@ +#pragma once + +#include + +struct internalATCData { + int startup = 0; // 0 = off, 1 = startup, 2 = running/data input, 3 = running, data inputed + bool dataEntryButtonPressed = false; + bool ABBVersion = false; // SRT/ATSS/Ansaldo on false, ABB on true + bool achived = false; // Used as a general varible to save data + bool achived1 = false; // Used as a general varible to save data + bool achived2 = false; // Used as a general varible to save data + bool failed = false; + int vmax = 0; // in km/h + int length = 0; // in x * 10²m 100m = 1, 900m = 9; + + void serialize(std::ostream& out) const { + out << startup << ' ' + << dataEntryButtonPressed << ' ' + << ABBVersion << ' ' + << achived << ' ' + << achived1 << ' ' + << achived2 << ' ' + << failed << ' ' + << vmax << ' ' + << length << ' '; + } + + void deserialize(std::istream& in) { + in >> startup + >> dataEntryButtonPressed + >> ABBVersion + >> achived + >> achived1 + >> achived2 + >> failed + >> vmax + >> length; + } +}; + +struct ATCData { + int currentSpeed = 0; + + bool shuntingButton = 0; + bool releaseButton = 0; + bool increaseButton = 0; + bool stopPassageButton = 0; + bool dataEntryButton = 0; + + float brakePressure = 0.0f; + + float STHDial1 = 0; + float STHDial2 = 0; + float lengthDial = 0; + float applyTimeDial1 = 0; + float applyTimeDial2 = 0; + float retardationDial1 = 0; + float retardationDial2 = 0; + float retardationDial3 = 0; + float overrideDial = 0; + + void serialize(std::ostream& out) const { + out << currentSpeed << ' ' + << shuntingButton << ' ' + << releaseButton << ' ' + << increaseButton << ' ' + << stopPassageButton << ' ' + << dataEntryButton << ' ' + << brakePressure << ' ' + << STHDial1 << ' ' + << STHDial2 << ' ' + << lengthDial << ' ' + << applyTimeDial1 << ' ' + << applyTimeDial2 << ' ' + << retardationDial1 << ' ' + << retardationDial2 << ' ' + << retardationDial3 << ' ' + << overrideDial << ' '; + } + + void deserialize(std::istream& in) { + in >> currentSpeed + >> shuntingButton + >> releaseButton + >> increaseButton + >> stopPassageButton + >> dataEntryButton + >> brakePressure + >> STHDial1 + >> STHDial2 + >> lengthDial + >> applyTimeDial1 + >> applyTimeDial2 + >> retardationDial1 + >> retardationDial2 + >> retardationDial3 + >> overrideDial; + } +}; + +struct ATCReturnData { + int ATCStatus = 0; // 0 = off, 1 = on + bool toneF1 = 0; + bool toneF2 = 0; + bool shuntingLamp = 0; + char preIndicator0 = ' '; + char preIndicator1 = ' '; + char preIndicator2 = ' '; + bool ATCError = 0; + bool BaliseError = 0; + bool speeding = 0; + char mainIndicator0 = ' '; + char mainIndicator1 = ' '; + char mainIndicator2 = ' '; + bool releaseLamp = 0; + bool increaseLamp = 0; + bool dataEntryLamp = 0; + bool smallError = 0; + float requestedBrakePressure = 0.0f; + + void serialize(std::ostream& out) const { + out << ATCStatus << ' ' + << toneF1 << ' ' + << toneF2 << ' ' + << shuntingLamp << ' ' + << (int)preIndicator0 << ' ' + << (int)preIndicator1 << ' ' + << (int)preIndicator2 << ' ' + << ATCError << ' ' + << BaliseError << ' ' + << speeding << ' ' + << (int)mainIndicator0 << ' ' + << (int)mainIndicator1 << ' ' + << (int)mainIndicator2 << ' ' + << releaseLamp << ' ' + << increaseLamp << ' ' + << dataEntryLamp << ' ' + << smallError << ' ' + << requestedBrakePressure << ' '; + } + + void deserialize(std::istream& in) { + int p0, p1, p2, m0, m1, m2; + in >> ATCStatus + >> toneF1 + >> toneF2 + >> shuntingLamp + >> p0 + >> p1 + >> p2 + >> ATCError + >> BaliseError + >> speeding + >> m0 + >> m1 + >> m2 + >> releaseLamp + >> increaseLamp + >> dataEntryLamp + >> smallError + >> requestedBrakePressure; + preIndicator0 = (char)p0; + preIndicator1 = (char)p1; + preIndicator2 = (char)p2; + mainIndicator0 = (char)m0; + mainIndicator1 = (char)m1; + mainIndicator2 = (char)m2; + } +}; \ No newline at end of file diff --git a/ATC_Dator/src/ATCStartup/errors.cpp b/ATC_Dator/src/ATCStartup/errors.cpp new file mode 100644 index 0000000..9ce52e9 --- /dev/null +++ b/ATC_Dator/src/ATCStartup/errors.cpp @@ -0,0 +1,89 @@ +#include "startup.hpp" +#include + +void ATC::Startup::errors(ATCData &data, internalATCData &internalData, ATCReturnData &returnData) { + if (std::trunc(data.STHDial2) != data.STHDial2) { // move to error check function or something // only in phase 0 of startup? + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '1'; + returnData.preIndicator2 = '1'; + } + if (std::trunc(data.STHDial1) != data.STHDial1) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '1'; + returnData.preIndicator2 = '2'; + } + if (std::trunc(data.lengthDial) != data.lengthDial) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '1'; + returnData.preIndicator2 = '3'; + } + if (std::trunc(data.retardationDial3) != data.retardationDial3) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '1'; + returnData.preIndicator2 = '4'; + } + if (std::trunc(data.retardationDial2) != data.retardationDial2) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '1'; + returnData.preIndicator2 = '5'; + } + if (std::trunc(data.retardationDial1) != data.retardationDial1) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '1'; + returnData.preIndicator2 = '6'; + } + if (std::trunc(data.applyTimeDial2) != data.applyTimeDial2) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '1'; + returnData.preIndicator2 = '7'; + } + if (std::trunc(data.applyTimeDial1) != data.applyTimeDial1) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '1'; + returnData.preIndicator2 = '8'; + } + if (std::trunc(data.overrideDial) != data.overrideDial) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '1'; + returnData.preIndicator2 = '9'; + } + if (data.stopPassageButton) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '3'; + returnData.preIndicator2 = '2'; + } + if (data.dataEntryButton) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '4'; + returnData.preIndicator2 = '1'; + } + if (data.shuntingButton) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '4'; + returnData.preIndicator2 = '2'; + } + if (data.increaseButton) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '4'; + returnData.preIndicator2 = '3'; + } + if (data.releaseButton) { + internalData.failed = true; + returnData.mainIndicator1 = '0'; + returnData.preIndicator1 = '4'; + returnData.preIndicator2 = '4'; + } +} \ No newline at end of file diff --git a/ATC_Dator/src/ATCStartup/startup.cpp b/ATC_Dator/src/ATCStartup/startup.cpp new file mode 100644 index 0000000..c67f924 --- /dev/null +++ b/ATC_Dator/src/ATCStartup/startup.cpp @@ -0,0 +1,210 @@ +#include "startup.hpp" +#include "../ATCData.hpp" +#include "../Utils/utils.hpp" + +#include + +int ATC::Startup::ms = 0; + +bool floatCompare(float a, float b) { + if (a - b > 0.01 || a - b > -0.01) + return true; + return false; +} + +void ATC::startupSequence(ATCData &data, internalATCData &internalData, ATCReturnData &returnData) { // Rewrite for better "stages" system and better times aswell as use the brake during startup + // https://bransch.trafikverket.se/contentassets/438381cb6c794b85a28d090b0c280b70/handbok--trvinfra-90001-v1_0.pdf // Page 18 for error codes + /* + To be added: + Preind 01 MainInd 0 2 cabs activated + Preind 02 MainInd 0 No contact with the panel + Preind 03 MainInd 0 No contact with the "manöverenheten" + + // translate + 1 Hastighetsmätarkonstanter + 2 Hastighetsmätaringångar + 02 2 Lokanpassningsfel + 3 Transmissionstest (Transmission = sändare/mottagare + antenn) + 02 3 Fel i antenn / kabel / transmissionskassett. + 06 3 Balisupptäckt med sändaren frånslagen + + 4 Bromstryck m.m. + 01 4 Tryckgivarfel + 02 4 Tryckgivarfel + 03 4 Systembroms obehörigt aktiv + 04 4 Nödbromsreläkontakt obehörigt öppen + 05 4 Huvudledningstrycket < 4,0 bar + 06 4 Huvudledningstrycket > 5,5 bar + 07 4 Huvudledningstrycket har ej stabiliserats (får variera högst 0,2 bar på 3 sekunder) + + 6 Systemnödbromsning + 01 6 Någon reläkontakt öppnar ej + 07 6 Trycksänkning på 0,6 bar har ej uppmätts inom 0,5 sekunder efter prov av systemnödbroms + + Alredy added: + 5 Systembromsning + 01 5 Trycksänkningen < 0,25 bar + 06 5 Efter lossning har trycket ej stigit minst 0,12 bar + + 11 0 "thumb wheel" Vmax, right, wrong/wrongly + 12 0 "thumb wheel" Vmax, left, wrong/wrongly + 13 0 "thumb wheel" train length, wrong/wrongly + 14 0 Tumhjul Retardation, höger felaktigt + 15 0 Tumhjul Retardation, mitten felaktigt + 16 0 Tumhjul Retardation, vänster felaktigt + 17 0 Tumhjul Bromstillsättningstid, höger felaktigt + 18 0 Tumhjul Bromstillsättningstid, vänster + 32 0 Button Stop passage pressed + 41 0 Button Input pressed + 42 0 Button Shunting pressed + 43 0 Button Increase pressed + 44 0 Button Release pressed + */ + + returnData.ATCStatus = 1; + + // I hate this timebased system + int startupTime = 0; + auto now = std::chrono::system_clock::now(); + auto duration = now.time_since_epoch(); + int ms = std::chrono::duration_cast(duration).count(); + if (ATC::Startup::ms == 0) { + internalData.startup = 1; + ATC::Startup::ms = ms; + } + + if (startupTime == 0) { + if (internalData.ABBVersion) + startupTime = 5000; + if (!internalData.ABBVersion) + startupTime = 8000; + } + + if (ms - ATC::Startup::ms <= 100) { + ATC::turnOnAll(returnData); + returnData.toneF1 = false; + returnData.toneF2 = false; + return; + } + + if (ms - ATC::Startup::ms <= 120) { + ATC::turnOffAll(returnData); + return; + } + + if (ms - ATC::Startup::ms <= 300) + return; + + if (ms - ATC::Startup::ms <= 500) { + returnData.ATCError = true; + returnData.toneF1 = true; + return; + } + returnData.ATCError = false; + returnData.toneF1 = false; + + if (internalData.ABBVersion) { + returnData.mainIndicator0 = '4'; + returnData.mainIndicator1 = '0'; + returnData.mainIndicator2 = '1'; + + if (ms - ATC::Startup::ms >= 700) { + returnData.mainIndicator0 = '4'; + returnData.mainIndicator1 = '0'; + returnData.mainIndicator2 = '0'; + } + + if (ms - ATC::Startup::ms >= 3000) { + returnData.mainIndicator0 = '4'; + returnData.mainIndicator1 = '1'; + returnData.mainIndicator2 = '0'; + } + + if (ms - ATC::Startup::ms >= 4000) { + returnData.mainIndicator0 = '4'; + returnData.mainIndicator1 = '1'; + returnData.mainIndicator2 = '1'; + } + } else { + returnData.mainIndicator1 = '0'; + + if (ms - ATC::Startup::ms >= 1000) + returnData.mainIndicator1 = '1'; + if (ms - ATC::Startup::ms >= 1500) + returnData.mainIndicator1 = '2'; + if (ms - ATC::Startup::ms >= 1600) + returnData.mainIndicator1 = '3'; + if (ms - ATC::Startup::ms >= 2300) + returnData.mainIndicator1 = '4'; + if (ms - ATC::Startup::ms >= 3000) + returnData.mainIndicator1 = '5'; + + if (ms - ATC::Startup::ms >= 1000) // phase 1 + ATC::Startup::errors(data, internalData, returnData); + + if (!internalData.achived) + returnData.requestedBrakePressure = 5.0f; + + if (floatCompare(data.brakePressure, 5.0f) && !internalData.achived && ms - ATC::Startup::ms >= 3000) { + returnData.requestedBrakePressure = 4.0f; + internalData.achived = true; + } + + if (internalData.achived && floatCompare(data.brakePressure, 4.0f) && !internalData.achived1) { + internalData.achived1 = true; + returnData.requestedBrakePressure = 5.0f; + } + + if (internalData.achived1 && floatCompare(data.brakePressure, 5.0f) && !internalData.achived2) + internalData.achived2 = true; + + if (ms - ATC::Startup::ms >= 7000 && !internalData.achived2) { // startup failed + internalData.failed = true; + if (data.brakePressure < 4.12f) { // Failed to increase pressure by 0.12 bar, error code 06 5 + returnData.preIndicator1 = '0'; + returnData.preIndicator2 = '6'; + } + if (data.brakePressure > 4.75f) { // Failed to lower pressure by 0.25 or more bar, error code 01 5 + returnData.preIndicator1 = '0'; + returnData.preIndicator2 = '1'; + } + } + + if (ms - ATC::Startup::ms >= 7000 && internalData.achived2) { // no fail + returnData.mainIndicator1 = '6'; + returnData.requestedBrakePressure = 0.0f; + } + + if (internalData.failed) { + returnData.ATCStatus = 0; + internalData.startup = 0; + ATC::Startup::ms = 0; + internalData.dataEntryButtonPressed = false; + internalData.failed = false; + } + } + + if (ms - ATC::Startup::ms >= startupTime) { + returnData.mainIndicator0 = ' '; + returnData.mainIndicator1 = ' '; + returnData.mainIndicator2 = ' '; + returnData.ATCError = true; + returnData.toneF1 = true; + returnData.toneF2 = true; + if (data.dataEntryButton) { + internalData.dataEntryButtonPressed = true; + ATC::turnOnAll(returnData); + returnData.ATCError = false; + returnData.toneF1 = false; + } + if (!data.dataEntryButton && internalData.dataEntryButtonPressed) { + ATC::turnOffAll(returnData); + internalData.startup = 2; + ATC::Startup::ms = 0; + internalData.dataEntryButtonPressed = false; + internalData.achived = false; + internalData.achived1 = false; + internalData.achived2 = false; + } + } +} \ No newline at end of file diff --git a/ATC_Dator/src/ATCStartup/startup.hpp b/ATC_Dator/src/ATCStartup/startup.hpp new file mode 100644 index 0000000..36264be --- /dev/null +++ b/ATC_Dator/src/ATCStartup/startup.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "../ATCData.hpp" + +namespace ATC { + +namespace Startup { +extern int ms; +extern void errors(ATCData &data, internalATCData &internalData, ATCReturnData &returnData); +} // namespace Startup + +extern void startupSequence(ATCData &data, internalATCData &internalData, ATCReturnData &returnData); + +} // namespace ATC \ No newline at end of file diff --git a/ATC_Dator/src/Utils/utils.cpp b/ATC_Dator/src/Utils/utils.cpp new file mode 100644 index 0000000..9fc3abe --- /dev/null +++ b/ATC_Dator/src/Utils/utils.cpp @@ -0,0 +1,41 @@ +#include "utils.hpp" + +void ATC::turnOffAll(ATCReturnData &returnData) { + returnData.ATCError = false; + returnData.toneF1 = false; + returnData.toneF2 = false; + returnData.shuntingLamp = false; + returnData.preIndicator0 = ' '; + returnData.preIndicator1 = ' '; + returnData.preIndicator2 = ' '; + returnData.ATCError = false; + returnData.BaliseError = false; + returnData.speeding = false; + returnData.mainIndicator0 = ' '; + returnData.mainIndicator1 = ' '; + returnData.mainIndicator2 = ' '; + returnData.releaseLamp = false; + returnData.increaseLamp = false; + returnData.dataEntryLamp = false; + returnData.smallError = false; +} + +void ATC::turnOnAll(ATCReturnData &returnData) { + returnData.ATCError = true; + returnData.toneF1 = true; + returnData.toneF2 = true; + returnData.shuntingLamp = true; + returnData.preIndicator0 = '8'; + returnData.preIndicator1 = '8'; + returnData.preIndicator2 = '8'; + returnData.ATCError = true; + returnData.BaliseError = true; + returnData.speeding = true; + returnData.mainIndicator0 = '8'; + returnData.mainIndicator1 = '8'; + returnData.mainIndicator2 = '8'; + returnData.releaseLamp = true; + returnData.increaseLamp = true; + returnData.dataEntryLamp = true; + returnData.smallError = true; +} \ No newline at end of file diff --git a/ATC_Dator/src/Utils/utils.hpp b/ATC_Dator/src/Utils/utils.hpp new file mode 100644 index 0000000..f5d8c8c --- /dev/null +++ b/ATC_Dator/src/Utils/utils.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "../ATCData.hpp" + +namespace ATC { +extern void turnOffAll(ATCReturnData &returnData); +extern void turnOnAll(ATCReturnData &returnData); +} // namespace ATC \ No newline at end of file diff --git a/ATC_Dator/src/main.cpp b/ATC_Dator/src/main.cpp index edffe08..0b36c86 100644 --- a/ATC_Dator/src/main.cpp +++ b/ATC_Dator/src/main.cpp @@ -1,8 +1,80 @@ +#include #include -#include "networking/sockets/tcpSocket.hpp" +#include +#include + +#include "ATCStartup/startup.hpp" + +struct ClientData { + bool power = false; +}; + +ClientData clientData; + +ATCReturnData atcReturn; + +void togglePowerMessage(ShiraNet::NetworkData::Message &message) { + ShiraNet::NetworkData::DataField data; + message.payloadToDataField(data); + + clientData.power = data.data; + std::cout << "power is now: " << std::to_string(data.data) << std::endl; +} + +void handleMessage(ShiraNet::NetworkData::Message &message) { + switch (message.id) { + case 0: + break; + + case 1: + togglePowerMessage(message); + break; + + default: + break; + } +} + +void clientCallback(std::shared_ptr client, ShiraNet::Servers::TcpServer *server) { + while (true) { + try { + ShiraNet::NetworkData::Message message = client->receiveMessage(MSG_DONTWAIT); + handleMessage(message); + } catch (...) { + } + + try { + ShiraNet::NetworkData::DataField ATCDataField{sizeof(ATCReturnData), atcReturn}; + ShiraNet::NetworkData::Message ATCDataMessage(0, ATCDataField); + client->send(ATCDataMessage); + std::cout << "sent message\n"; + } catch (const std::exception &e) { + std::cerr << "Failed to send (std): " << e.what() << std::endl; + } catch (...) { + std::cerr << "Failed to send: unknown exception\n"; + } + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } +} + +void server(ShiraNet::Servers::TcpServer *server) { + while (true) { + server->getConnection(clientCallback); + } +} int main() { - std::cout << "Hello world\n"; + ShiraNet::Servers::TcpServer ATCServer(AF_INET, 1337, 10); + std::thread serverThread(server, &ATCServer); + + ATCData atcData; + internalATCData atcInternal; - Networking::TcpSocket tcpSocket; + while (true) { + if (clientData.power || atcInternal.startup == 1) { + clientData.power = false; + ATC::startupSequence(atcData, atcInternal, atcReturn); + } + } } \ No newline at end of file diff --git a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt index 3db6acd..7e88853 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt +++ b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt @@ -13,6 +13,7 @@ endif() set(BUILD_SHARED_LIBS ON) set(BUILD_EXAMPLES OFF) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Raylib set(SUPPORT_X11 ON CACHE BOOL "Use X11 for windowing" FORCE) @@ -23,17 +24,27 @@ add_subdirectory( ) include_directories(../../../extern/raylib/) +# ShiraNet +add_subdirectory( + ${CMAKE_CURRENT_LIST_DIR}/../../../extern/ShiraNet + ${CMAKE_BINARY_DIR}/ShiraNet +) +include_directories(../../../extern/ShiraNet/include) + # RaylibAdditions include_directories(../../../extern/RaylibAdditions) file(GLOB RAYLIB_ADDITIONS_SOURCES ../../../extern/RaylibAdditions/*.cpp) file(GLOB SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) +include_directories(${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/networking) +file(GLOB ATCNetworkingSources ${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/networking/*.cpp) + set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") # Create the executable -add_executable(ATC_Panel_ExDebug ${SOURCES} ${RAYLIB_ADDITIONS_SOURCES}) -target_link_libraries(ATC_Panel_ExDebug PRIVATE raylib) +add_executable(ATC_Panel_ExDebug ${SOURCES} ${RAYLIB_ADDITIONS_SOURCES} ${ATCNetworkingSources}) +target_link_libraries(ATC_Panel_ExDebug PRIVATE raylib ShiraNet) # Apply Release mode specific settings if(CMAKE_BUILD_TYPE STREQUAL "Release") diff --git a/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp index 028b7d2..b146058 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp +++ b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp @@ -1,12 +1,26 @@ +#include +#include #include #include -#include #include +#include "networking.hpp" + +ATCReturnData ATCData; + +void getDataThread(ShiraNet::Sockets::TcpSocket &socket) { + while (true) { // [taskig] use interval + auto newData = ATCNetworking::getATCData(socket); + if (newData.has_value()) { + ATCData = newData.value(); + } + } +} + int main() { - const std::string resPath = "../../res"; // should be ./ when built for "release" or packaged, also adjust for windows, also use filesystem path for ease of use + const std::string resPath = "../../../res"; // should be ./ when built for "release" or packaged, also adjust for windows, also use filesystem path for ease of use - RaylibAdditions::WindowClass window{"ATC_Panel_Extended_Debug", 1024, 500}; // read screen size from config later + RaylibAdditions::WindowClass window{"ATC_Panel_Extended_Debug", 1200, 500}; // read screen size from config later SetTargetFPS(60); SetWindowMonitor(0); @@ -32,7 +46,7 @@ int main() { RaylibAdditions::ButtonClass stopPassageButton = {stopPassage, "", 0, BLANK, BLANK, BLANK, 0, 1}; Rectangle dataEntry = {642, 40, 20, 20}; RaylibAdditions::ButtonClass dataEntryButton = {dataEntry, "", 0, BLANK, BLANK, BLANK, 0, 1}; - + RaylibAdditions::SpeedometerClass speedometer = {{0, float(ATCPanelTexture.height), 300, 300}, 0, 200, 160, 380, 21, "km/h", WHITE, YELLOW}; Rectangle speedButtonRect = {0, 300, 50, 50}; RaylibAdditions::ButtonClass speedRemove = {speedButtonRect, "-10", 20, GRAY, WHITE, WHITE, 5, 1}; @@ -49,6 +63,9 @@ int main() { brakePressureButtonRect.x += 300 - 50; RaylibAdditions::ButtonClass brakePressureAdd = {brakePressureButtonRect, "+0,5", 20, GRAY, WHITE, WHITE, 5, 1}; + Rectangle toggleATCRect = {0, 350, 200, 50}; + RaylibAdditions::ButtonClass toggleATCButton = {toggleATCRect, "Toggle ATC", 20, GRAY, WHITE, WHITE, 5, 1}; + std::vector> thumbWheels = { {{691, 21}, 0}, // STH/V-MAX {{712, 21}, 0}, @@ -62,12 +79,59 @@ int main() { {{882, 21}, 0}, {{903, 21}, 0}, - {{949, 21}, 0}, // procentuell överskridning / procentual override, X2000 has 30% due to boggies design and tilting + {{949, 21}, 0}, // procentuell överskridning / procentual override, X2000 has 30% due to boggies design and tilting }; - while(!WindowShouldClose()) { - //update - // this button code sucks, fix it + ShiraNet::Sockets::TcpSocket socket(AF_INET); + socket.connect("localhost", 1337); + + std::thread getATCDataThread{getDataThread, std::ref(socket)}; + + while (!WindowShouldClose()) { + // ATC values + int y = 0; + int fontSize = 10; + int lineHeight = 14; // slightly bigger than font size for spacing + DrawText(("ATCStatus = " + std::to_string(ATCData.ATCStatus)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("toneF1 = " + std::to_string(ATCData.toneF1)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("toneF2 = " + std::to_string(ATCData.toneF2)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("shuntingLamp = " + std::to_string(ATCData.shuntingLamp)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("ATCStatus = " + std::to_string(ATCData.ATCStatus)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("preIndicator0 = " + std::string(1, ATCData.preIndicator0)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("preIndicator1 = " + std::string(1, ATCData.preIndicator1)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("preIndicator2 = " + std::string(1, ATCData.preIndicator2)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("ATCError = " + std::to_string(ATCData.ATCError)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("BaliseError = " + std::to_string(ATCData.BaliseError)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("speeding = " + std::to_string(ATCData.speeding)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("mainIndicator0 = " + std::string(1, ATCData.mainIndicator0)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("mainIndicator1 = " + std::string(1, ATCData.mainIndicator1)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("mainIndicator2 = " + std::string(1, ATCData.mainIndicator2)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("releaseLamp = " + std::to_string(ATCData.releaseLamp)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("increaseLamp = " + std::to_string(ATCData.increaseLamp)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("dataEntryLamp = " + std::to_string(ATCData.dataEntryLamp)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("smallError = " + std::to_string(ATCData.smallError)).c_str(), 1024, y, fontSize, WHITE); + y += lineHeight; + DrawText(("requestedBrakePressure = " + std::to_string(ATCData.requestedBrakePressure)).c_str(), 1024, y, fontSize, WHITE); + + // update + // this button code sucks, fix it shuntingButton.updateState(); releaseButton.updateState(); increaseButton.updateState(); @@ -79,6 +143,14 @@ int main() { speedAddSmall.updateState(); brakePressureRemove.updateState(); brakePressureAdd.updateState(); + toggleATCButton.updateState(); + + if (toggleATCButton.state == 2) { + if (ATCData.ATCStatus == 0) + ATCNetworking::toggleATCPower(1, socket); + else + ATCNetworking::toggleATCPower(0, socket); + } if (speedRemove.state == 2) speedometer.value -= 10; @@ -107,6 +179,15 @@ int main() { speedAddSmall.draw(); brakePressureRemove.draw(); brakePressureAdd.draw(); + toggleATCButton.draw(); + + DrawText(std::string(1, ATCData.preIndicator0).c_str(), preInd.x + (preInd.width/3.0)*0, preInd.y + preInd.height/2 - 5, 10, YELLOW); + DrawText(std::string(1, ATCData.preIndicator1).c_str(), preInd.x + (preInd.width/3.0)*1, preInd.y + preInd.height/2 - 5, 10, YELLOW); + DrawText(std::string(1, ATCData.preIndicator2).c_str(), preInd.x + (preInd.width/3.0)*2, preInd.y + preInd.height/2 - 5, 10, YELLOW); + + DrawText(std::string(1, ATCData.mainIndicator0).c_str(), mainInd.x + (mainInd.width/3.0)*0, mainInd.y + mainInd.height/2 - 10, 20, GREEN); + DrawText(std::string(1, ATCData.mainIndicator1).c_str(), mainInd.x + (mainInd.width/3.0)*1, mainInd.y + mainInd.height/2 - 10, 20, GREEN); + DrawText(std::string(1, ATCData.mainIndicator2).c_str(), mainInd.x + (mainInd.width/3.0)*2, mainInd.y + mainInd.height/2 - 10, 20, GREEN); EndDrawing(); } diff --git a/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp b/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp new file mode 100644 index 0000000..e087f91 --- /dev/null +++ b/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp @@ -0,0 +1,24 @@ +#include "networking.hpp" + +#include + +std::optional ATCNetworking::getATCData(ShiraNet::Sockets::TcpSocket &socket) { + try { + ShiraNet::NetworkData::Message message = socket.receiveMessage(); // note this is blocking which is good in this case + if (message.payloadSize == 0) + return std::nullopt; + ShiraNet::NetworkData::DataField data; + message.payloadToDataField(data); + return data.data; + } catch (...) { + } + return std::nullopt; +} + +void ATCNetworking::toggleATCPower(bool state, ShiraNet::Sockets::TcpSocket &socket) { + ShiraNet::NetworkData::DataField data; + data.data = state; + + ShiraNet::NetworkData::Message message(1, data); + socket.send(message); +} \ No newline at end of file diff --git a/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp b/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp new file mode 100644 index 0000000..bdf394f --- /dev/null +++ b/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "../../../../ATC_Dator/src/ATCData.hpp" + +#include +#include + +namespace ATCNetworking { + +std::optional getATCData(ShiraNet::Sockets::TcpSocket &socket); +void toggleATCPower(bool state, ShiraNet::Sockets::TcpSocket &socket); + +} \ No newline at end of file diff --git a/Examples/C++/CMakeLists.txt b/Examples/C++/CMakeLists.txt deleted file mode 100644 index ed1312d..0000000 --- a/Examples/C++/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -cmake_minimum_required(VERSION 3.20) - -set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build) - -project(ATCEXAMPLE) -set(CMAKE_CXX_STANDARD 20) # Use C++ 20 -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# Enable Release mode -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) -endif() - -set(BUILD_SHARED_LIBS ON) -set(BUILD_EXAMPLES OFF) - -add_subdirectory(./extern/raylib) -include_directories(./extern/raylib/) - -include_directories(./extern/RaylibAdditions) -file(GLOB_RECURSE RAYLIB_ADDITIONS_SOURCES ./extern/RaylibAdditions/*.cpp) - -file(GLOB SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) - -set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") - -add_subdirectory(../../ATC/API_C_CPP ATCAPI) -include_directories(../../ATC/API_C_CPP/include) - -# Create the executable -add_executable(ATCEXAMPLE ${SOURCES} ${RAYLIB_ADDITIONS_SOURCES}) - -# Link libraries -target_link_libraries(ATCEXAMPLE PRIVATE raylib) -target_link_libraries(ATCEXAMPLE PRIVATE ATCAPI) - -# Apply Release mode specific settings -if(CMAKE_BUILD_TYPE STREQUAL "Release") - # Add optimization flags - target_compile_options(ATCEXAMPLE PRIVATE -O3) - - # Optionally, strip symbols to reduce binary size - if (NOT WIN32) - target_link_options(ATCEXAMPLE PRIVATE -s) - endif() -endif() diff --git a/Examples/C++/res/ATC.gui b/Examples/C++/res/ATC.gui deleted file mode 100644 index 0d4de96..0000000 --- a/Examples/C++/res/ATC.gui +++ /dev/null @@ -1,31 +0,0 @@ -1023:80 -[frame:0] - 0 ----- atcpanel2 ----- 0 ----- 0 ----- x1 - 1 ----- up_arrow ----- 694 ----- 38 ----- x1 - 2 ----- up_arrow ----- 718 ----- 38 ----- x1 - 3 ----- down_arrow ----- 694 ----- 62 ----- x1 - 4 ----- down_arrow ----- 718 ----- 62 ----- x1 - 5 ----- temp ----- 694 ----- 50 ----- x1 - 6 ----- temp ----- 718 ----- 50 ----- x1 - 7 ----- down_arrow ----- 762 ----- 62 ----- x1 - 8 ----- up_arrow ----- 762 ----- 39 ----- x1 - 9 ----- temp ----- 762 ----- 50 ----- x1 - 10 ----- up_arrow ----- 806 ----- 40 ----- x1 - 11 ----- up_arrow ----- 828 ----- 40 ----- x1 - 12 ----- down_arrow ----- 806 ----- 63 ----- x1 - 13 ----- down_arrow ----- 828 ----- 63 ----- x1 - 14 ----- up_arrow ----- 872 ----- 40 ----- x1 - 15 ----- up_arrow ----- 895 ----- 40 ----- x1 - 16 ----- up_arrow ----- 916 ----- 40 ----- x1 - 17 ----- up_arrow ----- 959 ----- 40 ----- x1 - 18 ----- temp ----- 806 ----- 51 ----- x1 - 19 ----- temp ----- 828 ----- 51 ----- x1 - 20 ----- down_arrow ----- 872 ----- 62 ----- x1 - 21 ----- down_arrow ----- 895 ----- 62 ----- x1 - 22 ----- down_arrow ----- 959 ----- 62 ----- x1 - 23 ----- down_arrow ----- 916 ----- 62 ----- x1 - 24 ----- temp ----- 872 ----- 51 ----- x1 - 25 ----- temp ----- 895 ----- 51 ----- x1 - 26 ----- temp ----- 916 ----- 51 ----- x1 - 27 ----- temp ----- 959 ----- 51 ----- x1 -[buttons] diff --git a/Examples/C++/res/audio/ATC1.wav b/Examples/C++/res/audio/ATC1.wav deleted file mode 100644 index 553681a1fed12646a44b5d2659c938aba5a1bff0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96028 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 X@$L9_(MzH&*e2{B!Y*Mq|3Ci!)R!)& diff --git a/Examples/C++/res/audio/f2.wav b/Examples/C++/res/audio/f2.wav deleted file mode 100644 index c1a9e3ba636e1419ea3537434b4bd3baac46f964..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76320 zcmeI*zf06{9LMpmS`J2Ka(JfaU1M5MQ{ZG`i4B1{Xw(ovwe$mmh9DhsXlQ5>8iJs$ zA%}jg;?mYER70m;-Y-2vv&;V|eoU-tZkiH!{-I-;_)aO`N@P z``(fEBuSc*=H$$)Bx!%$oa{;3lWSM+UES(ys(&-tGue|IX{@u5UC7>Sx!KZD>L?}o z#yfq#`hLx%W>Sr%_V?EewGFkEYNcA^sU`XG&GF5-{d4;p(Jg%_eQ17re!CIfrmNG{ z#n#2vMs!71jbpmmIHp^ywsA~5 z8^?6BaZEQG$8?L;HjZg$1N}YZZ?kT7OQO>)6T{*-E17w&Big^ zVzrH9+Sxd!n~h_-**KM zY#h_g#xdP&9MdgU+c>73jbpmmIHsG8W4gs^8^^S>aZEQG$8?Lv)nBdSyLIZ#pdA}W z6Z^Z@#xdP&9MjEv9MdgU+c>73jbpmmIHsHTIHp^ywsA~58^?6BaZESwaZI;ZZR41B zHje3LMY#h_g#xdQz$1&YvwT)xi**K<~jbpmmIHp^ywsA~58^?6B zaZEQG$8?L;HjZg$1N}YZZ?kT7OQO>)6T{*-E17w&Big^VzrH9 z+Sxd!n~h_-MdN($0MpLKG2Lt&)6K>)-E17wEmqq&rk#yry4g6Uo6jnlZn4_NG3{&| z)6K>)-E17wEmqq&rk#yry4g6Un~h_-#cCVJw6k$cHyg)v^Zz)eTdcNmOgkILbhB|x zH}7#ww^(iCn07Xf>1N}YZZ?kT7OQO>)6T{*-E17w&1aQNw^(iCn07Xf>1N}YZZ?kT z7OQO>)6T{*-E17w&1aQNw^(iCn07Xf>1N}YZZ?kT7OQO>)6T{*-E17w&1aQNw^(iC zn07Xf>1N}YZr)-TwE+?dEoKUvpn_PjgRl1G&E3$Lzc8SoUQ0 zL+`WRqrE>eQ<>A5`JVedweIKL`?}v8?mYaq>p<6w^j7C|=T_=|>U{HH^TY3j@29Ho ztDh@l)mxQMm9_F%Ymm1;=y93lqvO>`^y8Bfy!ugv^udi Sv37m^+WOtv-P(hVsf|DKR}|#{ diff --git a/Examples/C++/res/textures/atcpanel2.png b/Examples/C++/res/textures/atcpanel2.png deleted file mode 100644 index 7c276e6c9acdac73644ae5cff7d428f8a217be1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53866 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 QKSI25S7-8TxH$-fsVRt7`zrJ3UhlM= zo^HqZO6u|Lv$hUeayRatn!0wX!p+=YyBL43J6`hO%UNluV0E6|TX|K1wlH|Q`njxg HN@xNA8Iv_O diff --git a/Examples/C++/src/main.cpp b/Examples/C++/src/main.cpp deleted file mode 100644 index 6fe12a4..0000000 --- a/Examples/C++/src/main.cpp +++ /dev/null @@ -1,267 +0,0 @@ -#include -#include -#include -#include -#include - -int main() { - std::cout << "Hello world!"; - - InitWindow(1500, 400, "ATC Simulator"); - SetTargetFPS(60); - SetWindowMonitor(0); - - int lastTime = GetTime(); - - InitAudioDevice(); - Sound ATC1 = LoadSound("../res/audio/f1.wav"); // Better f1 tone // 1. f1 med 2,5 kHz ± 20 %. f1 aktiveras endast vid ATC-larm (verkligt eller simulerat) och är helt oberoende av om ATC-systemets matningsdon fungerar eller inte. Ljudstyrkan hos f1 kan inte regleras. - Sound ATC2 = LoadSound("../res/audio/f2.wav"); // f2 med 400 Hz ± 10 % fyrkantvåg. f2 är styrbar från datorerna under normal drift. Den aktiveras dessutom vid ATC-larm och är härvid oberoende av om ATC-systemets matningsdon fungerar eller inte. Ljudstyrkan är reglerbar med en potentiometer på panelen. - - Texture2D ATCPanel = LoadTexture("../res/textures/cleanATC.png"); - Rectangle preInd = {61, 28, 59, 24}; - Rectangle mainInd = {234, 23, 75, 30}; - - Rectangle startup = {0, float(ATCPanel.height), 200, 50}; - RaylibAdditions::ButtonClass startupButton = {startup, "Start ATC", 20, GRAY, WHITE, WHITE, 5, 1}; - Rectangle switchATCType = {0, startupButton.rect.y + startupButton.rect.height, 200, 50}; - RaylibAdditions::ButtonClass switchATCTypeButton = {switchATCType, "Use ABB ATC", 20, GRAY, WHITE, WHITE, 5, 1}; - - Rectangle shunting = {17, 38, 18, 18}; - RaylibAdditions::ButtonClass shuntingButton = {shunting, BLANK, BLANK, 0, 1}; - Rectangle release = {333, 39, 18, 18}; - RaylibAdditions::ButtonClass releaseButton = {release, BLANK, BLANK, 0, 1}; - Rectangle increase = {384, 39, 18, 18}; - RaylibAdditions::ButtonClass increaseButton = {increase, BLANK, BLANK, 0, 1}; - Rectangle stopPassage = {484, 39, 18, 18}; - RaylibAdditions::ButtonClass stopPassageButton = {stopPassage, BLANK, BLANK, 0, 1}; - Rectangle dataEntry = {642, 40, 20, 20}; - RaylibAdditions::ButtonClass dataEntryButton = {dataEntry, BLANK, BLANK, 0, 1}; - - RaylibAdditions::SpeedometerClass speedometer = {{200, float(ATCPanel.height), 300, 300}, 0, 200, 160, 380, 21, "km/h", WHITE, YELLOW}; - Rectangle speedButtonRect = {200, 300, 50, 50}; - RaylibAdditions::ButtonClass speedRemove = {speedButtonRect, "-10", 20, GRAY, WHITE, WHITE, 5, 1}; - speedButtonRect.x += 300 - 50; - RaylibAdditions::ButtonClass speedAdd = {speedButtonRect, "+10", 20, GRAY, WHITE, WHITE, 5, 1}; - - Rectangle speedButtonRectSmall = {250, 300, 50, 50}; - RaylibAdditions::ButtonClass speedRemoveSmall = {speedButtonRectSmall, "-1", 20, GRAY, WHITE, WHITE, 5, 1}; - speedButtonRectSmall.x += 200 - 50; - RaylibAdditions::ButtonClass speedAddSmall = {speedButtonRectSmall, "+1", 20, GRAY, WHITE, WHITE, 5, 1}; - - RaylibAdditions::SpeedometerClass brakePressure = {{500, float(ATCPanel.height), 300, 300}, 0, 10, 160, 380, 11, "kPa", WHITE, RED}; - Rectangle brakePressureButtonRect = {500, 300, 50, 50}; - RaylibAdditions::ButtonClass brakePressureRemove = {brakePressureButtonRect, "-0,5", 20, GRAY, WHITE, WHITE, 5, 1}; - brakePressureButtonRect.x += 300 - 50; - RaylibAdditions::ButtonClass brakePressureAdd = {brakePressureButtonRect, "+0,5", 20, GRAY, WHITE, WHITE, 5, 1}; - - bool leakBool = false; - Rectangle leak = {switchATCType.x, switchATCType.y + switchATCType.height, switchATCType.width, switchATCType.height}; - RaylibAdditions::ButtonClass leakButton = {leak, "Pressure leak", 20, GRAY, WHITE, WHITE, 5, 1}; - - std::vector> thumbWheels = { - {{691, 21}, 0}, // STH/V-MAX - {{712, 21}, 0}, - - {{752, 21}, 0}, // length (100m) - - {{795, 21}, 0}, // tillsättningstid / brake apply time - {{817, 21}, 0}, - - {{861, 21}, 0}, // redartationstalet / deacelerationnumber (converted by some formula, locos have a guide) (bromsprocent på 76 = 061) - {{882, 21}, 0}, - {{903, 21}, 0}, - - {{949, 21}, 0}, // procentuell överskridning / procentual override, X2000 has 30% due to boggies design and tilting - }; - - ATCReturnData returnedData; - ATCData data = {}; - initATC(); - - while (!WindowShouldClose()) { - BeginDrawing(); - ClearBackground(BLACK); - DrawTexture(ATCPanel, 0, 0, WHITE); - RaylibAdditions::drawButton(&startupButton); - RaylibAdditions::updateButtonstate(&startupButton); - if (startupButton.state == 2) { - if (returnedData.ATCStatus == 1) - toggleATC(0); - if (returnedData.ATCStatus == 0) - toggleATC(1); - } - - if (returnedData.ATCStatus == 1) - startupButton.text = "Turn off ATC"; - if (returnedData.ATCStatus == 0) - startupButton.text = "Turn on ATC"; - - RaylibAdditions::drawButton(&switchATCTypeButton); - RaylibAdditions::updateButtonstate(&switchATCTypeButton); - if (switchATCTypeButton.state == 2) { - toggleSystemType(!getSystemType()); - if (getSystemType()) - switchATCTypeButton.text = "Use SRT ATC"; - if (!getSystemType()) - switchATCTypeButton.text = "Use ABB ATC"; - } - - data.shuntingButton = shuntingButton.updateState(); - data.releaseButton = releaseButton.updateState(); - data.increaseButton = increaseButton.updateState(); - data.stopPassageButton = stopPassageButton.updateState(); - data.dataEntryButton = dataEntryButton.updateState(true); - - data.brakePressure = brakePressure.value; - std::cout << brakePressure.value << std::endl; - returnedData = runATC(data); - if (returnedData.requestedBrakePressure != 0) { - if (GetTime() > lastTime && brakePressure.value != returnedData.requestedBrakePressure) { - if (brakePressure.value > returnedData.requestedBrakePressure) - brakePressure.value -= 0.05; - if (brakePressure.value < returnedData.requestedBrakePressure) - brakePressure.value += 0.05; - } - lastTime = GetTime(); - } - - int i = 0; - for (auto& thumbWheel : thumbWheels) { - Vector2 pos = thumbWheel.first; - int& value = thumbWheel.second; - - Rectangle wheelRect = {pos.x, pos.y, 20, 30}; - DrawText(std::to_string(value).c_str(), pos.x + 5, pos.y + 5, 20, WHITE); - if (CheckCollisionPointRec(GetMousePosition(), wheelRect)) { - int mouseWheel = GetMouseWheelMove(); - if (mouseWheel > 0) { - value++; - if (value > 9) value = 0; - } else if (mouseWheel < 0) { - value--; - if (value < 0) value = 9; - } - } - - switch (i) { // stupid - case 0: - data.STHDial1 = value * 2; - break; - - case 1: - data.STHDial2 = value * 2; - break; - - case 2: - data.lengthDial = value * 2; - break; - - case 3: - data.applyTimeDial1 = value * 2; - break; - - case 4: - data.applyTimeDial2 = value * 2; - break; - - case 5: - data.retardationDial1 = value * 2; - break; - - case 6: - data.retardationDial2 = value * 2; - break; - - case 7: - data.retardationDial3 = value * 2; - break; - - case 8: - data.overrideDial = value * 2; - break; - - default: - break; - } - - i++; - } - - if (returnedData.shuntingLamp) DrawCircle(25, 25, 5, RED); - if (returnedData.ATCError) DrawCircle(150, 40, 5, RED); - if (returnedData.BaliseError) DrawCircle(180, 40, 5, YELLOW); - if (returnedData.speeding) DrawCircle(212, 40, 5, GREEN); - if (returnedData.releaseLamp) DrawCircle(340, 25, 5, YELLOW); - if (returnedData.increaseLamp) DrawCircle(392, 25, 5, GREEN); - if (returnedData.dataEntryLamp) DrawCircle(652, 25, 5, RED); - if (returnedData.smallError) DrawCircle(1007, 37, 5, YELLOW); - - if (returnedData.toneF1 && !IsSoundPlaying(ATC1)) PlaySound(ATC1); - if (returnedData.toneF2 && !IsSoundPlaying(ATC2)) PlaySound(ATC2); - - int fontSizePreInd = 15; - DrawText(std::string(1, returnedData.preIndicator0).c_str(), preInd.x + ((preInd.width/4) * 1) - fontSizePreInd / 2, preInd.y + preInd.height/2 - fontSizePreInd/2, fontSizePreInd, YELLOW); - DrawText(std::string(1, returnedData.preIndicator1).c_str(), preInd.x + ((preInd.width/4) * 2) - fontSizePreInd / 2, preInd.y + preInd.height/2 - fontSizePreInd/2, fontSizePreInd, YELLOW); - DrawText(std::string(1, returnedData.preIndicator2).c_str(), preInd.x + ((preInd.width/4) * 3) - fontSizePreInd / 2, preInd.y + preInd.height/2 - fontSizePreInd/2, fontSizePreInd, YELLOW); - int fontSizeMainInd = 20; - DrawText(std::string(1, returnedData.mainIndicator0).c_str(), mainInd.x + ((mainInd.width/4) * 1) - fontSizeMainInd / 2, mainInd.y + mainInd.height/2 - fontSizeMainInd/2, fontSizeMainInd, GREEN); - DrawText(std::string(1, returnedData.mainIndicator1).c_str(), mainInd.x + ((mainInd.width/4) * 2) - fontSizeMainInd / 2, mainInd.y + mainInd.height/2 - fontSizeMainInd/2, fontSizeMainInd, GREEN); - DrawText(std::string(1, returnedData.mainIndicator2).c_str(), mainInd.x + ((mainInd.width/4) * 3) - fontSizeMainInd / 2, mainInd.y + mainInd.height/2 - fontSizeMainInd/2, fontSizeMainInd, GREEN); - - DrawText(std::string("ATC status = " + std::to_string(returnedData.ATCStatus)).c_str(), 1050, 0, 10, WHITE); - DrawText(std::string("Tone f1 = " + std::to_string(returnedData.toneF1)).c_str(), 1050, 15, 10, WHITE); - DrawText(std::string("Tone f2 = " + std::to_string(returnedData.toneF2)).c_str(), 1050, 30, 10, WHITE); - DrawText(std::string("Shunting lamp = " + std::to_string(returnedData.shuntingLamp)).c_str(), 1050, 45, 10, WHITE); - DrawText(std::string("ATC preind = " + std::string(1, returnedData.preIndicator0) + std::string(1, returnedData.preIndicator1) + std::string(1, returnedData.preIndicator2)).c_str(), 1050, 60, 10, WHITE); - DrawText(std::string("ATC Error = " + std::to_string(returnedData.ATCError)).c_str(), 1050, 75, 10, WHITE); - DrawText(std::string("Balise Error = " + std::to_string(returnedData.BaliseError)).c_str(), 1050, 90, 10, WHITE); - DrawText(std::string("Speeding = " + std::to_string(returnedData.speeding)).c_str(), 1050, 105, 10, WHITE); - DrawText(std::string("ATC mainind = " + std::string(1, returnedData.mainIndicator0) + std::string(1, returnedData.mainIndicator1) + std::string(1, returnedData.mainIndicator2)).c_str(), 1050, 120, 10, WHITE); - DrawText(std::string("Release lamp = " + std::to_string(returnedData.releaseLamp)).c_str(), 1050, 135, 10, WHITE); - DrawText(std::string("Increase lamp = " + std::to_string(returnedData.increaseLamp)).c_str(), 1050, 150, 10, WHITE); - DrawText(std::string("Data entry lamp = " + std::to_string(returnedData.dataEntryLamp)).c_str(), 1050, 165, 10, WHITE); - DrawText(std::string("Small error = " + std::to_string(returnedData.smallError)).c_str(), 1050, 180, 10, WHITE); - DrawText(std::string("Requested brake pressure = " + std::to_string(returnedData.requestedBrakePressure)).c_str(), 1050, 195, 10, WHITE); - DrawText(std::string("Data entry button = " + std::to_string(data.dataEntryButton)).c_str(), 1050, 210, 10, WHITE); - - speedometer.drawSpeedometer(); - brakePressure.drawSpeedometer(); - brakePressure.drawNeedle({255, 4, 20, 255}, 3.0f, 0.5); - - speedAdd.drawAndUpdate(); - speedRemove.drawAndUpdate(); - speedAddSmall.drawAndUpdate(); - speedRemoveSmall.drawAndUpdate(); - - if (speedAdd.state == 2 && speedometer.value + 10 <= 200) - speedometer.value += 10; - if (speedRemove.state == 2 && speedometer.value - 10 >= 0) - speedometer.value -= 10; - if (speedAddSmall.state == 2 && speedometer.value + 1 <= 200) - speedometer.value += 1; - if (speedRemoveSmall.state == 2 && speedometer.value - 1 >= 0) - speedometer.value -= 1; - - brakePressureAdd.drawAndUpdate(); - brakePressureRemove.drawAndUpdate(); - - if (brakePressureRemove.state == 2 && brakePressure.value - 0.5 >= 0) - brakePressure.value -= 0.5; - if (brakePressureAdd.state == 2 && brakePressure.value + 0.5 <= 10) - brakePressure.value += 0.5; - - leakButton.drawAndUpdate(); - if (leakButton.state == 2) - leakBool = !leakBool; - - if (leakBool) { - if (GetTime() > lastTime && brakePressure.value >= 0.5) // 1 sec or more passed - brakePressure.value -= 0.5; - lastTime = GetTime(); - } - - EndDrawing(); - } - - return 0; -} \ No newline at end of file diff --git a/UniversalFunctions/networking/sockets/tcpSocket.cpp b/UniversalFunctions/networking/sockets/tcpSocket.cpp deleted file mode 100644 index 0f5d7ca..0000000 --- a/UniversalFunctions/networking/sockets/tcpSocket.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "tcpSocket.hpp" -#include - -namespace Networking { - TcpSocket::TcpSocket(int SocketDomain, int SocketType, int Protocol) { - socketFd = socket(SocketDomain, SocketType, Protocol); - - if (socketFd == -1) { - std::cerr << "Failed to open socket: " << errno << std::endl; - return; - } - - socketAddress.sin_family = SocketDomain; - socketAddress.sin_addr.s_addr = htonl(address); - socketAddress.sin_port = htons(port); - } -} \ No newline at end of file diff --git a/UniversalFunctions/networking/sockets/tcpSocket.hpp b/UniversalFunctions/networking/sockets/tcpSocket.hpp deleted file mode 100644 index b85de59..0000000 --- a/UniversalFunctions/networking/sockets/tcpSocket.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef __linux__ - #include - #include - #include - #include -#elif _WIN32 - #include -#endif - -#include "../../utils.hpp" - -namespace Networking { - - class TcpSocket : private Utils::NoCopy { // add windows support - private: - sockaddr_in socketAddress; - in_port_t port = 1337; - in_addr_t address = INADDR_LOOPBACK; - int socketFd; - public: - TcpSocket(int SocketDomain = AF_INET, int SocketType = SOCK_STREAM | SOCK_NONBLOCK, int Protocol = 0); // AF_UNIX = local communication, allow other types later - int bind(); - int connect(); - }; -} \ No newline at end of file diff --git a/UniversalFunctions/readme.md b/UniversalFunctions/readme.md deleted file mode 100644 index b66ba6a..0000000 --- a/UniversalFunctions/readme.md +++ /dev/null @@ -1,4 +0,0 @@ -## Folder explanation - -### Networking -Contains the code for sockets, ect needed by both the "dator" and the "panel" \ No newline at end of file diff --git a/UniversalFunctions/utils.hpp b/UniversalFunctions/utils.hpp deleted file mode 100644 index dd6d294..0000000 --- a/UniversalFunctions/utils.hpp +++ /dev/null @@ -1,10 +0,0 @@ -namespace Utils { - - class NoCopy { - public: - NoCopy(const NoCopy&) = delete; - NoCopy& operator=(const NoCopy&) = delete; - NoCopy() = default; - }; - -} \ No newline at end of file From 69959f56e0543cd653483dca309b311aa24589e7 Mon Sep 17 00:00:00 2001 From: ShiralynDev Date: Sat, 30 May 2026 18:49:57 +0200 Subject: [PATCH 6/9] Better drawing and avoid crash on no connection to dator --- ATC_Dator/CMakeLists.txt | 6 +- ATC_Dator/src/ATCStartup/startup.cpp | 2 +- ATC_Dator/src/ATCStartup/startup.hpp | 2 +- ATC_Dator/src/Utils/utils.hpp | 2 +- ATC_Dator/src/main.cpp | 2 + .../C++/ExtendedDebugPanel/CMakeLists.txt | 10 +- ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp | 191 +++++++----------- .../UniversalFunctions/drawing/drawing.cpp | 61 ++++++ .../UniversalFunctions/drawing/drawing.hpp | 49 +++++ .../networking/networking.cpp | 15 +- .../networking/networking.hpp | 2 +- {ATC_Dator/src => ATC_Universal}/ATCData.hpp | 0 12 files changed, 206 insertions(+), 136 deletions(-) create mode 100644 ATC_Panel/C++/UniversalFunctions/drawing/drawing.cpp create mode 100644 ATC_Panel/C++/UniversalFunctions/drawing/drawing.hpp rename {ATC_Dator/src => ATC_Universal}/ATCData.hpp (100%) diff --git a/ATC_Dator/CMakeLists.txt b/ATC_Dator/CMakeLists.txt index bbe3b53..40b8b6b 100644 --- a/ATC_Dator/CMakeLists.txt +++ b/ATC_Dator/CMakeLists.txt @@ -21,12 +21,14 @@ add_subdirectory( include_directories(../extern/ShiraNet/include) file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) -file(GLOB_RECURSE UniversalFunctionsSources ${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/*.cpp) + +include_directories(${CMAKE_CURRENT_LIST_DIR}/../ATC_Universal) +file(GLOB ATCUniversalSources ${CMAKE_CURRENT_LIST_DIR}/../ATC_Universal/*.cpp) set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") # Create the executable -add_executable(ATC_Dator ${SOURCES} ${UniversalFunctionsSources}) +add_executable(ATC_Dator ${SOURCES} ${ATCUniversalSources}) target_link_libraries(ATC_Dator PRIVATE ShiraNet) target_include_directories(ATC_Dator PRIVATE diff --git a/ATC_Dator/src/ATCStartup/startup.cpp b/ATC_Dator/src/ATCStartup/startup.cpp index c67f924..c32e02a 100644 --- a/ATC_Dator/src/ATCStartup/startup.cpp +++ b/ATC_Dator/src/ATCStartup/startup.cpp @@ -1,5 +1,5 @@ #include "startup.hpp" -#include "../ATCData.hpp" +#include "ATCData.hpp" #include "../Utils/utils.hpp" #include diff --git a/ATC_Dator/src/ATCStartup/startup.hpp b/ATC_Dator/src/ATCStartup/startup.hpp index 36264be..14a6c22 100644 --- a/ATC_Dator/src/ATCStartup/startup.hpp +++ b/ATC_Dator/src/ATCStartup/startup.hpp @@ -1,6 +1,6 @@ #pragma once -#include "../ATCData.hpp" +#include "ATCData.hpp" namespace ATC { diff --git a/ATC_Dator/src/Utils/utils.hpp b/ATC_Dator/src/Utils/utils.hpp index f5d8c8c..8623088 100644 --- a/ATC_Dator/src/Utils/utils.hpp +++ b/ATC_Dator/src/Utils/utils.hpp @@ -1,6 +1,6 @@ #pragma once -#include "../ATCData.hpp" +#include "ATCData.hpp" namespace ATC { extern void turnOffAll(ATCReturnData &returnData); diff --git a/ATC_Dator/src/main.cpp b/ATC_Dator/src/main.cpp index 0b36c86..8ee4b82 100644 --- a/ATC_Dator/src/main.cpp +++ b/ATC_Dator/src/main.cpp @@ -50,8 +50,10 @@ void clientCallback(std::shared_ptr client, ShiraN std::cout << "sent message\n"; } catch (const std::exception &e) { std::cerr << "Failed to send (std): " << e.what() << std::endl; + break; } catch (...) { std::cerr << "Failed to send: unknown exception\n"; + break; } std::this_thread::sleep_for(std::chrono::milliseconds(10)); diff --git a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt index 7e88853..2733881 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt +++ b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.20) set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build) project(ATC_Panel_ExDebug) -set(CMAKE_CXX_STANDARD 20) # Use C++ 20 +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Enable Release mode @@ -40,10 +40,16 @@ file(GLOB SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) include_directories(${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/networking) file(GLOB ATCNetworkingSources ${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/networking/*.cpp) +include_directories(${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/drawing) +file(GLOB ATCDrawingSources ${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/drawing/*.cpp) + +include_directories(${CMAKE_CURRENT_LIST_DIR}/../../../ATC_Universal) +file(GLOB ATCUniversalSources ${CMAKE_CURRENT_LIST_DIR}/../../../ATC_Universal/*.cpp) + set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") # Create the executable -add_executable(ATC_Panel_ExDebug ${SOURCES} ${RAYLIB_ADDITIONS_SOURCES} ${ATCNetworkingSources}) +add_executable(ATC_Panel_ExDebug ${SOURCES} ${RAYLIB_ADDITIONS_SOURCES} ${ATCNetworkingSources} ${ATCDrawingSources} ${ATCUniversalSources}) target_link_libraries(ATC_Panel_ExDebug PRIVATE raylib ShiraNet) # Apply Release mode specific settings diff --git a/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp index b146058..827e96c 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp +++ b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp @@ -1,71 +1,35 @@ #include #include -#include #include -#include +#include +#include "ATCData.hpp" #include "networking.hpp" +#include "drawing.hpp" -ATCReturnData ATCData; +ATCReturnData ReceivedATCData; void getDataThread(ShiraNet::Sockets::TcpSocket &socket) { while (true) { // [taskig] use interval auto newData = ATCNetworking::getATCData(socket); if (newData.has_value()) { - ATCData = newData.value(); + ReceivedATCData = newData.value(); } } } int main() { - const std::string resPath = "../../../res"; // should be ./ when built for "release" or packaged, also adjust for windows, also use filesystem path for ease of use - RaylibAdditions::WindowClass window{"ATC_Panel_Extended_Debug", 1200, 500}; // read screen size from config later SetTargetFPS(60); SetWindowMonitor(0); SetExitKey(KEY_NULL); + const std::string resPath = "../../../res"; InitAudioDevice(); Sound ATC1 = LoadSound((resPath + "/f1.wav").c_str()); // Better f1 tone // 1. f1 med 2,5 kHz ± 20 %. f1 aktiveras endast vid ATC-larm (verkligt eller simulerat) och är helt oberoende av om ATC-systemets matningsdon fungerar eller inte. Ljudstyrkan hos f1 kan inte regleras. Sound ATC2 = LoadSound((resPath + "/f2.wav").c_str()); // f2 med 400 Hz ± 10 % fyrkantvåg. f2 är styrbar från datorerna under normal drift. Den aktiveras dessutom vid ATC-larm och är härvid oberoende av om ATC-systemets matningsdon fungerar eller inte. Ljudstyrkan är reglerbar med en potentiometer på panelen. - Texture2D ATCPanelTexture = LoadTexture((resPath + "/cleanATC.png").c_str()); - - Rectangle preInd = {61, 28, 59, 24}; - Rectangle mainInd = {234, 23, 75, 30}; - Rectangle startup = {0, float(ATCPanelTexture.height), 200, 50}; - RaylibAdditions::ButtonClass startupButton = {startup, "Start ATC", 20, GRAY, WHITE, WHITE, 5, 1}; - - Rectangle shunting = {17, 38, 18, 18}; - RaylibAdditions::ButtonClass shuntingButton = {shunting, "", 0, BLANK, BLANK, BLANK, 0, 1}; - Rectangle release = {333, 39, 18, 18}; - RaylibAdditions::ButtonClass releaseButton = {release, "", 0, BLANK, BLANK, BLANK, 0, 1}; - Rectangle increase = {384, 39, 18, 18}; - RaylibAdditions::ButtonClass increaseButton = {increase, "", 0, BLANK, BLANK, BLANK, 0, 1}; - Rectangle stopPassage = {484, 39, 18, 18}; - RaylibAdditions::ButtonClass stopPassageButton = {stopPassage, "", 0, BLANK, BLANK, BLANK, 0, 1}; - Rectangle dataEntry = {642, 40, 20, 20}; - RaylibAdditions::ButtonClass dataEntryButton = {dataEntry, "", 0, BLANK, BLANK, BLANK, 0, 1}; - - RaylibAdditions::SpeedometerClass speedometer = {{0, float(ATCPanelTexture.height), 300, 300}, 0, 200, 160, 380, 21, "km/h", WHITE, YELLOW}; - Rectangle speedButtonRect = {0, 300, 50, 50}; - RaylibAdditions::ButtonClass speedRemove = {speedButtonRect, "-10", 20, GRAY, WHITE, WHITE, 5, 1}; - speedButtonRect.x += 300 - 50; - RaylibAdditions::ButtonClass speedAdd = {speedButtonRect, "+10", 20, GRAY, WHITE, WHITE, 5, 1}; - Rectangle speedButtonRectSmall = {50, 300, 50, 50}; - RaylibAdditions::ButtonClass speedRemoveSmall = {speedButtonRectSmall, "-1", 20, GRAY, WHITE, WHITE, 5, 1}; - speedButtonRectSmall.x += 200 - 50; - RaylibAdditions::ButtonClass speedAddSmall = {speedButtonRectSmall, "+1", 20, GRAY, WHITE, WHITE, 5, 1}; - - RaylibAdditions::SpeedometerClass brakePressure = {{300, float(ATCPanelTexture.height), 300, 300}, 0, 10, 160, 380, 11, "kPa", WHITE, RED}; - Rectangle brakePressureButtonRect = {300, 300, 50, 50}; - RaylibAdditions::ButtonClass brakePressureRemove = {brakePressureButtonRect, "-0,5", 20, GRAY, WHITE, WHITE, 5, 1}; - brakePressureButtonRect.x += 300 - 50; - RaylibAdditions::ButtonClass brakePressureAdd = {brakePressureButtonRect, "+0,5", 20, GRAY, WHITE, WHITE, 5, 1}; - - Rectangle toggleATCRect = {0, 350, 200, 50}; - RaylibAdditions::ButtonClass toggleATCButton = {toggleATCRect, "Toggle ATC", 20, GRAY, WHITE, WHITE, 5, 1}; - + std::vector> thumbWheels = { {{691, 21}, 0}, // STH/V-MAX {{712, 21}, 0}, @@ -82,113 +46,94 @@ int main() { {{949, 21}, 0}, // procentuell överskridning / procentual override, X2000 has 30% due to boggies design and tilting }; + ATCPanelDrawing ATCDrawing; + ShiraNet::Sockets::TcpSocket socket(AF_INET); - socket.connect("localhost", 1337); + + bool connected = false; + while (connected == 0) { // this should be remade in some better form directly in shiranet + try { + socket.connect("localhost", 1337); + connected = true; + } catch (...) { + } + + BeginDrawing(); + ClearBackground(BLACK); + DrawText("Could not connect to ATC Dator", 0, 0, 50, WHITE); + EndDrawing(); + } std::thread getATCDataThread{getDataThread, std::ref(socket)}; while (!WindowShouldClose()) { - // ATC values + // update + + ATCDrawing.updateButtons(true); + + if (ATCDrawing.toggleATCButton.state == 2) { + if (ReceivedATCData.ATCStatus == 0) + ATCNetworking::toggleATCPower(1, socket); + else + ATCNetworking::toggleATCPower(0, socket); + } + + // draw + BeginDrawing(); + ClearBackground(BLACK); + + // ATC values int y = 0; int fontSize = 10; int lineHeight = 14; // slightly bigger than font size for spacing - DrawText(("ATCStatus = " + std::to_string(ATCData.ATCStatus)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("ATCStatus = " + std::to_string(ReceivedATCData.ATCStatus)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("toneF1 = " + std::to_string(ATCData.toneF1)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("toneF1 = " + std::to_string(ReceivedATCData.toneF1)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("toneF2 = " + std::to_string(ATCData.toneF2)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("toneF2 = " + std::to_string(ReceivedATCData.toneF2)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("shuntingLamp = " + std::to_string(ATCData.shuntingLamp)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("shuntingLamp = " + std::to_string(ReceivedATCData.shuntingLamp)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("ATCStatus = " + std::to_string(ATCData.ATCStatus)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("ATCStatus = " + std::to_string(ReceivedATCData.ATCStatus)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("preIndicator0 = " + std::string(1, ATCData.preIndicator0)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("preIndicator0 = " + std::string(1, ReceivedATCData.preIndicator0)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("preIndicator1 = " + std::string(1, ATCData.preIndicator1)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("preIndicator1 = " + std::string(1, ReceivedATCData.preIndicator1)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("preIndicator2 = " + std::string(1, ATCData.preIndicator2)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("preIndicator2 = " + std::string(1, ReceivedATCData.preIndicator2)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("ATCError = " + std::to_string(ATCData.ATCError)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("ATCError = " + std::to_string(ReceivedATCData.ATCError)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("BaliseError = " + std::to_string(ATCData.BaliseError)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("BaliseError = " + std::to_string(ReceivedATCData.BaliseError)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("speeding = " + std::to_string(ATCData.speeding)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("speeding = " + std::to_string(ReceivedATCData.speeding)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("mainIndicator0 = " + std::string(1, ATCData.mainIndicator0)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("mainIndicator0 = " + std::string(1, ReceivedATCData.mainIndicator0)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("mainIndicator1 = " + std::string(1, ATCData.mainIndicator1)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("mainIndicator1 = " + std::string(1, ReceivedATCData.mainIndicator1)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("mainIndicator2 = " + std::string(1, ATCData.mainIndicator2)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("mainIndicator2 = " + std::string(1, ReceivedATCData.mainIndicator2)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("releaseLamp = " + std::to_string(ATCData.releaseLamp)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("releaseLamp = " + std::to_string(ReceivedATCData.releaseLamp)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("increaseLamp = " + std::to_string(ATCData.increaseLamp)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("increaseLamp = " + std::to_string(ReceivedATCData.increaseLamp)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("dataEntryLamp = " + std::to_string(ATCData.dataEntryLamp)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("dataEntryLamp = " + std::to_string(ReceivedATCData.dataEntryLamp)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("smallError = " + std::to_string(ATCData.smallError)).c_str(), 1024, y, fontSize, WHITE); + DrawText(("smallError = " + std::to_string(ReceivedATCData.smallError)).c_str(), 1024, y, fontSize, WHITE); y += lineHeight; - DrawText(("requestedBrakePressure = " + std::to_string(ATCData.requestedBrakePressure)).c_str(), 1024, y, fontSize, WHITE); - - // update - // this button code sucks, fix it - shuntingButton.updateState(); - releaseButton.updateState(); - increaseButton.updateState(); - stopPassageButton.updateState(); - dataEntryButton.updateState(); - speedRemove.updateState(); - speedRemoveSmall.updateState(); - speedAdd.updateState(); - speedAddSmall.updateState(); - brakePressureRemove.updateState(); - brakePressureAdd.updateState(); - toggleATCButton.updateState(); - - if (toggleATCButton.state == 2) { - if (ATCData.ATCStatus == 0) - ATCNetworking::toggleATCPower(1, socket); - else - ATCNetworking::toggleATCPower(0, socket); - } - - if (speedRemove.state == 2) - speedometer.value -= 10; - if (speedRemoveSmall.state == 2) - speedometer.value -= 1; - if (speedAdd.state == 2) - speedometer.value += 10; - if (speedAddSmall.state == 2) - speedometer.value += 1; - - if (brakePressureRemove.state == 2) - brakePressure.value -= 0.5; - if (brakePressureAdd.state == 2) - brakePressure.value += 0.5; - - // draw - BeginDrawing(); - ClearBackground(BLACK); - - DrawTexture(ATCPanelTexture, 0, 0, WHITE); - speedometer.drawSpeedometer(); - brakePressure.drawSpeedometer(); - speedRemove.draw(); - speedRemoveSmall.draw(); - speedAdd.draw(); - speedAddSmall.draw(); - brakePressureRemove.draw(); - brakePressureAdd.draw(); - toggleATCButton.draw(); - - DrawText(std::string(1, ATCData.preIndicator0).c_str(), preInd.x + (preInd.width/3.0)*0, preInd.y + preInd.height/2 - 5, 10, YELLOW); - DrawText(std::string(1, ATCData.preIndicator1).c_str(), preInd.x + (preInd.width/3.0)*1, preInd.y + preInd.height/2 - 5, 10, YELLOW); - DrawText(std::string(1, ATCData.preIndicator2).c_str(), preInd.x + (preInd.width/3.0)*2, preInd.y + preInd.height/2 - 5, 10, YELLOW); - - DrawText(std::string(1, ATCData.mainIndicator0).c_str(), mainInd.x + (mainInd.width/3.0)*0, mainInd.y + mainInd.height/2 - 10, 20, GREEN); - DrawText(std::string(1, ATCData.mainIndicator1).c_str(), mainInd.x + (mainInd.width/3.0)*1, mainInd.y + mainInd.height/2 - 10, 20, GREEN); - DrawText(std::string(1, ATCData.mainIndicator2).c_str(), mainInd.x + (mainInd.width/3.0)*2, mainInd.y + mainInd.height/2 - 10, 20, GREEN); + DrawText(("requestedBrakePressure = " + std::to_string(ReceivedATCData.requestedBrakePressure)).c_str(), 1024, y, fontSize, WHITE); + ATCDrawing.drawButtons(); + char indicators[6] = { + ReceivedATCData.preIndicator0, + ReceivedATCData.preIndicator1, + ReceivedATCData.preIndicator2, + ReceivedATCData.mainIndicator0, + ReceivedATCData.mainIndicator1, + ReceivedATCData.mainIndicator2 + }; + ATCDrawing.drawIndicators(indicators); EndDrawing(); } } \ No newline at end of file diff --git a/ATC_Panel/C++/UniversalFunctions/drawing/drawing.cpp b/ATC_Panel/C++/UniversalFunctions/drawing/drawing.cpp new file mode 100644 index 0000000..ec59c0e --- /dev/null +++ b/ATC_Panel/C++/UniversalFunctions/drawing/drawing.cpp @@ -0,0 +1,61 @@ +#include "drawing.hpp" + +#include + +void ATCPanelDrawing::updateButtons(bool debugButtons) { + // this button code sucks, fix it + shuntingButton.updateState(); + releaseButton.updateState(); + increaseButton.updateState(); + stopPassageButton.updateState(); + dataEntryButton.updateState(); + + if (debugButtons) { + speedRemove.updateState(); + speedRemoveSmall.updateState(); + speedAdd.updateState(); + speedAddSmall.updateState(); + brakePressureRemove.updateState(); + brakePressureAdd.updateState(); + toggleATCButton.updateState(); + + if (speedRemove.state == 2) + speedometer.value -= 10; + if (speedRemoveSmall.state == 2) + speedometer.value -= 1; + if (speedAdd.state == 2) + speedometer.value += 10; + if (speedAddSmall.state == 2) + speedometer.value += 1; + + if (brakePressureRemove.state == 2) + brakePressure.value -= 0.5; + if (brakePressureAdd.state == 2) + brakePressure.value += 0.5; + } + +} + +void ATCPanelDrawing::drawButtons(bool debugButtons) { + DrawTexture(ATCPanelTexture, 0, 0, WHITE); + speedometer.drawSpeedometer(); + brakePressure.drawSpeedometer(); + speedRemove.draw(); + speedRemoveSmall.draw(); + speedAdd.draw(); + speedAddSmall.draw(); + brakePressureRemove.draw(); + brakePressureAdd.draw(); + toggleATCButton.draw(); +} + +void ATCPanelDrawing::drawIndicators(char indicators[6]) { + + DrawText(std::string(1, indicators[0]).c_str(), preInd.x + (preInd.width/3.0)*0, preInd.y + preInd.height/2 - 5, 10, YELLOW); + DrawText(std::string(1, indicators[1]).c_str(), preInd.x + (preInd.width/3.0)*1, preInd.y + preInd.height/2 - 5, 10, YELLOW); + DrawText(std::string(1, indicators[2]).c_str(), preInd.x + (preInd.width/3.0)*2, preInd.y + preInd.height/2 - 5, 10, YELLOW); + + DrawText(std::string(1, indicators[3]).c_str(), mainInd.x + (mainInd.width/3.0)*0, mainInd.y + mainInd.height/2 - 10, 20, GREEN); + DrawText(std::string(1, indicators[4]).c_str(), mainInd.x + (mainInd.width/3.0)*1, mainInd.y + mainInd.height/2 - 10, 20, GREEN); + DrawText(std::string(1, indicators[5]).c_str(), mainInd.x + (mainInd.width/3.0)*2, mainInd.y + mainInd.height/2 - 10, 20, GREEN); +} \ No newline at end of file diff --git a/ATC_Panel/C++/UniversalFunctions/drawing/drawing.hpp b/ATC_Panel/C++/UniversalFunctions/drawing/drawing.hpp new file mode 100644 index 0000000..5902c6f --- /dev/null +++ b/ATC_Panel/C++/UniversalFunctions/drawing/drawing.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include + +class ATCPanelDrawing { + public: + Texture2D ATCPanelTexture; + Rectangle preInd = {61, 28, 59, 24}; + Rectangle mainInd = {234, 23, 75, 30}; + Rectangle startup = {0, 64, 200, 50}; + RaylibAdditions::ButtonClass startupButton = {startup, "Start ATC", 20, GRAY, WHITE, WHITE, 5, 1}; + + Rectangle shunting = {17, 38, 18, 18}; + RaylibAdditions::ButtonClass shuntingButton = {shunting, "", 0, BLANK, BLANK, BLANK, 0, 1}; + Rectangle release = {333, 39, 18, 18}; + RaylibAdditions::ButtonClass releaseButton = {release, "", 0, BLANK, BLANK, BLANK, 0, 1}; + Rectangle increase = {384, 39, 18, 18}; + RaylibAdditions::ButtonClass increaseButton = {increase, "", 0, BLANK, BLANK, BLANK, 0, 1}; + Rectangle stopPassage = {484, 39, 18, 18}; + RaylibAdditions::ButtonClass stopPassageButton = {stopPassage, "", 0, BLANK, BLANK, BLANK, 0, 1}; + Rectangle dataEntry = {642, 40, 20, 20}; + RaylibAdditions::ButtonClass dataEntryButton = {dataEntry, "", 0, BLANK, BLANK, BLANK, 0, 1}; + + RaylibAdditions::SpeedometerClass speedometer = {{0, 64, 300, 300}, 0, 200, 160, 380, 21, "km/h", WHITE, YELLOW}; + Rectangle speedRemoveRect = {0, 300, 50, 50}; + RaylibAdditions::ButtonClass speedRemove = {speedRemoveRect, "-10", 20, GRAY, WHITE, WHITE, 5, 1}; + Rectangle speedAddRect = {250, 300, 50, 50}; + RaylibAdditions::ButtonClass speedAdd = {speedAddRect, "+10", 20, GRAY, WHITE, WHITE, 5, 1}; + Rectangle speedButtonRectSmall = {50, 300, 50, 50}; + RaylibAdditions::ButtonClass speedRemoveSmall = {speedButtonRectSmall, "-1", 20, GRAY, WHITE, WHITE, 5, 1}; + Rectangle speedAddSmallRect = {200, 300, 50, 50}; + RaylibAdditions::ButtonClass speedAddSmall = {speedAddSmallRect, "+1", 20, GRAY, WHITE, WHITE, 5, 1}; + + RaylibAdditions::SpeedometerClass brakePressure = {{300, 64, 300, 300}, 0, 10, 160, 380, 11, "kPa", WHITE, RED}; + Rectangle removeBrakePressureButtonRect = {300, 300, 50, 50}; + RaylibAdditions::ButtonClass brakePressureRemove = {removeBrakePressureButtonRect, "-0,5", 20, GRAY, WHITE, WHITE, 5, 1}; + Rectangle addBrakePressureButtonRect = {500, 300, 50, 50}; + RaylibAdditions::ButtonClass brakePressureAdd = {addBrakePressureButtonRect, "+0,5", 20, GRAY, WHITE, WHITE, 5, 1}; + + Rectangle toggleATCRect = {0, 350, 200, 50}; + RaylibAdditions::ButtonClass toggleATCButton = {toggleATCRect, "Toggle ATC", 20, GRAY, WHITE, WHITE, 5, 1}; + + ATCPanelDrawing() { ATCPanelTexture = LoadTexture("../../../res/cleanATC.png"); } // should be ./ when built for "release" or packaged, also adjust for windows, also use filesystem path for ease of use + void updateButtons(bool debugButtons = false); + void drawButtons(bool debugButtons = false); + void drawIndicators(char indicators[6]); +}; \ No newline at end of file diff --git a/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp b/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp index e087f91..774e7ab 100644 --- a/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp +++ b/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp @@ -1,6 +1,7 @@ #include "networking.hpp" #include +#include std::optional ATCNetworking::getATCData(ShiraNet::Sockets::TcpSocket &socket) { try { @@ -11,14 +12,18 @@ std::optional ATCNetworking::getATCData(ShiraNet::Sockets::TcpSoc message.payloadToDataField(data); return data.data; } catch (...) { + return std::nullopt; } - return std::nullopt; } void ATCNetworking::toggleATCPower(bool state, ShiraNet::Sockets::TcpSocket &socket) { - ShiraNet::NetworkData::DataField data; - data.data = state; + try { + ShiraNet::NetworkData::DataField data; + data.data = state; - ShiraNet::NetworkData::Message message(1, data); - socket.send(message); + ShiraNet::NetworkData::Message message(1, data); + socket.send(message); + } catch (...) { + std::cout << "Failed to send toggelATCPower message\n"; + } } \ No newline at end of file diff --git a/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp b/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp index bdf394f..6547ee1 100644 --- a/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp +++ b/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp @@ -1,6 +1,6 @@ #pragma once -#include "../../../../ATC_Dator/src/ATCData.hpp" +#include "ATCData.hpp" #include #include diff --git a/ATC_Dator/src/ATCData.hpp b/ATC_Universal/ATCData.hpp similarity index 100% rename from ATC_Dator/src/ATCData.hpp rename to ATC_Universal/ATCData.hpp From ad59eec87bc20a4b43a2ddb1213d214b435db3fe Mon Sep 17 00:00:00 2001 From: SparklesReal Date: Fri, 19 Jun 2026 15:20:45 +0200 Subject: [PATCH 7/9] Fix ShiraNet submodule --- .gitmodules | 2 +- extern/ShiraNet | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 160000 extern/ShiraNet diff --git a/.gitmodules b/.gitmodules index 2d57f82..82e2876 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,4 +6,4 @@ url = https://github.com/ShiralynDev/RaylibAdditions.git [submodule "extern/ShiraNet"] path = extern/ShiraNet - url = https://github.com/ShiralynDev/ShiraNet + url = https://github.com/ShiralynDev/ShiraNet.git diff --git a/extern/ShiraNet b/extern/ShiraNet new file mode 160000 index 0000000..1a6a5bf --- /dev/null +++ b/extern/ShiraNet @@ -0,0 +1 @@ +Subproject commit 1a6a5bffc14d6bcc9814e0350d9bc03fbd505441 From ca179948116d81b114b5dfb75dea413d7b9e5c6d Mon Sep 17 00:00:00 2001 From: SparklesReal Date: Fri, 19 Jun 2026 16:46:20 +0200 Subject: [PATCH 8/9] Better building --- ATC_Dator/CMakeLists.txt | 5 ----- .../C++/ExtendedDebugPanel/CMakeLists.txt | 13 ++----------- .../C++/UniversalFunctions/CMakeLists.txt | 19 +++++++++++++++++++ CMakeLists.txt | 11 +++++++++++ 4 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 ATC_Panel/C++/UniversalFunctions/CMakeLists.txt create mode 100644 CMakeLists.txt diff --git a/ATC_Dator/CMakeLists.txt b/ATC_Dator/CMakeLists.txt index 40b8b6b..fd8c386 100644 --- a/ATC_Dator/CMakeLists.txt +++ b/ATC_Dator/CMakeLists.txt @@ -1,5 +1,4 @@ cmake_minimum_required(VERSION 3.20) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build) project(ATC_Dator) @@ -14,10 +13,6 @@ endif() set(BUILD_SHARED_LIBS ON) set(BUILD_EXAMPLES OFF) -add_subdirectory( - ${CMAKE_CURRENT_LIST_DIR}/../extern/ShiraNet - ${CMAKE_BINARY_DIR}/ShiraNet -) include_directories(../extern/ShiraNet/include) file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) diff --git a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt index 2733881..e655f94 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt +++ b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt @@ -13,7 +13,6 @@ endif() set(BUILD_SHARED_LIBS ON) set(BUILD_EXAMPLES OFF) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Raylib set(SUPPORT_X11 ON CACHE BOOL "Use X11 for windowing" FORCE) @@ -25,10 +24,6 @@ add_subdirectory( include_directories(../../../extern/raylib/) # ShiraNet -add_subdirectory( - ${CMAKE_CURRENT_LIST_DIR}/../../../extern/ShiraNet - ${CMAKE_BINARY_DIR}/ShiraNet -) include_directories(../../../extern/ShiraNet/include) # RaylibAdditions @@ -37,11 +32,7 @@ file(GLOB RAYLIB_ADDITIONS_SOURCES ../../../extern/RaylibAdditions/*.cpp) file(GLOB SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) -include_directories(${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/networking) -file(GLOB ATCNetworkingSources ${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/networking/*.cpp) - -include_directories(${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/drawing) -file(GLOB ATCDrawingSources ${CMAKE_CURRENT_LIST_DIR}/../UniversalFunctions/drawing/*.cpp) +add_subdirectory(../UniversalFunctions UniversalFunctionsBuild) include_directories(${CMAKE_CURRENT_LIST_DIR}/../../../ATC_Universal) file(GLOB ATCUniversalSources ${CMAKE_CURRENT_LIST_DIR}/../../../ATC_Universal/*.cpp) @@ -50,7 +41,7 @@ set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") # Create the executable add_executable(ATC_Panel_ExDebug ${SOURCES} ${RAYLIB_ADDITIONS_SOURCES} ${ATCNetworkingSources} ${ATCDrawingSources} ${ATCUniversalSources}) -target_link_libraries(ATC_Panel_ExDebug PRIVATE raylib ShiraNet) +target_link_libraries(ATC_Panel_ExDebug PRIVATE raylib ShiraNet ATCUniversalFunctions) # Apply Release mode specific settings if(CMAKE_BUILD_TYPE STREQUAL "Release") diff --git a/ATC_Panel/C++/UniversalFunctions/CMakeLists.txt b/ATC_Panel/C++/UniversalFunctions/CMakeLists.txt new file mode 100644 index 0000000..dd08257 --- /dev/null +++ b/ATC_Panel/C++/UniversalFunctions/CMakeLists.txt @@ -0,0 +1,19 @@ +file(GLOB NETWORKING_SOURCES networking/*.cpp) +file(GLOB DRAWING_SOURCES drawing/*.cpp) + +include_directories(${CMAKE_CURRENT_LIST_DIR}/../../../ATC_Universal) +file(GLOB ATCUniversalSources ${CMAKE_CURRENT_LIST_DIR}/../../../ATC_Universal/*.cpp) + +add_library(ATCUniversalFunctions STATIC + ${NETWORKING_SOURCES} + ${DRAWING_SOURCES} +) + +target_include_directories(ATCUniversalFunctions PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/networking + ${CMAKE_CURRENT_SOURCE_DIR}/drawing +) + +target_link_libraries(ATCUniversalFunctions PUBLIC + ShiraNet +) \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8c150e2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.20) +project(ATC) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +add_subdirectory(extern/ShiraNet) + +add_subdirectory(ATC_Dator) +#add_subdirectory(ATC_Panel/C++/DebugPanel) +add_subdirectory(ATC_Panel/C++/ExtendedDebugPanel) +#add_subdirectory(ATC_Panel/C++/SimplePanel) \ No newline at end of file From 3fd1c880abd017472f4622f415ab21a29052ad12 Mon Sep 17 00:00:00 2001 From: SparklesReal Date: Fri, 19 Jun 2026 17:27:08 +0200 Subject: [PATCH 9/9] ATC error on wrong cab --- ATC_Dator/src/ATCStartup/startup.cpp | 10 +++++-- ATC_Dator/src/ATCStartup/startup.hpp | 2 +- ATC_Dator/src/main.cpp | 27 +++++++++++++++---- .../C++/ExtendedDebugPanel/CMakeLists.txt | 9 +++++++ ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp | 11 +++++--- .../UniversalFunctions/drawing/drawing.hpp | 2 +- .../networking/networking.cpp | 13 +++++++++ .../networking/networking.hpp | 1 + ATC_Universal/ATCData.hpp | 1 + extern/ShiraNet | 2 +- 10 files changed, 65 insertions(+), 13 deletions(-) diff --git a/ATC_Dator/src/ATCStartup/startup.cpp b/ATC_Dator/src/ATCStartup/startup.cpp index c32e02a..a954a72 100644 --- a/ATC_Dator/src/ATCStartup/startup.cpp +++ b/ATC_Dator/src/ATCStartup/startup.cpp @@ -12,11 +12,10 @@ bool floatCompare(float a, float b) { return false; } -void ATC::startupSequence(ATCData &data, internalATCData &internalData, ATCReturnData &returnData) { // Rewrite for better "stages" system and better times aswell as use the brake during startup +void ATC::startupSequence(ATCData &data, internalATCData &internalData, ATCReturnData &returnData, bool isCabA) { // Rewrite for better "stages" system and better times aswell as use the brake during startup // https://bransch.trafikverket.se/contentassets/438381cb6c794b85a28d090b0c280b70/handbok--trvinfra-90001-v1_0.pdf // Page 18 for error codes /* To be added: - Preind 01 MainInd 0 2 cabs activated Preind 02 MainInd 0 No contact with the panel Preind 03 MainInd 0 No contact with the "manöverenheten" @@ -61,6 +60,13 @@ void ATC::startupSequence(ATCData &data, internalATCData &internalData, ATCRetur 44 0 Button Release pressed */ + if (isCabA != internalData.isCabA) { + returnData.preIndicator1 = '0'; + returnData.preIndicator2 = '1'; + returnData.mainIndicator1 = '0'; + return; + } + returnData.ATCStatus = 1; // I hate this timebased system diff --git a/ATC_Dator/src/ATCStartup/startup.hpp b/ATC_Dator/src/ATCStartup/startup.hpp index 14a6c22..cb099c2 100644 --- a/ATC_Dator/src/ATCStartup/startup.hpp +++ b/ATC_Dator/src/ATCStartup/startup.hpp @@ -9,6 +9,6 @@ extern int ms; extern void errors(ATCData &data, internalATCData &internalData, ATCReturnData &returnData); } // namespace Startup -extern void startupSequence(ATCData &data, internalATCData &internalData, ATCReturnData &returnData); +extern void startupSequence(ATCData &data, internalATCData &internalData, ATCReturnData &returnData, bool isCabA); } // namespace ATC \ No newline at end of file diff --git a/ATC_Dator/src/main.cpp b/ATC_Dator/src/main.cpp index 8ee4b82..8f89122 100644 --- a/ATC_Dator/src/main.cpp +++ b/ATC_Dator/src/main.cpp @@ -1,12 +1,15 @@ #include +#include #include #include #include +#include #include "ATCStartup/startup.hpp" struct ClientData { bool power = false; + bool isCabA = true; }; ClientData clientData; @@ -18,7 +21,14 @@ void togglePowerMessage(ShiraNet::NetworkData::Message &message) { message.payloadToDataField(data); clientData.power = data.data; - std::cout << "power is now: " << std::to_string(data.data) << std::endl; +} + +void togglePowerMessageWithCabID(ShiraNet::NetworkData::Message &message) { + ShiraNet::NetworkData::DataField> data; + message.payloadToDataField(data); + + clientData.power = data.data.at(0); + clientData.isCabA = data.data.at(1); } void handleMessage(ShiraNet::NetworkData::Message &message) { @@ -30,6 +40,10 @@ void handleMessage(ShiraNet::NetworkData::Message &message) { togglePowerMessage(message); break; + case 2: + togglePowerMessageWithCabID(message); + break; + default: break; } @@ -47,7 +61,6 @@ void clientCallback(std::shared_ptr client, ShiraN ShiraNet::NetworkData::DataField ATCDataField{sizeof(ATCReturnData), atcReturn}; ShiraNet::NetworkData::Message ATCDataMessage(0, ATCDataField); client->send(ATCDataMessage); - std::cout << "sent message\n"; } catch (const std::exception &e) { std::cerr << "Failed to send (std): " << e.what() << std::endl; break; @@ -66,17 +79,21 @@ void server(ShiraNet::Servers::TcpServer *server) { } } -int main() { +int main(int argc, char *argv[]) { + internalATCData atcInternal; + + if (argc == 2 && strcmp(argv[1], "B")) + atcInternal.isCabA = false; + ShiraNet::Servers::TcpServer ATCServer(AF_INET, 1337, 10); std::thread serverThread(server, &ATCServer); ATCData atcData; - internalATCData atcInternal; while (true) { if (clientData.power || atcInternal.startup == 1) { clientData.power = false; - ATC::startupSequence(atcData, atcInternal, atcReturn); + ATC::startupSequence(atcData, atcInternal, atcReturn, clientData.isCabA); } } } \ No newline at end of file diff --git a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt index e655f94..8c0178b 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt +++ b/ATC_Panel/C++/ExtendedDebugPanel/CMakeLists.txt @@ -43,6 +43,15 @@ set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") add_executable(ATC_Panel_ExDebug ${SOURCES} ${RAYLIB_ADDITIONS_SOURCES} ${ATCNetworkingSources} ${ATCDrawingSources} ${ATCUniversalSources}) target_link_libraries(ATC_Panel_ExDebug PRIVATE raylib ShiraNet ATCUniversalFunctions) +add_custom_command(TARGET ATC_Panel_ExDebug POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + $/res + + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_SOURCE_DIR}/../../res + $/res +) + # Apply Release mode specific settings if(CMAKE_BUILD_TYPE STREQUAL "Release") # Add optimization flags diff --git a/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp index 827e96c..30d1e16 100644 --- a/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp +++ b/ATC_Panel/C++/ExtendedDebugPanel/src/main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -18,14 +19,18 @@ void getDataThread(ShiraNet::Sockets::TcpSocket &socket) { } } -int main() { +int main(int argc, char *argv[]) { + bool isCabA = true; + if (argc == 2 && strcmp(argv[1], "B")) + isCabA = false; + RaylibAdditions::WindowClass window{"ATC_Panel_Extended_Debug", 1200, 500}; // read screen size from config later SetTargetFPS(60); SetWindowMonitor(0); SetExitKey(KEY_NULL); - const std::string resPath = "../../../res"; + const std::string resPath = "./res"; InitAudioDevice(); Sound ATC1 = LoadSound((resPath + "/f1.wav").c_str()); // Better f1 tone // 1. f1 med 2,5 kHz ± 20 %. f1 aktiveras endast vid ATC-larm (verkligt eller simulerat) och är helt oberoende av om ATC-systemets matningsdon fungerar eller inte. Ljudstyrkan hos f1 kan inte regleras. Sound ATC2 = LoadSound((resPath + "/f2.wav").c_str()); // f2 med 400 Hz ± 10 % fyrkantvåg. f2 är styrbar från datorerna under normal drift. Den aktiveras dessutom vid ATC-larm och är härvid oberoende av om ATC-systemets matningsdon fungerar eller inte. Ljudstyrkan är reglerbar med en potentiometer på panelen. @@ -82,7 +87,7 @@ int main() { BeginDrawing(); ClearBackground(BLACK); - // ATC values + // ATC values int y = 0; int fontSize = 10; int lineHeight = 14; // slightly bigger than font size for spacing diff --git a/ATC_Panel/C++/UniversalFunctions/drawing/drawing.hpp b/ATC_Panel/C++/UniversalFunctions/drawing/drawing.hpp index 5902c6f..4374d89 100644 --- a/ATC_Panel/C++/UniversalFunctions/drawing/drawing.hpp +++ b/ATC_Panel/C++/UniversalFunctions/drawing/drawing.hpp @@ -42,7 +42,7 @@ class ATCPanelDrawing { Rectangle toggleATCRect = {0, 350, 200, 50}; RaylibAdditions::ButtonClass toggleATCButton = {toggleATCRect, "Toggle ATC", 20, GRAY, WHITE, WHITE, 5, 1}; - ATCPanelDrawing() { ATCPanelTexture = LoadTexture("../../../res/cleanATC.png"); } // should be ./ when built for "release" or packaged, also adjust for windows, also use filesystem path for ease of use + ATCPanelDrawing() { ATCPanelTexture = LoadTexture("./res/cleanATC.png"); } // should be ./ when built for "release" or packaged, also adjust for windows, also use filesystem path for ease of use void updateButtons(bool debugButtons = false); void drawButtons(bool debugButtons = false); void drawIndicators(char indicators[6]); diff --git a/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp b/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp index 774e7ab..8b47eae 100644 --- a/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp +++ b/ATC_Panel/C++/UniversalFunctions/networking/networking.cpp @@ -26,4 +26,17 @@ void ATCNetworking::toggleATCPower(bool state, ShiraNet::Sockets::TcpSocket &soc } catch (...) { std::cout << "Failed to send toggelATCPower message\n"; } +} + +void ATCNetworking::toggleATCPower(bool state, bool isCabA, ShiraNet::Sockets::TcpSocket &socket) { + try { + ShiraNet::NetworkData::DataField> data; + data.data.push_back(state); + data.data.push_back(isCabA); + + ShiraNet::NetworkData::Message message(2, data); + socket.send(message); + } catch (...) { + std::cout << "Failed to send toggelATCPower message\n"; + } } \ No newline at end of file diff --git a/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp b/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp index 6547ee1..c2f433b 100644 --- a/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp +++ b/ATC_Panel/C++/UniversalFunctions/networking/networking.hpp @@ -9,5 +9,6 @@ namespace ATCNetworking { std::optional getATCData(ShiraNet::Sockets::TcpSocket &socket); void toggleATCPower(bool state, ShiraNet::Sockets::TcpSocket &socket); +void toggleATCPower(bool state, bool isCabA, ShiraNet::Sockets::TcpSocket &socket); } \ No newline at end of file diff --git a/ATC_Universal/ATCData.hpp b/ATC_Universal/ATCData.hpp index 8e24d14..613e6a0 100644 --- a/ATC_Universal/ATCData.hpp +++ b/ATC_Universal/ATCData.hpp @@ -3,6 +3,7 @@ #include struct internalATCData { + bool isCabA = true; int startup = 0; // 0 = off, 1 = startup, 2 = running/data input, 3 = running, data inputed bool dataEntryButtonPressed = false; bool ABBVersion = false; // SRT/ATSS/Ansaldo on false, ABB on true diff --git a/extern/ShiraNet b/extern/ShiraNet index 1a6a5bf..d95d8ec 160000 --- a/extern/ShiraNet +++ b/extern/ShiraNet @@ -1 +1 @@ -Subproject commit 1a6a5bffc14d6bcc9814e0350d9bc03fbd505441 +Subproject commit d95d8ec4ab36f84028a429924796d3c791949e94