Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

74 changes: 74 additions & 0 deletions mods/CrossPlatform/OnlineCTR/Network_PC/Client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
cmake_minimum_required(VERSION 3.20)
project(OnlineCTR-Client CXX C)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 99)

# Include directories
include_directories(${PROJECT_SOURCE_DIR}/../../../../../externals/enet/include)

# ENet source files (compile from source since submodule may not have a pre-built lib)
set(ENET_DIR ${PROJECT_SOURCE_DIR}/../../../../../externals/enet)
set(ENET_SOURCES
${ENET_DIR}/callbacks.c
${ENET_DIR}/compress.c
${ENET_DIR}/host.c
${ENET_DIR}/list.c
${ENET_DIR}/packet.c
${ENET_DIR}/peer.c
${ENET_DIR}/protocol.c
)

# Platform-specific enet sources
if(WIN32)
list(APPEND ENET_SOURCES ${ENET_DIR}/win32.c)
else()
list(APPEND ENET_SOURCES ${ENET_DIR}/unix.c)
endif()

# Client source
set(SOURCES CL_main.cpp)

# Create the executable
add_executable(ctr_client ${SOURCES} ${ENET_SOURCES})

# Preprocessor definitions
if(WIN32)
target_compile_definitions(ctr_client PRIVATE __WINDOWS__ _WINSOCK_DEPRECATED_NO_WARNINGS)
target_link_libraries(ctr_client winmm ws2_32 psapi)
else()
target_compile_definitions(ctr_client PRIVATE __LINUX__)
target_link_libraries(ctr_client pthread)
endif()

# Common definitions
target_compile_definitions(ctr_client PRIVATE WINDOWS_INCLUDE)
# Fix: global.h maps STATIC_ASSERT2 -> _Static_assert under __GNUC__,
# but _Static_assert is C-only. Map it to C++ static_assert.
target_compile_definitions(ctr_client PRIVATE "_Static_assert=static_assert")

# Compiler options
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(ctr_client PRIVATE
-Wno-int-conversion
-Wno-incompatible-function-pointer-types
-Wno-implicit-function-declaration
-Wno-return-type
-Wno-writable-strings
-Wno-bitfield-constant-conversion
)
else()
# Assume GCC
target_compile_options(ctr_client PRIVATE
-Wno-write-strings
-Wno-narrowing
-fpermissive
)
endif()

# Debug options
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(ctr_client PRIVATE -g -gdwarf-2 -O0)
else()
target_compile_options(ctr_client PRIVATE -O2)
endif()
53 changes: 53 additions & 0 deletions mods/CrossPlatform/OnlineCTR/Network_PC/README-Linux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# OnlineCTR Network_PC - Linux Port

This folder contains the Client and Server applications for OnlineCTR, which originally were developed strictly for Windows using Windows-specific APIs (`windows.h`, `psapi.lib`, `EnumProcessModules`, etc.).

This repository has been ported to support **Linux natively** via CMake and POSIX APIs.

## What was changed

1. **Process Detection**: The original code used Win32 `EnumProcesses` to find the DuckStation emulator. In Linux, it now parses the `/proc/` filesystem to look for the emulator by checking `comm` and `cmdline` to properly support native DuckStation installations and AppImages.
2. **Shared Memory Mapping**: The emulator memory is read/written to sync data. Replaced `MapViewOfFile` with POSIX `shm_open` and `mmap` to read the shared memory space `duckstation_<PID>` exported by DuckStation.
3. **Cross-Platform Compatibility**: Replaced Windows-only functions with portable macros or implementations:
- `strcpy_s` -> `STRCPY_SAFE`
- `sprintf_s` -> `SPRINTF_SAFE`
- `system("cls")` -> `system("clear")`
- Custom `Sleep`/`usleep` wrappers
- Proper `_Static_assert` mapping for C++ compilers (`g++`/`clang++`).
4. **Build System**: Added `CMakeLists.txt` for the Client and updated the Server's `CMakeLists.txt` to compile ENet directly from the submodules, preventing linker errors from missing pre-compiled ENet libraries.

## How to build on Linux

Make sure you have `cmake`, `make` (or `ninja`), and a C/C++ compiler installed (`gcc`/`g++`).
Also ensure that the ENet submodule is populated (`git submodule update --init --recursive`).

### Compiling the Client

```bash
cd mods/Windows/OnlineCTR/Network_PC/Client
mkdir build && cd build
cmake ..
cmake --build .
```
This will produce the executable `ctr_client`.

### Compiling the Server

```bash
cd mods/Windows/OnlineCTR/Network_PC/Server
mkdir build && cd build
cmake ..
cmake --build .
```
This will produce the executable `ctr_srv`.

## Running the Client

1. Open DuckStation and ensure **Enable Shared Memory** (PINE) is checked in the Advanced or Developer settings. Also make sure the **8MB RAM** (Console RAM Size) option is enabled!
2. Launch your patched Crash Team Racing game.
3. Open a terminal and run the Client:
```bash
./ctr_client <YourUsername>
```
4. If it detects multiple DuckStation instances (e.g., when running an AppImage), it will ask for the PID. Look at the DuckStation console logs to find the exact Shared Memory PID, and enter it.
5. Select a server (or run your own `ctr_srv` locally and choose "Private Server" with IP `127.0.0.1`).
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,30 @@ set(CMAKE_C_STANDARD 99)
# Include directories
include_directories(${PROJECT_SOURCE_DIR}/../../../../../externals/enet/include)

# Add the path to the enet library
link_directories(${PROJECT_SOURCE_DIR}/../../../../../externals/enet/lib)
# Add enet sources directly
set(ENET_DIR ${PROJECT_SOURCE_DIR}/../../../../../externals/enet)
set(ENET_SOURCES
${ENET_DIR}/callbacks.c
${ENET_DIR}/compress.c
${ENET_DIR}/host.c
${ENET_DIR}/list.c
${ENET_DIR}/packet.c
${ENET_DIR}/peer.c
${ENET_DIR}/protocol.c
${ENET_DIR}/unix.c
)

# Source files
set(SOURCES SV_main.c SV_helper.c)
set(SOURCES SV_main.c SV_helper.c ${ENET_SOURCES})

# Create the executable
add_executable(ctr_srv ${SOURCES})

# Link with the enet library
if (WIN32)
target_link_libraries(ctr_srv enet winmm ws2_32)
target_link_libraries(ctr_srv winmm ws2_32)
else()
target_link_libraries(ctr_srv enet)
target_link_libraries(ctr_srv pthread)
endif()

# Compiler options
Expand Down