commit 2fa9c1d00de23181085d1d51addb327a83789f51 Author: BordedDev <> Date: Wed Jul 9 03:16:40 2025 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de5e211 --- /dev/null +++ b/.gitignore @@ -0,0 +1,84 @@ +*.d +*.slo +*.lo +*.o +*.obj +*.gch +*.pch +*.so +*.dylib +*.dll +*.mod +*.smod +*.lai +*.la +*.a +*.lib +*.exe +*.out +*.app +vcpkg-manifest-install.log +vcpkg_installed/ +.idea/ +.vscode/ +cmake-build-*/ +.idea/**/mongoSettings.xml +*.iws +out/ +.idea_modules/ +atlassian-ide-plugin.xml +.idea/replstate.xml +.idea/sonarlint/ +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +.idea/httpRequests +.idea/caches/build_file_checksums.ser +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps +CMakeUserPresets.json +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.cab +*.msi +*.msix +*.msm +*.msp +*.lnk +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b808a8d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,70 @@ +cmake_minimum_required(VERSION 4.0) +project(example_project VERSION 1.0 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 26) +set(VCPKG_TARGET_ARCHITECTURE wasm32) +set(VCPKG_TARGET_TRIPLET wasm32-emscripten) +set(CMAKE_EXECUTABLE_SUFFIX ".html") + +if (MSVC) + add_compile_options(/W4) + add_compile_options(/WX) + add_compile_options(/external:anglebrackets) + add_compile_options(/external:W0) + add_compile_options(/wd4100) + add_compile_options(/wd5050) + add_definitions(-DWIN32_LEAN_AND_MEAN -DVC_EXTRALEAN) + add_compile_definitions(WIN32_LEAN_AND_MEAN NOMINMAX) +else () + add_compile_options(-Wall) + add_compile_options(-Wextra) + add_compile_options(-Wpedantic) + add_compile_options(-Werror) +endif () + +if (DEFINED VCPKG_INSTALLED_DIR) +elseif (DEFINED ENV{VCPKG_ROOT}) + include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake) +else () + message(FATAL_ERROR "VCPKG is not loaded, set VCPKG_ROOT to automatically load it or specify the cmake toolchain") +endif () + +set(${PROJECT_NAME}_src src/main.cpp) +add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_src}) + +# Configure Emscripten to preload the data folder +if(EMSCRIPTEN) + # Check if data folder exists and has content before preloading + file(GLOB_RECURSE DATA_FILES "${CMAKE_SOURCE_DIR}/data/*") + set_target_properties(${PROJECT_NAME} PROPERTIES + LINK_FLAGS "--preload-file ${CMAKE_SOURCE_DIR}/data@/" + SUFFIX ".html" + ) + if(DATA_FILES) + message(STATUS "Preloading data folder with ${CMAKE_SOURCE_DIR}/data") + else() + message(STATUS "Data folder is empty ${CMAKE_SOURCE_DIR}/data") + endif() +endif() + +find_package(SDL3 CONFIG REQUIRED) +target_link_libraries(${PROJECT_NAME} PRIVATE SDL3::SDL3) + +find_package(Catch2 CONFIG 3 REQUIRED) + +file(GLOB_RECURSE tests_${PROJECT_NAME}_src CONFIGURE_DEPENDS tests/*.cppm tests/*/*.cppm) + +add_executable(tests_${PROJECT_NAME} ${tests_${PROJECT_NAME}_src}) +target_link_libraries(tests_${PROJECT_NAME} PRIVATE Catch2::Catch2 Catch2::Catch2WithMain SDL3::SDL3) + +include(CTest) +include(Catch) +catch_discover_tests(tests_${PROJECT_NAME}) +enable_testing() + +add_custom_target(serve + COMMAND python3 ${CMAKE_SOURCE_DIR}/serve.py 5245 + WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + COMMENT "Serving WebAssembly files at http://localhost:5245" + USES_TERMINAL +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..1229338 --- /dev/null +++ b/README.md @@ -0,0 +1,163 @@ +# Example project - CMake Emscripten Project Template + +A cross-platform C++ project template using CMake and Emscripten for building native desktop applications and WebAssembly applications that run in web browsers. + +## Features + +- **Cross-platform**: Builds for both native platforms (Linux, Windows, macOS) and WebAssembly +- **Modern C++**: Uses C++26 standard +- **SDL3**: Graphics and multimedia library for cross-platform development +- **vcpkg**: Package manager for C++ dependencies +- **Emscripten**: Compile C++ to WebAssembly for web deployment +- **Testing**: Integrated with Catch2 testing framework +- **Asset Pipeline**: Automatic data folder preloading for web builds + +## Prerequisites + +### Required Tools +- **CMake** (version 4.0 or higher) +- **vcpkg** package manager +- **Emscripten SDK** (for WebAssembly builds) +- **C++ Compiler** supporting C++26: + - GCC 14+ or Clang 18+ (Linux/macOS) + - MSVC 2022 (Windows) + +### Setup vcpkg +```bash +git clone https://github.com/Microsoft/vcpkg.git +cd vcpkg +./bootstrap-vcpkg.sh # On Windows: .\bootstrap-vcpkg.bat +``` + +### Setup Emscripten +```bash +git clone https://github.com/emscripten-core/emsdk.git +cd emsdk +./emsdk install latest +./emsdk activate latest +source ./emsdk_env.sh # On Windows: emsdk_env.bat +``` + +## Project Structure + +``` +manater/ +├── CMakeLists.txt # Main CMake configuration +├── vcpkg.json # Package dependencies +├── serve.py # Development web server +├── src/ # Source code +│ ├── main.cpp # Application entry point +│ └── util/ # Utility modules +├── data/ # Game assets (preloaded in web builds) +│ └── test.txt # Example data file +├── tests/ # Unit tests +└── cmake-build-debug/ # Build output directory +``` + +## Building + +### Native Build (Desktop) +```bash +# Configure with vcpkg +cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=[path-to-vcpkg]/scripts/buildsystems/vcpkg.cmake + +# Build +cmake --build build + +# Run +./build/manater +``` + +### WebAssembly Build +```bash +# Configure with Emscripten toolchain +emcmake cmake -B build-web -S . -DCMAKE_TOOLCHAIN_FILE=[path-to-vcpkg]/scripts/buildsystems/vcpkg.cmake + +# Build +cmake --build build-web + +# Serve locally +cd build-web +python3 ../serve.py +``` + +Then open your browser to `http://localhost:8000` + +## Development + +### Adding Dependencies +Add new dependencies to `vcpkg.json`: +```json +{ + "dependencies": [ + "sdl3", + "catch2", + "your-new-dependency" + ] +} +``` + +### Asset Management +- Place game assets in the `data/` folder +- Files in `data/` are automatically preloaded in WebAssembly builds +- Access files using relative paths from the root (e.g., `"test.txt"`) + +### Testing +```bash +# Build and run tests +cmake --build build --target tests_manater +./build/tests_manater +``` + +## Configuration + +### Compiler Flags +The project is configured with strict warning levels: +- **MSVC**: `/W4 /WX` (treat warnings as errors) +- **GCC/Clang**: `-Wall -Wextra -Wpedantic -Werror` + +### Emscripten Settings +- Output format: HTML with embedded JavaScript and WebAssembly +- Data preloading: Automatically includes `data/` folder +- SDL3 integration: Configured for web compatibility + +## Customization + +### Project Name +1. Update the `project()` name in `CMakeLists.txt` +2. Update the `name` field in `vcpkg.json` +3. Rename the project folder if desired + +### Adding Source Files +Add new source files to the `${PROJECT_NAME}_src` variable in `CMakeLists.txt`: +```cmake +set(${PROJECT_NAME}_src + src/main.cpp + src/your_new_file.cpp + src/util/helper.cpp +) +``` + +## Troubleshooting + +### Common Issues + +**vcpkg not found**: Set the `VCPKG_ROOT` environment variable or specify the toolchain file manually. + +**Emscripten build fails**: Ensure the Emscripten SDK is properly activated in your shell. + +**SDL3 linking errors**: Make sure vcpkg has installed SDL3 for your target platform. + +### Web Deployment +For production deployment: +1. Build with release configuration: `-DCMAKE_BUILD_TYPE=Release` +2. Copy the generated `.html`, `.js`, `.wasm`, and `.data` files to your web server +3. Ensure proper MIME types are configured for `.wasm` files + +## License + +This template is provided as-is for educational and development purposes. + +## Contributing + +This is a template project. Fork and modify as needed for your specific use case. diff --git a/data/test.txt b/data/test.txt new file mode 100644 index 0000000..cf408de --- /dev/null +++ b/data/test.txt @@ -0,0 +1,4 @@ +Hello from preloaded data! +This file will be automatically embedded into your WebAssembly build. +You can access it from your C++ code using standard file operations. + diff --git a/serve.py b/serve.py new file mode 100644 index 0000000..102e5c7 --- /dev/null +++ b/serve.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +import http.server +import socketserver +import os +import sys +from urllib.parse import unquote + +class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler): + def do_GET(self): + # If requesting root path, serve the project HTML file + if self.path == '/' or self.path == '': + # Find the project HTML file (assumes pattern: projectname.html) + html_files = [f for f in os.listdir('.') if f.endswith('.html') and not f.startswith('index')] + if html_files: + self.path = '/' + html_files[0] + else: + # Fallback to index.html if it exists + self.path = '/index.html' + + return super().do_GET() + +if __name__ == "__main__": + port = int(sys.argv[1]) if len(sys.argv) > 1 else 5245 + + with socketserver.TCPServer(("", port), CustomHTTPRequestHandler) as httpd: + print(f"Starting HTTP server at http://localhost:{port}") + print(f"Serving directory: {os.getcwd()}") + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("\nServer stopped.") diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d626db5 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,64 @@ + +#define SDL_MAIN_USE_CALLBACKS +#include +#include +#include +#include + + +SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { + // Example initialization code + if (appstate) { + *appstate = nullptr; // Initialize app state pointer + } + + std::println("SDL App Initializing with:"); + for (int i = 0; i < argc; ++i) { + std::println(" Argument {}: {}", i, argv[i]); + } + std::ifstream file("test.txt"); + if (file.is_open()) { + std::string content; + std::getline(file, content); + std::cout << "Loaded data: " << content << std::endl; + } + // Perform any necessary setup here + // ... + + // Return SDL_APP_CONTINUE to proceed with the app's main loop + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void* appstate) { + // Example iteration code + // std::println("SDL App Iteration"); + (void) appstate; + + // Perform any necessary per-iteration tasks here + // ... + + // Return SDL_APP_CONTINUE to keep the app running + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { + // Example event handling code + std::println("SDL App Event Handling"); + (void) appstate; + (void) event; + // Handle the event here + // ... + + // Return SDL_APP_CONTINUE to keep the app running + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void* appstate, SDL_AppResult result) { + // Example cleanup code + std::println("SDL App Cleanup"); + (void) appstate; + (void) result; + // Perform any necessary cleanup here + // ... + +} \ No newline at end of file diff --git a/tests/empty.cppm b/tests/empty.cppm new file mode 100644 index 0000000..748d6c3 --- /dev/null +++ b/tests/empty.cppm @@ -0,0 +1,3 @@ +// +// Created by dark_eye on 09/07/2025. +// \ No newline at end of file diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000..37f2daa --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,8 @@ +{ + "name": "manaterra", + "version": "0.1.0", + "dependencies": [ + "sdl3", + "catch2" + ] +}