From 7df31f6b5c03f94bdbd891fad872642695db3bee Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Thu, 17 Mar 2022 11:35:29 -0700 Subject: [PATCH] set up Rust project, delete C++ files --- .gitignore | 7 +- CMakeLists.txt | 14 - Cargo.lock | 155 ++++++ Cargo.toml | 10 + README.md | 4 +- build/.gitignore | 9 +- build/README.md | 19 +- build/build.sh | 6 - build/debian.sh | 6 +- build/packer.py | 57 -- build/run.sh | 2 - .../DEBIAN/control | 4 +- .../usr/share/applications/septadrop.desktop | 2 +- .../usr/share/icons/septadrop-icon.xpm | 0 include/.gitignore | 1 - include/Block.hpp | 12 - include/BlockType.hpp | 19 - include/Config.hpp | 24 - include/NumberRenderer.hpp | 18 - include/TileType.hpp | 12 - src/Block.cpp | 52 -- src/BlockType.cpp | 115 ---- src/Main.cpp | 505 ------------------ src/NumberRenderer.cpp | 51 -- src/TileType.cpp | 8 - src/main.rs | 3 + 26 files changed, 185 insertions(+), 930 deletions(-) delete mode 100644 CMakeLists.txt create mode 100644 Cargo.lock create mode 100644 Cargo.toml delete mode 100755 build/build.sh delete mode 100644 build/packer.py delete mode 100755 build/run.sh rename build/{septadrop_1.0_amd64 => septadrop_1.1_amd64}/DEBIAN/control (80%) rename build/{septadrop_1.0_amd64 => septadrop_1.1_amd64}/usr/share/applications/septadrop.desktop (81%) rename build/{septadrop_1.0_amd64 => septadrop_1.1_amd64}/usr/share/icons/septadrop-icon.xpm (100%) delete mode 100644 include/.gitignore delete mode 100644 include/Block.hpp delete mode 100644 include/BlockType.hpp delete mode 100644 include/Config.hpp delete mode 100644 include/NumberRenderer.hpp delete mode 100644 include/TileType.hpp delete mode 100644 src/Block.cpp delete mode 100644 src/BlockType.cpp delete mode 100644 src/Main.cpp delete mode 100644 src/NumberRenderer.cpp delete mode 100644 src/TileType.cpp create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore index 1998c29..b6bd966 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ -.cache \ No newline at end of file +# Generated by Cargo +# will have compiled files and executables +/target/ + +# These are backup files generated by rustfmt +**/*.rs.bk \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 6f83bfe..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -set(ProjectName "septadrop") - -cmake_minimum_required(VERSION 3.10) -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED 20) - -project(${ProjectName} VERSION 1.0) - -file (GLOB_RECURSE SRC_FILES src/*.cpp) -add_executable(${ProjectName} ${SRC_FILES}) -target_include_directories(${ProjectName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) - -find_package(SFML 2.5 COMPONENTS system window graphics network audio REQUIRED) -target_link_libraries(${ProjectName} sfml-graphics sfml-audio) \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..d39f4c6 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,155 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "csfml-audio-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e20d25b6f2c582dff0b82440dd2b6b6a3ae78eb07096ca226a64f02779da96" +dependencies = [ + "csfml-system-sys", + "sfml-build", +] + +[[package]] +name = "csfml-graphics-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b592b4e5f26de6d46b53f762a2a46e80826f69e008272d302a49e87c27a6c996" +dependencies = [ + "csfml-system-sys", + "csfml-window-sys", + "sfml-build", +] + +[[package]] +name = "csfml-system-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4019b7cb9ece70481603aaadb9a0094c9a6455d1a71d82d24c5a0b47c037cfaf" +dependencies = [ + "sfml-build", +] + +[[package]] +name = "csfml-window-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27076c2b6aafd377d396700f25bbf5020c695781d20aed6a399bef7ea351a17" +dependencies = [ + "csfml-system-sys", + "sfml-build", +] + +[[package]] +name = "getrandom" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.120" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09" + +[[package]] +name = "once_cell" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "septadrop" +version = "1.1.0" +dependencies = [ + "rand", + "sfml", +] + +[[package]] +name = "sfml" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c72108133019d399b24d0c0bd179cc26aa2909b0001e4202d756e4c90c21b4" +dependencies = [ + "bitflags", + "csfml-audio-sys", + "csfml-graphics-sys", + "csfml-system-sys", + "csfml-window-sys", + "once_cell", + "widestring", +] + +[[package]] +name = "sfml-build" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e0893aaf18583de27202b17007258377d5c4be16e1d0b601fd6943bc36c98b" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ac1bf6e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "septadrop" +version = "1.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +sfml = "0.16.0" +rand = "0.8.5" \ No newline at end of file diff --git a/README.md b/README.md index ecf2159..87d0303 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ ![screenshot](screenshot.png) -A block game made in C++ and [SFML](https://www.sfml-dev.org/). +A block game made in Rust and [SFML](https://www.sfml-dev.org/). -For build instructions, see the [build folder](build). +For packaging instructions, see the [build folder](build). ### Acknowledgements diff --git a/build/.gitignore b/build/.gitignore index 26a7d55..a4c20f4 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -1,9 +1,2 @@ -CMakeFiles -cmake_install.cmake -CMakeCache.txt -compile_commands.json -Makefile septadrop -septadrop_1.0_amd64/usr/bin/septadrop -septadrop_1.0_amd64.deb -.cmake \ No newline at end of file +*.deb \ No newline at end of file diff --git a/build/README.md b/build/README.md index f99d13d..675e101 100644 --- a/build/README.md +++ b/build/README.md @@ -1,23 +1,6 @@ # Building -This build setup is only working/tested for GNU/Linux systems. In order to have the required development dependencies, install them using your system's package manager. This is `libsfml-dev` on Debian-based systems and `sfml` on Arch-based systems. They package must be at version 2.5. - -To compile: - -```SH -./build.sh -``` - -To compile and run: - -```SH -./run.sh -``` - -To run: -```SH -./septadrop -``` +This build setup is only working/tested for GNU/Linux systems. In order to have the required development dependencies, install them using your system's package manager. This is `libsfml-dev` on Debian-based systems and `sfml` on Arch-based systems. The package must be at version 2.5. Since septadrop now uses Rust bindings of SFML, `libcsfml-dev` needs to also be installed on Debian-based systems, and and `csfml` on Arch-based systems. ## Packaging diff --git a/build/build.sh b/build/build.sh deleted file mode 100755 index deaef61..0000000 --- a/build/build.sh +++ /dev/null @@ -1,6 +0,0 @@ -# DCMAKE_EXPORT_COMPILE_COMMANDS=ON generates compile_commands.json in build folder, -# which clangd will pick up -# Without this, clangd might assume the wrong C++ version -cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. -python3 packer.py -cmake --build . \ No newline at end of file diff --git a/build/debian.sh b/build/debian.sh index 9d82ba4..e35a2f0 100755 --- a/build/debian.sh +++ b/build/debian.sh @@ -1,5 +1,7 @@ TARGET=septadrop_1.0_amd64 -./build.sh mkdir -p ${TARGET}/usr/bin/ -cp septadrop ${TARGET}/usr/bin/ +cd .. +cargo build --release +cp target/release/septadrop build/${TARGET}/usr/bin/ +cd build dpkg-deb --build ${TARGET} \ No newline at end of file diff --git a/build/packer.py b/build/packer.py deleted file mode 100644 index 747d125..0000000 --- a/build/packer.py +++ /dev/null @@ -1,57 +0,0 @@ -import os, shutil - -RES_DIR = "../res/" -PACKED_DIR = "../include/packed/" -SHARED_HEADER_PATH = f"{PACKED_DIR}/SharedResources.hpp" - -resources = os.fsencode(RES_DIR) -os.makedirs(PACKED_DIR, exist_ok=True) -packed_dir = os.fsencode(PACKED_DIR) - -for filename in os.listdir(packed_dir): - file_path = os.path.join(packed_dir, filename) - if os.path.isfile(file_path) or os.path.islink(file_path): - os.unlink(file_path) - elif os.path.isdir(file_path): - shutil.rmtree(file_path) - -shared_header = "#pragma once\n\n" - -for folder in os.listdir(resources): - folder_path = os.path.join(resources, folder) - if os.path.isfile(folder_path): - continue - packed_path = os.path.join(packed_dir, folder) - os.makedirs(packed_path, exist_ok=True) - for resource in os.listdir(folder_path): - resource_path = os.path.join(folder_path, resource) - - res = "#pragma once\n\n" - - splitext = os.path.splitext(resource) - name = splitext[0].decode() - ext = splitext[1].decode() - - if ext == ".png": - name += "_texture" - elif ext == ".wav": - name += "_audio" - name += "_data" - - encoded = f"const unsigned char {name.upper()}[] = {'{'}" - file = open(resource_path, "rb") # read binary - bytes_processed = 0 - for byte in file.read(): - if bytes_processed % 16 == 0: - encoded += "\n\t" - encoded += f"0x{byte.to_bytes(1, byteorder='little').hex()}, " - bytes_processed += 1 - encoded = encoded[:-2] + "\n};" - res += encoded + "\n" - header_name = f"{name}.hpp" - with open(os.path.join(packed_path.decode(), header_name), "w") as f: - f.write(res) - shared_header += f'#include "{folder.decode()}/{header_name}"\n' - -with open(SHARED_HEADER_PATH, "w") as f: - f.write(shared_header) \ No newline at end of file diff --git a/build/run.sh b/build/run.sh deleted file mode 100755 index ed46cfd..0000000 --- a/build/run.sh +++ /dev/null @@ -1,2 +0,0 @@ -./build.sh -./septadrop \ No newline at end of file diff --git a/build/septadrop_1.0_amd64/DEBIAN/control b/build/septadrop_1.1_amd64/DEBIAN/control similarity index 80% rename from build/septadrop_1.0_amd64/DEBIAN/control rename to build/septadrop_1.1_amd64/DEBIAN/control index f755848..721a060 100644 --- a/build/septadrop_1.0_amd64/DEBIAN/control +++ b/build/septadrop_1.1_amd64/DEBIAN/control @@ -1,10 +1,10 @@ Package: septadrop -Version: 1.0 +Version: 1.1 Architecture: amd64 Essential: no Priority: optional Maintainer: ElnuDev -Description: A block game made in C++ and SFML. +Description: A block game made in Rust and SFML. Homepage: https://github.com/ElnuDev/septadrop Vcs-Browser: https://github.com/ElnuDev/septadrop Vcs-Git: https://github.com/ElnuDev/septadrop.git diff --git a/build/septadrop_1.0_amd64/usr/share/applications/septadrop.desktop b/build/septadrop_1.1_amd64/usr/share/applications/septadrop.desktop similarity index 81% rename from build/septadrop_1.0_amd64/usr/share/applications/septadrop.desktop rename to build/septadrop_1.1_amd64/usr/share/applications/septadrop.desktop index 3457bd1..bb962e8 100644 --- a/build/septadrop_1.0_amd64/usr/share/applications/septadrop.desktop +++ b/build/septadrop_1.1_amd64/usr/share/applications/septadrop.desktop @@ -2,7 +2,7 @@ Version=1.0 Name=septadrop GenericName=septadrop -Comment=A block game made in C++ and SFML. +Comment=A block game made in Rust and SFML. Exec=/usr/bin/septadrop TryExec=/usr/bin/septadrop Icon=/usr/share/icons/septadrop-icon.xpm diff --git a/build/septadrop_1.0_amd64/usr/share/icons/septadrop-icon.xpm b/build/septadrop_1.1_amd64/usr/share/icons/septadrop-icon.xpm similarity index 100% rename from build/septadrop_1.0_amd64/usr/share/icons/septadrop-icon.xpm rename to build/septadrop_1.1_amd64/usr/share/icons/septadrop-icon.xpm diff --git a/include/.gitignore b/include/.gitignore deleted file mode 100644 index ea1bb8d..0000000 --- a/include/.gitignore +++ /dev/null @@ -1 +0,0 @@ -packed \ No newline at end of file diff --git a/include/Block.hpp b/include/Block.hpp deleted file mode 100644 index d6cb2b8..0000000 --- a/include/Block.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "BlockType.hpp" - -class Block { - public: - BlockType* type; - sf::Vector2i position; - int rotation_state; - Block(); - std::vector get_tiles(); -}; \ No newline at end of file diff --git a/include/BlockType.hpp b/include/BlockType.hpp deleted file mode 100644 index 534cfc0..0000000 --- a/include/BlockType.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "TileType.hpp" -#include - -class BlockType { - public: - TileType* tile_type; - std::vector> grid; - uint width, height, starting_line; - bool rotate; - BlockType(TileType* _tile_type, const std::vector> _grid, bool _rotate = true); - - static BlockType* random(); - static void init(); - private: - inline static std::vector list = {}; - inline static bool inited = false; -}; \ No newline at end of file diff --git a/include/Config.hpp b/include/Config.hpp deleted file mode 100644 index 1c581a6..0000000 --- a/include/Config.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#define TILE_SIZE 20 - -#define GRID_WIDTH 14 -#define GRID_HEIGHT 20 - -#define WINDOW_WIDTH 500 -#define WINDOW_HEIGHT 440 - -#define PLAYFIELD_X 20 -#define PLAYFIELD_Y 20 - -#define NEXT_X 370 -#define NEXT_Y 70 -#define NEXT_WIDTH 5 -#define NEXT_HEIGHT 5 - -#define LINES_PER_LEVEL 5 -#define POINTS_1_LINE 40 -#define POINTS_2_LINES 100 -#define POINTS_3_LINES 300 -#define POINTS_4_LINES 1200 - -#define MOVE_FRAME_INTERVAL 125 -#define MAX_FAST_FORWARD_INTERVAL 125 \ No newline at end of file diff --git a/include/NumberRenderer.hpp b/include/NumberRenderer.hpp deleted file mode 100644 index 7ea4953..0000000 --- a/include/NumberRenderer.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -class NumberRenderer { - public: - sf::Texture texture; - sf::IntRect comma_rect; - sf::IntRect numeral_rects[10]; - NumberRenderer( - sf::Texture _texture, - sf::IntRect _comma_rect, - std::initializer_list _numeral_rects - ); - void render(sf::RenderWindow* window, uint number, int x, int y); - private: - sf::Sprite sprite; -}; \ No newline at end of file diff --git a/include/TileType.hpp b/include/TileType.hpp deleted file mode 100644 index 71f7f88..0000000 --- a/include/TileType.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -#include "Config.hpp" - -class TileType { - public: - sf::IntRect texture_rect; - sf::IntRect ghost_texture_rect; - TileType(sf::IntRect _texture_rect, sf::IntRect _ghost_texture_rect); -}; \ No newline at end of file diff --git a/src/Block.cpp b/src/Block.cpp deleted file mode 100644 index 83c9a67..0000000 --- a/src/Block.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include - -Block::Block() { - type = BlockType::random(); - position = sf::Vector2i(GRID_WIDTH / 2 - type->grid[0].size() / 2, 0); - rotation_state = 0; -} - -std::vector Block::get_tiles() { - std::vectortiles = {}; - for (int y = 0; y < type->grid.size(); y++) { - for (int x = 0; x < type->grid[y].size(); x++) { - if (!type->grid[y][x]) { - continue; - } - int rotated_x = x; - int rotated_y = y; - if (type->rotate) { - int center_x = type->grid[0].size() / 2; - int center_y = type->grid.size() / 2; - int offset_x = x - center_x; - int offset_y = y - center_y; - switch (rotation_state) { - case 0: - rotated_x = x; - rotated_y = y; - break; - case 1: - rotated_x = center_x + offset_y; - rotated_y = center_y - offset_x; - break; - case 2: - rotated_x = center_x - offset_x; - rotated_y = center_y - offset_y; - break; - case 3: - rotated_x = center_x - offset_y; - rotated_y = center_y + offset_x; - break; - default: - rotation_state %= 4; - } - } - int global_x = rotated_x + position.x; - int global_y = rotated_y + position.y; - tiles.push_back(sf::Vector2i(global_x, global_y)); - } - } - return tiles; -} \ No newline at end of file diff --git a/src/BlockType.cpp b/src/BlockType.cpp deleted file mode 100644 index b5ea17a..0000000 --- a/src/BlockType.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include - -BlockType::BlockType(TileType* _tile_type, const std::vector> _grid, bool _rotate) { - tile_type = _tile_type; - grid = _grid; - rotate = _rotate; - // Used for alignment in "next block" area - width = 0; - starting_line = 0; - for (uint y = 0; y < grid.size(); y++) { - bool has_content = false; - for (uint x = 0; x < grid[y].size(); x++) { - if (grid[y][x]) { - width = std::max({width, x + 1}); - has_content = true; - } - } - if (has_content) { - if (height == 0) { - starting_line = y; - } - height = y + 1 - starting_line; - } - } -} - -BlockType* BlockType::random() { - init(); - return &list[rand() % list.size()]; -} - -void BlockType::init() { - if (inited) { - return; - } - - // I block - list.push_back(BlockType(new TileType( - sf::IntRect(0, 0, TILE_SIZE, TILE_SIZE), - sf::IntRect(0, TILE_SIZE, TILE_SIZE, TILE_SIZE) - ), { - {0, 0, 0, 0}, - {1, 1, 1, 1}, - {0, 0, 0, 0}, - {0, 0, 0, 0} - } - )); - - // J Block - list.push_back(BlockType(new TileType( - sf::IntRect(TILE_SIZE, 0, TILE_SIZE, TILE_SIZE), - sf::IntRect(TILE_SIZE, TILE_SIZE, TILE_SIZE, TILE_SIZE) - ), { - {1, 0, 0}, - {1, 1, 1}, - {0, 0, 0} - } - )); - - // L Block - list.push_back(BlockType(new TileType( - sf::IntRect(TILE_SIZE * 2, 0, TILE_SIZE, TILE_SIZE), - sf::IntRect(TILE_SIZE * 2, TILE_SIZE, TILE_SIZE, TILE_SIZE) - ), { - {0, 0, 1}, - {1, 1, 1}, - {0, 0, 0} - } - )); - - // O Block - list.push_back(BlockType(new TileType( - sf::IntRect(TILE_SIZE * 3, 0, TILE_SIZE, TILE_SIZE), - sf::IntRect(TILE_SIZE * 3, TILE_SIZE, TILE_SIZE, TILE_SIZE) - ), { - {1, 1}, - {1, 1} - }, false - )); - - // S Block - list.push_back(BlockType(new TileType( - sf::IntRect(TILE_SIZE * 4, 0, TILE_SIZE, TILE_SIZE), - sf::IntRect(TILE_SIZE * 4, TILE_SIZE, TILE_SIZE, TILE_SIZE) - ), { - {0, 1, 1}, - {1, 1, 0}, - {0, 0, 0} - } - )); - - // T Block - list.push_back(BlockType(new TileType( - sf::IntRect(TILE_SIZE * 5, 0, TILE_SIZE, TILE_SIZE), - sf::IntRect(TILE_SIZE * 5, TILE_SIZE, TILE_SIZE, TILE_SIZE) - ), { - {0, 1, 0}, - {1, 1, 1}, - {0, 0, 0} - } - )); - - // Z Block - list.push_back(BlockType(new TileType( - sf::IntRect(TILE_SIZE * 6, 0, TILE_SIZE, TILE_SIZE), - sf::IntRect(TILE_SIZE * 6, TILE_SIZE, TILE_SIZE, TILE_SIZE) - ), { - {1, 1, 0}, - {0, 1, 1}, - {0, 0, 0} - } - )); - - inited = true; -} \ No newline at end of file diff --git a/src/Main.cpp b/src/Main.cpp deleted file mode 100644 index 0fc45b7..0000000 --- a/src/Main.cpp +++ /dev/null @@ -1,505 +0,0 @@ -#include "packed/textures/icon_texture_data.hpp" -#include "packed/textures/paused_texture_data.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -uint get_level(int lines) { - return std::min(lines / LINES_PER_LEVEL, 15); -} - -uint get_update_interval(int level) { - // From Tetris Worlds, see https://harddrop.com/wiki/Tetris_Worlds#Gravity - return pow(0.8 - (level - 1) * 0.007, level - 1) * 1000; -} - -int gcd(int n, int m) { - for (int i = m<=n ? m:n; i > 1; i--) { - if (n % i == 0 && m % i==0) - return i; - } - return 1; -} - -int main() -{ - srand(time(NULL)); - - sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "septadrop", sf::Style::Close); - window.setFramerateLimit(60); - window.setKeyRepeatEnabled(false); // prevent keys from retriggering when held - - sf::Image icon; - icon.loadFromMemory(ICON_TEXTURE_DATA, sizeof(ICON_TEXTURE_DATA)); - auto icon_size = icon.getSize(); - window.setIcon(icon_size.x, icon_size.y, icon.getPixelsPtr()); - - Block block; - Block next_block; - - TileType* grid[GRID_HEIGHT][GRID_WIDTH] = { nullptr }; - - sf::Texture blocks_texture; - blocks_texture.loadFromMemory(&BLOCKS_TEXTURE_DATA, sizeof(BLOCKS_TEXTURE_DATA)); - sf::Sprite sprite; - sprite.setTexture(blocks_texture); - - sf::Texture background_texture; - background_texture.loadFromMemory(&BACKGROUND_TEXTURE_DATA, sizeof(BACKGROUND_TEXTURE_DATA)); - sf::Sprite background; - background.setTexture(background_texture); - - sf::Texture numeral_texture; - numeral_texture.loadFromMemory(&NUMERALS_TEXTURE_DATA, sizeof(NUMERALS_TEXTURE_DATA)); - NumberRenderer number_renderer(numeral_texture, sf::IntRect(134, 0, 10, 16), { - sf::IntRect(0, 0, 14, 16), - sf::IntRect(14, 0, 8, 16), - sf::IntRect(22, 0, 14, 16), - sf::IntRect(36, 0, 14, 16), - sf::IntRect(50, 0, 14, 16), - sf::IntRect(64, 0, 14, 16), - sf::IntRect(78, 0, 14, 16), - sf::IntRect(92, 0, 14, 16), - sf::IntRect(106, 0, 14, 16), - sf::IntRect(120, 0, 14, 16) - }); - - bool rotate = false; - bool move_left = false; - bool move_right = false; - bool move_left_immediate = false; - bool move_right_immediate = false; - bool snap = false; - bool paused = false; - bool paused_from_lost_focus = false; - sf::Clock update_clock, move_clock, pause_clock; - uint pause_offset = 0; - - sf::RectangleShape paused_clear; - paused_clear.setFillColor(sf::Color(81, 62, 69)); - - sf::Texture paused_texture; - paused_texture.loadFromMemory(PAUSED_TEXTURE_DATA, sizeof(PAUSED_TEXTURE_DATA)); - auto paused_texture_size = paused_texture.getSize(); - - sf::Sprite paused_text; - paused_text.setTexture(paused_texture); - paused_text.setPosition( - PLAYFIELD_X + ((float)GRID_WIDTH * TILE_SIZE / 2) - (float)paused_texture_size.x / 2, - PLAYFIELD_Y + ((float)GRID_HEIGHT * TILE_SIZE / 2) - (float)paused_texture_size.y / 2 - ); - - // https://stackoverflow.com/a/478088 - const char *homedir; - if ((homedir = getenv("HOME")) == NULL) { - homedir = getpwuid(getuid())->pw_dir; - } - std::string highscore_file_path = homedir; - highscore_file_path += "/.septadrop"; - - if (!std::filesystem::exists(highscore_file_path)) { - std::ofstream highscore_file(highscore_file_path); - highscore_file << "0"; - highscore_file.close(); - } - std::fstream highscore_file(highscore_file_path); - std::string highscore_string; - highscore_file >> highscore_string; - uint highscore = std::stoi(highscore_string); - uint point_gcd = gcd(POINTS_1_LINE, gcd(POINTS_2_LINES, gcd(POINTS_3_LINES, POINTS_4_LINES))); - if (highscore % point_gcd != 0) { - std::cout << "It seems your system is misconfigured. Please see this guide for fixing the issue: https://www.youtube.com/watch?v=dQw4w9WgXcQ" << std::endl; - return 0; - } - - uint score = 0; - uint lines = 0; - uint blocks = 0; - uint tiles = 0; - - uint update_interval = get_update_interval(0); - - // https://sfxr.me/#57uBnWWZeyDTsBRrJsAp2Vwd76cMVrdeRQ7DirNQW5XekKxcrCUNx47Zggh7Uqw4R5FdeUpyk362uhjWmpNHmqxE7JBp3EkxDxfJ1VjzMRpuSHieW6B5iyVFM - sf::SoundBuffer rotate_buffer; - rotate_buffer.loadFromMemory(&ROTATE_AUDIO_DATA, sizeof(ROTATE_AUDIO_DATA)); - - sf::Sound rotate_sound; - rotate_sound.setBuffer(rotate_buffer); - - // https://sfxr.me/#57uBnWTMa2LUtaPa3P8xWZekiRxNwCPFWpRoPDVXDJM9KHkiGJcs6J62FRcjMY5oVNdT73MtmUf5rXCPvSZWL7AZuTRWWjKbPKTpZjT85AcZ6htUqTswkjksZ - sf::SoundBuffer snap_buffer; - snap_buffer.loadFromMemory(&SNAP_AUDIO_DATA, sizeof(SNAP_AUDIO_DATA)); - - sf::Sound snap_sound; - snap_sound.setBuffer(snap_buffer); - - // https://sfxr.me/#57uBnWbareN7MJJsWGD8eFCrqjikS9f8JXg8jvmKzMdVtqmRsb81eToSUpnkqgFhvxD2QoAjpw4SmGZHZjbhEiPQKetRSHCHXYFZzD7Q6RVVS9CRSeRAb6bZp - sf::SoundBuffer game_over_buffer; - game_over_buffer.loadFromMemory(&GAME_OVER_AUDIO_DATA, sizeof(GAME_OVER_AUDIO_DATA)); - - sf::Sound game_over_sound; - game_over_sound.setBuffer(game_over_buffer); - - // https://sfxr.me/#7BMHBGMfGk8EHV8czJkUucUm8EMAnMNxiqYyTfKkMpHFJu44GEdD7xP6E8NM3K7RKRExTpagPBAiWf7BLtC52CEWJVGHh8hwDLygoEG86tcPth2UtmfdrXLoh - sf::SoundBuffer row_clear_buffer; - row_clear_buffer.loadFromMemory(&ROW_CLEAR_AUDIO_DATA, sizeof(ROW_CLEAR_AUDIO_DATA)); - - sf::Sound row_clear_sound; - row_clear_sound.setBuffer(row_clear_buffer); - - // https://sfxr.me/#57uBnWg8448kTPqWAxeDvZ5CP5JWbrfJGWuRcTjva5uX3vvBnEAZ6SfiH9oLKMXgsusuJwGWx6KPfvLfHtqnhLxr476ptGv4jPbfNhQaFMYeMHFdHk9SotQ4X - sf::SoundBuffer level_up_buffer; - level_up_buffer.loadFromMemory(&LEVEL_UP_AUDIO_DATA, sizeof(LEVEL_UP_AUDIO_DATA)); - - sf::Sound level_up_sound; - level_up_sound.setBuffer(level_up_buffer); - - // https://sfxr.me/#34T6PkzvrkfdahGDBAh1uYGXTwZ8rG54kxfHpgdVCPxqG7yyK5UuqgiK9Z8Q5177itxbkSNfLSHm4zTkemT4iyxJpW89VJx82feaq8qxZeA5AJR2nWZZR59hq - sf::SoundBuffer new_highscore_buffer; - new_highscore_buffer.loadFromMemory(&NEW_HIGHSCORE_AUDIO_DATA, sizeof(NEW_HIGHSCORE_AUDIO_DATA)); - - sf::Sound new_highscore_sound; - new_highscore_sound.setBuffer(new_highscore_buffer); - - auto toggle_pause = [&] () { - paused = !paused; - if (paused) { - pause_clock.restart(); - paused_clear.setPosition(sf::Vector2f(PLAYFIELD_X, PLAYFIELD_Y)); - paused_clear.setSize(sf::Vector2f(GRID_WIDTH * TILE_SIZE, GRID_HEIGHT * TILE_SIZE)); - window.draw(paused_clear); - auto size = sf::Vector2f(NEXT_WIDTH * TILE_SIZE, NEXT_HEIGHT * TILE_SIZE); - paused_clear.setPosition(sf::Vector2f(NEXT_X, NEXT_Y) - size / 2.0f); - paused_clear.setSize(size); - window.draw(paused_clear); - window.draw(paused_text); - window.display(); - } else { - pause_offset = pause_clock.getElapsedTime().asMilliseconds(); - } - }; - - while (window.isOpen()) - { - sf::Event event; - while (window.pollEvent(event)) - { - switch (event.type) { - case sf::Event::Closed: - window.close(); - break; - case sf::Event::GainedFocus: - if (paused && paused_from_lost_focus) { - toggle_pause(); - paused_from_lost_focus = false; - } - break; - case sf::Event::LostFocus: - if (!paused) { - toggle_pause(); - paused_from_lost_focus = true; - } - break; - case sf::Event::KeyPressed: - switch (event.key.code) { - case sf::Keyboard::Escape: - toggle_pause(); - break; - case sf::Keyboard::Space: - snap = !paused; - break; - case sf::Keyboard::Up: - rotate = !paused; - break; - case sf::Keyboard::Left: - move_left = !paused; - move_left_immediate = !paused; - move_clock.restart(); - break; - case sf::Keyboard::Right: - move_right = !paused; - move_right_immediate = !paused; - move_clock.restart(); - break; - default: - break; - } - break; - case sf::Event::KeyReleased: - switch (event.key.code) { - case sf::Keyboard::Left: - move_left = false; - break; - case sf::Keyboard::Right: - move_right = false; - break; - default: - break; - } - default: - break; - } - } - - if (paused) { - // window.display() is where SFML implements frame rate limiting - // If we don't run this here, then when paused septadrop will max out the thread - window.display(); - continue; - } - - bool is_update_frame = update_clock.getElapsedTime().asMilliseconds() - pause_offset > (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) ? std::min({update_interval, (uint)MAX_FAST_FORWARD_INTERVAL}) : update_interval); - if (is_update_frame) { - update_clock.restart(); - } - - bool is_move_frame = move_clock.getElapsedTime().asMilliseconds() - pause_offset > MOVE_FRAME_INTERVAL; - if (is_move_frame) { - move_clock.restart(); - } - - pause_offset = 0; - - // Rotation - if (rotate) { - block.rotation_state++; - // Check to see if new rotation state is overlapping any tiles - int offset_required = 0; - for (auto tile : block.get_tiles()) { - if (grid[tile.y][tile.x]) { - // Can't wall kick off of blocks - block.rotation_state--; - break; - } - if (tile.x <= 0) { - int potential_offset = -tile.x; - if (potential_offset > abs(offset_required)) { - offset_required = potential_offset; - } - } else if (tile.x >= GRID_WIDTH) { - int potential_offset = GRID_WIDTH - tile.x - 1; - if (-potential_offset > abs(offset_required)) { - offset_required = potential_offset; - } - } - } - block.position.x += offset_required; - rotate = false; - rotate_sound.play(); - } - - // Horizontal movement - int movement = 0; - if (move_left_immediate || is_move_frame && move_left) { - movement--; - move_left_immediate = false; - } - if (move_right_immediate || is_move_frame && move_right) { - movement++; - move_right_immediate = false; - } - if (movement != 0) { - for (auto tile : block.get_tiles()) { - if (tile.x + movement < 0 || tile.x + movement >= GRID_WIDTH || grid[tile.y][tile.x + movement]) { - goto after_movement_loop; - } - } - block.position.x += movement; - } - after_movement_loop: - - // Snapping - int snap_offset = 0; - while (true) { - for (auto tile : block.get_tiles()) { - int y = tile.y + snap_offset; - if (y == GRID_HEIGHT - 1 || grid[y + 1][tile.x] != nullptr) { - goto after_snap_loop; - } - } - snap_offset++; - } - after_snap_loop: - bool landed = snap; - if (snap) { - block.position.y += snap_offset; - snap = false; - snap_sound.play(); - } - - // Land checking - if (!snap && is_update_frame) { - for (auto tile : block.get_tiles()) { - if (tile.y == GRID_HEIGHT - 1 || grid[tile.y + 1][tile.x] != nullptr) { - landed = true; - break; - } - } - } - - // Clear window - // Normally, one would run window.clear(), - // but the background image covers the entire window. - window.draw(background); - - // Draw block - if (!landed) { - for (auto tile : block.get_tiles()) { - int snap_y = tile.y + snap_offset; - sprite.setTextureRect(block.type->tile_type->texture_rect); - sprite.setPosition(PLAYFIELD_X + tile.x * TILE_SIZE, PLAYFIELD_Y + tile.y * TILE_SIZE); - window.draw(sprite); - sprite.setTextureRect(block.type->tile_type->ghost_texture_rect); - sprite.setPosition(PLAYFIELD_X + tile.x * TILE_SIZE, PLAYFIELD_Y + snap_y * TILE_SIZE); - window.draw(sprite); - } - } - - // Draw next block - auto next_block_tiles = next_block.get_tiles(); - // This is assuming the next block spawns unrotated. - // Refactoring is needed if random rotations are added - uint x_offset = next_block.type->width * TILE_SIZE / 2; - uint y_offset = (next_block.type->height + next_block.type->starting_line * 2) * TILE_SIZE / 2; - for (auto tile : next_block_tiles) { - sprite.setTextureRect(next_block.type->tile_type->texture_rect); - sprite.setPosition( - NEXT_X + (tile.x - next_block.position.x) * TILE_SIZE - x_offset, - NEXT_Y + (tile.y - next_block.position.y) * TILE_SIZE - y_offset - ); - window.draw(sprite); - } - - // Landing (transfering block to grid and reinitializing) - if (landed) { - if (block.position.y == 0) { - score = 0; - lines = 0; - blocks = 0; - tiles = 0; - for (int y = 0; y < GRID_HEIGHT; y++) { - for (int x = 0; x < GRID_WIDTH; x++) { - grid[y][x] = nullptr; - } - } - update_interval = get_update_interval(0); - game_over_sound.play(); - } else { - tiles += block.get_tiles().size(); - blocks++; - for (auto tile : block.get_tiles()) { - grid[tile.y][tile.x] = block.type->tile_type; - } - uint cleared_lines = 0; - // Check for completed rows - for (int y = 0; y < GRID_HEIGHT; y++) { - bool completed = true; - for (int x = 0; x < GRID_WIDTH; x++) { - if (!grid[y][x]) { - completed = false; - break; - } - } - if (!completed) { - continue; - } - for (int z = y - 1; z >= 0; z--) { - for (int x = 0; x < GRID_WIDTH; x++) { - grid[z + 1][x] = grid[z][x]; - } - } - cleared_lines++; - } - uint scored; - switch (cleared_lines) { - case 0: - scored = 0; - break; - case 1: - scored = POINTS_1_LINE; - break; - case 2: - scored = POINTS_2_LINES; - break; - case 3: - scored = POINTS_3_LINES; - break; - default: - scored = POINTS_4_LINES; - break; - } - if (scored > 0) { - int level = get_level(lines); - scored *= level + 1; - if (score + scored > highscore && score < highscore) { - new_highscore_sound.play(); - } - score += scored; - lines += cleared_lines; - if (level != get_level(lines)) { - level_up_sound.play(); - } - if (score > highscore) { - highscore = score; - std::ofstream highscore_file(highscore_file_path); - highscore_file << highscore; - highscore_file.close(); - } - update_interval = get_update_interval(level); - row_clear_sound.play(); - } - } - block = next_block; - next_block = Block(); - } else if(is_update_frame) { - block.position.y++; - } - - // Drawing grid - for (int y = 0; y < GRID_HEIGHT; y++) { - for (int x = 0; x < GRID_WIDTH; x++) { - auto tile_type = grid[y][x]; - if (tile_type == nullptr) { - // If tile_type is a nullptr (no block), continue - continue; - } - sprite.setTextureRect(tile_type->texture_rect); - sprite.setPosition(PLAYFIELD_X + x * TILE_SIZE, PLAYFIELD_Y + y * TILE_SIZE); - window.draw(sprite); - } - } - - number_renderer.render(&window, score, 477, 162); - number_renderer.render(&window, highscore, 477, 202); - number_renderer.render(&window, lines, 477, 242); - number_renderer.render(&window, get_level(lines), 477, 282); - number_renderer.render(&window, blocks, 477, 322); - number_renderer.render(&window, tiles, 477, 362); - - window.display(); - } - - return 0; -} \ No newline at end of file diff --git a/src/NumberRenderer.cpp b/src/NumberRenderer.cpp deleted file mode 100644 index cdcc768..0000000 --- a/src/NumberRenderer.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -#include - -NumberRenderer::NumberRenderer( - sf::Texture _texture, - sf::IntRect _comma_rect, - std::initializer_list _numeral_rects -) { - texture = _texture; - comma_rect = _comma_rect; - sprite = sf::Sprite(texture); - int i = 0; - for (auto numeral_rect = _numeral_rects.begin(); numeral_rect != _numeral_rects.end(); ++numeral_rect) { - numeral_rects[i] = *numeral_rect; - i++; - } -} - -void NumberRenderer::render(sf::RenderWindow* window, uint number, int x, int y) { - auto number_string = std::to_string(number); - std::string numeral_string; - numeral_string.push_back(number_string.back()); - auto numeral_rect = numeral_rects[std::stoi(numeral_string)]; - int x_offset = -numeral_rect.width; - uint digits = number_string.length(); - for (int i = digits - 1; i >= 0; i--) { - char numeral_string[] = {number_string[i]}; - auto numeral_rect = numeral_rects[std::stoi(numeral_string)]; - if ((digits - i) % 3 == 1 && i != digits - 1) { - sprite.setTextureRect(comma_rect); - sprite.setPosition(x + x_offset, y); - window->draw(sprite); - x_offset -= numeral_rect.width; - } - sprite.setTextureRect(numeral_rect); - sprite.setPosition(x + x_offset, y); - window->draw(sprite); - if (i == 0) { - break; - } - if ((digits - i) % 3 == 0) { - x_offset -= comma_rect.width; - continue; - } - numeral_string[0] = number_string[i - 1]; - numeral_rect = numeral_rects[std::stoi(numeral_string)]; - x_offset -= numeral_rect.width; - } -} \ No newline at end of file diff --git a/src/TileType.cpp b/src/TileType.cpp deleted file mode 100644 index c3096f6..0000000 --- a/src/TileType.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -#include - -TileType::TileType(sf::IntRect _texture_rect, sf::IntRect _ghost_texture_rect) { - texture_rect = _texture_rect; - ghost_texture_rect = _ghost_texture_rect; -} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +}