diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0803688 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# Заставляем IDE сохранять файлы в кодировке UTF-8 +# https://editorconfig.org + +# В родительских папках .editorconfig искаться не будет +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 + +# Не меняем формат разделителя строк. Может возникнуть конфликт с настройками git +#end_of_line = lf diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9a1189b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +# Автоматически нормализуем концы строк, если у пользователя не настроен параметр autocrlf +# https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings +# https://www.aleksandrhovhannisyan.com/blog/crlf-vs-lf-normalizing-line-endings-in-git/ +* text=auto + +# Батники с юниксовыми концами строк глючат +*.bat text eol=crlf +*.cmd text eol=crlf diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..49df97e --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,140 @@ +name: CI/CD + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + linux: + runs-on: ubuntu-24.04 + + strategy: + fail-fast: false + matrix: + compiler: + - { + id: gcc, + c: gcc-13, + cxx: g++-13, + } + - { + id: clang, + c: clang-16, + cxx: clang++-16, + } + build_type: [debug, release] + + name: 🐧-${{ matrix.compiler.id }}-${{ matrix.build_type }} + + steps: + - name: Устанавливаем зависимости + run: | + sudo apt update + sudo apt install libgl1-mesa-dev libxrandr-dev + + - name: Скачиваем репозиторий + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + path: repo + + - name: Генерируем проекты + run: | + cmake repo -B build -G "Unix Makefiles" \ + -D CMAKE_C_COMPILER=${{ matrix.compiler.c }} -D CMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} \ + -D CMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -D DV_ALL_WARNINGS=1 -D DV_CTEST=1 + + - name: Компилируем + run: | + cmake --build build + + - name: CTest + run: | + xvfb-run ctest --verbose --test-dir build --timeout 60 + + windows: + runs-on: windows-latest + + strategy: + fail-fast: false + matrix: + compiler: [vs, mingw] + build_type: [debug, release] + + name: 🔲-${{ matrix.compiler }}-${{ matrix.build_type }} + + steps: + - name: Устанавливаем MinGW + if: matrix.compiler == 'mingw' + uses: msys2/setup-msys2@v2 + with: + update: true + install: mingw-w64-x86_64-toolchain + + - name: Добавляем в PATH путь к MinGW + if: matrix.compiler == 'mingw' + shell: bash + run: echo "${RUNNER_TEMP}/msys64/mingw64/bin" >> $GITHUB_PATH + + - name: Скачиваем репозиторий + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + path: repo + + - name: Генерируем проекты + shell: bash + run: | + args=(repo -B build) + + if [ "${{ matrix.compiler }}" == "vs" ] + then + args+=(-G "Visual Studio 17 2022") + else + args+=(-G "MinGW Makefiles") + args+=(-D CMAKE_BUILD_TYPE=${{ matrix.build_type }}) + fi + + args+=(-D DV_ALL_WARNINGS=1 -D DV_CTEST=1) + + cmake "${args[@]}" + + - name: Компилируем + shell: bash + run: | + args=(--build build) + + if [ "${{ matrix.compiler }}" == "vs" ] + then + args+=(--config ${{ matrix.build_type }}) + fi + + cmake "${args[@]}" + + - name: Качаем Mesa + shell: bash + run: | + curl.exe --location --output mesa.7z --url https://github.com/pal1000/mesa-dist-win/releases/download/22.2.3/mesa3d-22.2.3-release-msvc.7z + 7z x mesa.7z -omesa + rm mesa.7z + + mv mesa/x64/libgallium_wgl.dll build/result + mv mesa/x64/libglapi.dll build/result + mv mesa/x64/opengl32.dll build/result + + - name: CTest + shell: bash + run: | + args=(--verbose --test-dir build --timeout 60) + + if [ "${{ matrix.compiler }}" == "vs" ] + then + args+=(-C ${{ matrix.build_type }}) + fi + + export LIBGL_ALWAYS_SOFTWARE=true + ctest "${args[@]}" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..55086dc --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# https://git-scm.com/docs/gitignore +# https://www.atlassian.com/ru/git/tutorials/saving-changes/gitignore + +# Игнорируем папки, которые создаёт VS Code +/.vscode/ +/build/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a15ad1b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "libs/dviglo2d"] + path = libs/dviglo2d + url = https://github.com/dviglo2d/dviglo2d +[submodule "libs/dv_big_int"] + path = libs/dv_big_int + url = https://github.com/dviglo2d/dv_big_int diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..40fbacc --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,25 @@ +# Путь к исходникам движка +set(engine_dir "${CMAKE_SOURCE_DIR}/libs/dviglo2d") + +# Указываем минимальную версию CMake +include(${engine_dir}/cmake/cmake_min_version.cmake) +cmake_minimum_required(VERSION ${dv_cmake_min_version}) + +# Название проекта +project(stuff) + +include(${engine_dir}/cmake/common.cmake) + +# Папка для скомпилированных проектов +set(result_dir "${CMAKE_BINARY_DIR}/result") + +# Создаём папку result +file(MAKE_DIRECTORY ${result_dir}) + +# Указываем папку для следующих скомпилированных экзешников +dv_set_bin_dir(${result_dir}) + +# Подключаем библиотеки +add_subdirectory(libs) + +add_subdirectory(games) diff --git a/add_submodules.sh b/add_submodules.sh new file mode 100755 index 0000000..8e1d3b3 --- /dev/null +++ b/add_submodules.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +repo_dir=$(dirname "$0") + +git -C "$repo_dir" submodule add https://github.com/dviglo2d/dviglo2d libs/dviglo2d + +git -C "$repo_dir" submodule add https://github.com/dviglo2d/dv_big_int libs/dv_big_int diff --git a/build_linux.sh b/build_linux.sh new file mode 100644 index 0000000..34a5807 --- /dev/null +++ b/build_linux.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +build_type="-D CMAKE_BUILD_TYPE=Debug" +#build_type="-D CMAKE_BUILD_TYPE=Release" +#build_type="-D CMAKE_BUILD_TYPE=MinSizeRel" +#build_type="-D CMAKE_BUILD_TYPE=RelWithDebInfo" + +compiler="-D CMAKE_C_COMPILER=gcc-13 -D CMAKE_CXX_COMPILER=g++-13" +#compiler="-D CMAKE_C_COMPILER=clang-15 -D CMAKE_CXX_COMPILER=clang++-15" + +repo_dir=$(dirname "$0") + +# Генерируем проект +cmake "$repo_dir" -B "$repo_dir/../build" -G "Unix Makefiles" $build_type $compiler + +# Компилируем проект +cmake --build "$repo_dir/../build" diff --git a/build_mingw.bat b/build_mingw.bat new file mode 100644 index 0000000..bbaf236 --- /dev/null +++ b/build_mingw.bat @@ -0,0 +1,23 @@ +:: Меняем кодировку консоли на UTF-8 +chcp 65001 + +:: Указываем путь к cmake.exe и MinGW. Без system32 в PATH ссылки на папки не создаются +set "PATH=%SystemRoot%\system32;c:\programs\cmake\bin;c:\msys64\ucrt64\bin" + +set build_type=Debug +::set build_type=Release +::set build_type=MinSizeRel +::set build_type=RelWithDebInfo + +set "repo_dir=%~dp0" +:: Удаляем обратный слэш в конце +set "repo_dir=%repo_dir:~0,-1%" + +:: Генерируем проект +cmake "%repo_dir%" -B "%repo_dir%/../build_mingw" -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=%build_type% + +:: Компилируем проект +cmake --build "%repo_dir%/../build_mingw" + +:: Ждём нажатие Enter перед закрытием консоли +pause diff --git a/build_vs.bat b/build_vs.bat new file mode 100644 index 0000000..f428c6d --- /dev/null +++ b/build_vs.bat @@ -0,0 +1,25 @@ +:: Меняем кодировку консоли на UTF-8 +chcp 65001 + +:: Указываем путь к cmake.exe. Без system32 в PATH ссылки на папки не создаются +set "PATH=%SystemRoot%\system32;c:\programs\cmake\bin" + +set build_type=Debug +::set build_type=Release +::set build_type=MinSizeRel +::set build_type=RelWithDebInfo + +set "generator=Visual Studio 17" + +set "repo_dir=%~dp0" +:: Удаляем обратный слэш в конце +set "repo_dir=%repo_dir:~0,-1%" + +:: Генерируем проект +cmake "%repo_dir%" -B "%repo_dir%/../build_vs" -G "%generator%" -A x64 + +:: Компилируем проект +cmake --build "%repo_dir%/../build_vs" --config %build_type% + +:: Ждём нажатие Enter перед закрытием консоли +pause diff --git a/games/CMakeLists.txt b/games/CMakeLists.txt new file mode 100644 index 0000000..8f839ba --- /dev/null +++ b/games/CMakeLists.txt @@ -0,0 +1,14 @@ +# Помещаем игры в отдельный проект +project(games) + +# В IDE таргеты будут отображаться в папке игры +set(CMAKE_FOLDER игры) + +# Создаём папку result +file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/result) + +# Указываем папку для следующих скомпилированных экзешников +dv_set_bin_dir(${result_dir}) + +# Добавляем все папки +dv_add_all_subdirs() diff --git a/games/clicker/CMakeLists.txt b/games/clicker/CMakeLists.txt new file mode 100644 index 0000000..5e32f2a --- /dev/null +++ b/games/clicker/CMakeLists.txt @@ -0,0 +1,38 @@ +# Название таргета +set(target_name clicker) + +# Создаём список файлов +file(GLOB_RECURSE source_files src/*.cpp src/*.hpp) + +# Создаём приложение +add_executable(${target_name} ${source_files}) + +if(NOT DV_WIN32_CONSOLE) + # Используем точку входа WinMain() + set_property(TARGET ${target_name} PROPERTY WIN32_EXECUTABLE TRUE) +endif() + +# Отладочная версия приложения будет иметь суффикс _d +set_property(TARGET ${target_name} PROPERTY DEBUG_POSTFIX _d) + +# Подключаем библиотеки +target_link_libraries(${target_name} PRIVATE dviglo dv_big_int) + +# Копируем динамические библиотеки в папку с приложением +dv_copy_shared_libs_to_bin_dir(${target_name} ${result_dir} copy_shared_libs_to_app_dir) + +# Список папок с ресурсами движка для копирования в result +set(dir_names engine_data samples_data) + +# Копируем папки с ресурсами движка в result, если нужно +foreach(dir_name ${dir_names}) + if(NOT EXISTS ${result_dir}/${dir_name}) + dv_create_dir_link(${engine_dir}/result/${dir_name} ${result_dir}/${dir_name}) + endif() +endforeach() + +# Заставляем VS отображать дерево каталогов +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src FILES ${source_files}) + +# Добавляем приложение в список тестируемых +add_test(NAME ${target_name} COMMAND ${target_name} -duration 5) diff --git a/games/clicker/src/app.cpp b/games/clicker/src/app.cpp new file mode 100644 index 0000000..a47cc6c --- /dev/null +++ b/games/clicker/src/app.cpp @@ -0,0 +1,109 @@ +#include "app.hpp" + +#include +#include +#include + +#include + +using namespace glm; + + +App::App(const vector& args) + : Application(args) +{ +} + +App::~App() +{ +} + +void App::setup() +{ + engine_params::log_path = get_pref_path("dviglo2d", "mini_games") + "clicker.log"; + engine_params::window_size = ivec2(720, 700); + engine_params::msaa_samples = 4; // При значении 8 крэшится на сервере ГитХаба в Линуксе + engine_params::window_title = "Кликер"; + engine_params::vsync = -1; + engine_params::window_mode = WindowMode::windowed; +} + +void App::start() +{ + StrUtf8 base_path = get_base_path(); + sprite_batch_ = make_unique(); + r_20_font_ = make_unique(base_path + "samples_data/fonts/ubuntu-r_20_simple.fnt"); +} + +void App::handle_sdl_event(const SDL_Event& event) +{ + switch (event.type) + { + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: + on_key(event.key); + return; + + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + on_mouse_button(event.button); + return; + + default: + // Реагируем на закрытие приложения и изменение размера окна + Application::handle_sdl_event(event); + return; + } +} + +void App::on_key(const SDL_KeyboardEvent& event_data) +{ + if (event_data.type == SDL_EVENT_KEY_DOWN && event_data.repeat == false + && event_data.scancode == SDL_SCANCODE_ESCAPE) + { + should_exit_ = true; + } +} + +void App::on_mouse_button(const SDL_MouseButtonEvent& event_data) +{ + if (event_data.type == SDL_EVENT_MOUSE_BUTTON_DOWN + && event_data.button == SDL_BUTTON_LEFT) + { + gold_ += power_; + } + + else if (event_data.type == SDL_EVENT_MOUSE_BUTTON_DOWN + && event_data.button == SDL_BUTTON_RIGHT) + { + // Цена апгрейда равна силе клика + if (gold_ >= power_) + { + gold_ -= power_; + ++power_; + } + } +} + +void App::update(u64 ns) +{ +} + +void App::draw() +{ + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + + sprite_batch_->prepare_ogl(true); + + StrUtf8 help_str = "ЛКМ - добывать золото, ПКМ - усилить кирку"; + sprite_batch_->draw_string(help_str, r_20_font_.get(), vec2(10.f, 10.f)); + + StrUtf8 power_str = "Сила нажатия: " + power_.to_string() + " (= цене апгрейда)"; + sprite_batch_->draw_string(power_str, r_20_font_.get(), vec2(10.f, 40.f)); + + StrUtf8 gold_str = "Золота: " + gold_.to_string(); + sprite_batch_->draw_string(gold_str, r_20_font_.get(), vec2(300.f, 300.f)); + + sprite_batch_->flush(); +} diff --git a/games/clicker/src/app.hpp b/games/clicker/src/app.hpp new file mode 100644 index 0000000..4cb61b5 --- /dev/null +++ b/games/clicker/src/app.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include + +using namespace dviglo; +using namespace std; + + +class App : public Application +{ + unique_ptr sprite_batch_; + unique_ptr r_20_font_; + + /// Количество золота + BigInt gold_; + + /// Количество золота, получаемого за клик + BigInt power_{1}; + +public: + App(const vector& args); + ~App() override; + + void setup() override; + void start() override; + void handle_sdl_event(const SDL_Event& event) override; + void update(u64 ns) override; + void draw() override; + + void on_key(const SDL_KeyboardEvent& event_data); + void on_mouse_button(const SDL_MouseButtonEvent& event_data); +}; diff --git a/games/clicker/src/main.cpp b/games/clicker/src/main.cpp new file mode 100644 index 0000000..037e844 --- /dev/null +++ b/games/clicker/src/main.cpp @@ -0,0 +1,9 @@ +#include "app.hpp" + +#include + +#define SDL_MAIN_USE_CALLBACKS +#include + + +DV_DEFINE_APP(App); diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt new file mode 100644 index 0000000..17e27ef --- /dev/null +++ b/libs/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(dv_big_int EXCLUDE_FROM_ALL) +add_subdirectory(dviglo2d EXCLUDE_FROM_ALL) diff --git a/libs/dv_big_int b/libs/dv_big_int new file mode 160000 index 0000000..63d82f6 --- /dev/null +++ b/libs/dv_big_int @@ -0,0 +1 @@ +Subproject commit 63d82f6e45a10389974df84444e1b2513a8b32b8 diff --git a/libs/dviglo2d b/libs/dviglo2d new file mode 160000 index 0000000..6911c4f --- /dev/null +++ b/libs/dviglo2d @@ -0,0 +1 @@ +Subproject commit 6911c4f91f3b6679e6bb680854bef7b2995ffc52 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..1c3f8c4 --- /dev/null +++ b/readme.md @@ -0,0 +1,5 @@ +# Содержание + +## Игры + +* [Кликер](games/clicker) diff --git a/remove_spaces.py b/remove_spaces.py new file mode 100644 index 0000000..bf3d301 --- /dev/null +++ b/remove_spaces.py @@ -0,0 +1,40 @@ +# Удаляет пробелы в конце строк + +import os + + +def get_newline(file_path): + with open(file_path, 'rb') as file: + content = file.read() + + if b'\r\n' in content: + return '\r\n' + else: + return '\n' + + +def remove_trailing_spaces(file_path): + with open(file_path, 'r', encoding='utf-8') as file: + lines = file.readlines() + + # Сохраняем формат разделителя строк + nel = get_newline(file_path) + + with open(file_path, 'w', encoding='utf-8', newline=nel) as file: + for line in lines: + file.write(line.rstrip() + '\n') + + +if __name__ == '__main__': + repo_dir = os.path.dirname(os.path.realpath(__file__)) + exts = {'.bat', '.sh', '.md', '.hpp', '.cpp', '.txt', '.py', '.yml', '.editorconfig', '.gitattributes', '.gitignore'} + + for root, dirs, files in os.walk(repo_dir): + if '.git' in dirs: # Не заходим в папку .git + dirs.remove('.git') + + for file in files: + if any(file.endswith(ext) for ext in exts): + file_path = os.path.join(root, file) + remove_trailing_spaces(file_path) + print('Обработан файл: ' + file_path)