commit 9080d88f6f30164e84e08a1769f9e07ad930d2d6 Author: Joseph Aquino Date: Mon Sep 29 21:25:09 2025 -0400 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ef6152 --- /dev/null +++ b/.gitignore @@ -0,0 +1,396 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +#[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +intermediate-files/ + +.cache/ +.vscode/ +*.json +*.make +Makefile +*.sublime-* + +*.vcxproj + +*.sln + +*.vcxproj.filters + +*.code-workspace + +*.o + +*.d + +*.ninja* + +.idea/ + +Engine-Core/lib +Engine-Core/intermediate-files +Editor/bin +Editor/intermediate-files +Game/bin + +imgui.ini \ No newline at end of file diff --git a/Create-Solution.bat b/Create-Solution.bat new file mode 100644 index 0000000..2cd4d72 --- /dev/null +++ b/Create-Solution.bat @@ -0,0 +1,2 @@ +.\vendor\premake5\premake5.exe vs2022 +PAUSE \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..3da13a2 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Joseph Aquino + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/assets/fonts/ChakraPetch-Regular.ttf b/assets/fonts/ChakraPetch-Regular.ttf new file mode 100644 index 0000000..245df02 Binary files /dev/null and b/assets/fonts/ChakraPetch-Regular.ttf differ diff --git a/assets/fonts/OFL.txt b/assets/fonts/OFL.txt new file mode 100644 index 0000000..7bd926c --- /dev/null +++ b/assets/fonts/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2018 The Chakra Petch Project Authors (https://github.com/m4rc1e/Chakra-Petch.git) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/build-ninja.sh b/build-ninja.sh new file mode 100755 index 0000000..c4a2877 --- /dev/null +++ b/build-ninja.sh @@ -0,0 +1,4 @@ +#! /bin/bash + +./vendor/premake5/premake5 ninja +ninja $1 diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..8b3a4e6 --- /dev/null +++ b/build.sh @@ -0,0 +1,4 @@ +#! /bin/bash + +./vendor/premake5/premake5 gmake +make config=$1 diff --git a/clean-ninja.sh b/clean-ninja.sh new file mode 100755 index 0000000..f01a203 --- /dev/null +++ b/clean-ninja.sh @@ -0,0 +1,7 @@ +#! /bin/bash +if [ -z "$1" ] || [ $# -eq 0 ] + then + ninja -t clean + else + ninja -t clean $1 +fi \ No newline at end of file diff --git a/clean.sh b/clean.sh new file mode 100755 index 0000000..d726eae --- /dev/null +++ b/clean.sh @@ -0,0 +1,7 @@ +#! /bin/bash +if [ -z "$1" ] || [ $# -eq 0 ] + then + make config=Debug clean && make config=Release clean + else + make config=$1 clean +fi \ No newline at end of file diff --git a/config/game-config.txt b/config/game-config.txt new file mode 100644 index 0000000..3953675 --- /dev/null +++ b/config/game-config.txt @@ -0,0 +1,4 @@ +framerate 60 + +playerColor 1 1 1 + diff --git a/ecc.sh b/ecc.sh new file mode 100755 index 0000000..323e448 --- /dev/null +++ b/ecc.sh @@ -0,0 +1,7 @@ +#! /bin/bash +if [ -z "$1" ] || [ $# -eq 0 ] + then + ./vendor/premake5/premake5 --config=Debug ecc + else + ./vendor/premake5/premake5 --config=$1 ecc +fi \ No newline at end of file diff --git a/include/Color.h b/include/Color.h new file mode 100644 index 0000000..fa80187 --- /dev/null +++ b/include/Color.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +struct Color +{ + Color() = default; + Color(float r_in, float g_in, float b_in, float a_in); + + Color(sf::Color color_in); + + sf::Color sfml(); + + float* imgui(); + + float r{}; + float g{}; + float b{}; + float a{1.f}; +}; \ No newline at end of file diff --git a/include/Game.h b/include/Game.h new file mode 100644 index 0000000..d8c6142 --- /dev/null +++ b/include/Game.h @@ -0,0 +1,75 @@ +#pragma once + +#include + +#include + +#include +#include +#include +#include + + +class SnakeNode +{ + +}; + +struct Player +{ + Player() = default; + Player(sf::Vector2i gridPos_in); + + sf::Vector2i gridPos{}; + sf::Vector2i previousGridPos{}; + sf::Vector2f windowPos{}; + int score{}; + int lives{3}; + bool left{false}; + bool right{false}; + bool up{false}; + bool down{false}; +}; + +class Game +{ +public: + Game(bool useImgui_in); + + void run(); + +private: + void imgui(); + + void render(); + + void input(); + + void collision(); + + void movement(); + + void resetGame(); + + bool parseConfigFile(); + + void soundSystem(); + + void scoreSystem(); + + +private: + sf::Clock clock; + sf::RenderWindow window; + sf::Font font; + sf::Text lives; + sf::Text score; + + Player player; + + // mostly used for imgui + int framerate{}; + float volume{}; + bool useImgui; + static constexpr unsigned int numPhysicsUpdates{4}; +}; \ No newline at end of file diff --git a/include/Math-util.h b/include/Math-util.h new file mode 100644 index 0000000..01dcb1a --- /dev/null +++ b/include/Math-util.h @@ -0,0 +1,9 @@ + +namespace Math +{ + template + inline T max(U first, V second) + { + return static_cast(static_cast(first) >= static_cast(second) ? first : second); + } +} \ No newline at end of file diff --git a/include/Random.h b/include/Random.h new file mode 100644 index 0000000..28c2beb --- /dev/null +++ b/include/Random.h @@ -0,0 +1,74 @@ +#pragma once + +#ifndef RANDOM_MT_H +#define RANDOM_MT_H + +#include +#include + +// This header-only Random namespace implements a self-seeding Mersenne Twister. +// Requires C++17 or newer. +// It can be #included into as many code files as needed (The inline keyword avoids ODR violations) +// Freely redistributable, courtesy of learncpp.com (https://www.learncpp.com/cpp-tutorial/global-random-numbers-random-h/) +namespace Random +{ + // Returns a seeded Mersenne Twister + // Note: we'd prefer to return a std::seed_seq (to initialize a std::mt19937), but std::seed can't be copied, so it can't be returned by value. + // Instead, we'll create a std::mt19937, seed it, and then return the std::mt19937 (which can be copied). + inline std::mt19937 generate() + { + std::random_device rd{}; + + // Create seed_seq with clock and 7 random numbers from std::random_device + std::seed_seq ss{ + static_cast(std::chrono::steady_clock::now().time_since_epoch().count()), + rd(), rd(), rd(), rd(), rd(), rd(), rd() }; + + return std::mt19937{ ss }; + } + + // Here's our global std::mt19937 object. + // The inline keyword means we only have one global instance for our whole program. + inline std::mt19937 mt{ generate() }; // generates a seeded std::mt19937 and copies it into our global object + + // Generate a random int between [min, max] (inclusive) + // * also handles cases where the two arguments have different types but can be converted to int + inline int get(int min, int max) + { + return std::uniform_int_distribution{min, max}(mt); + } + + // The following function templates can be used to generate random numbers in other cases + + // See https://www.learncpp.com/cpp-tutorial/function-template-instantiation/ + // You can ignore these if you don't understand them + + // Generate a random value between [min, max] (inclusive) + // * min and max must have the same type + // * return value has same type as min and max + // * Supported types: + // * short, int, long, long long + // * unsigned short, unsigned int, unsigned long, or unsigned long long + // Sample call: Random::get(1L, 6L); // returns long + // Sample call: Random::get(1u, 6u); // returns unsigned int + template + T get(T min, T max) + { + return std::uniform_int_distribution{min, max}(mt); + } + + // Generate a random value between [min, max] (inclusive) + // * min and max can have different types + // * return type must be explicitly specified as a template argument + // * min and max will be converted to the return type + // Sample call: Random::get(0, 6); // returns std::size_t + // Sample call: Random::get(0, 6u); // returns std::size_t + // Sample call: Random::get(0, 6u); // returns int + template + R get(S min, T max) + { + return get(static_cast(min), static_cast(max)); + } +} + +#endif \ No newline at end of file diff --git a/include/Util.h b/include/Util.h new file mode 100644 index 0000000..53ba3ae --- /dev/null +++ b/include/Util.h @@ -0,0 +1,5 @@ +#pragma once + +#include +#include +#include \ No newline at end of file diff --git a/premake5.lua b/premake5.lua new file mode 100644 index 0000000..f497dbb --- /dev/null +++ b/premake5.lua @@ -0,0 +1,154 @@ +require "ecc/ecc" +require "ninja/ninja" + +workspace "snake" + architecture "x64" + + output_dir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" + vs_intdir = "!$(SolutionDir)intermediate-files/" .. output_dir + intdir = "%{wks.location}/intermediate-files/" .. output_dir + vs_bindir = "$(SolutionDir)bin/" .. output_dir + bindir = "%{wks.location}/bin/" .. output_dir + vs_coreinclude_dir = "$(SolutionDir)include" + vs_sfmldir = "$(SolutionDir)vendor/SFML" + sfmldir = "%{wks.location}/vendor/SFML" + vs_imguidir = "$(SolutionDir)vendor/imgui" + imguidir = "%{wks.location}/vendor/imgui" + vs_include_dir = "$(SolutionDir)include" + include_dir = "%{wks.location}/include" + + configurations + { + "Debug", + "Release" + } + + project "snake" + language "C++" + cppdialect "C++20" + systemversion "latest" + kind "WindowedApp" + targetname "snake" + + files + { + "src/**.cpp", + "include/**.h", + "include/**.hpp", + "vendor/imgui/imgui.cpp", + "vendor/imgui/imgui_draw.cpp", + "vendor/imgui/imgui_tables.cpp", + "vendor/imgui/imgui_widgets.cpp", + "vendor/imgui/imgui-SFML.cpp" + } + + --visual studio-- + filter {"action:vs*", "system:windows"} + targetdir (vs_bindir) + objdir (vs_intdir) + debugdir "$(SolutionDir)" + includedirs + { + "src", + vs_include_dir, + vs_sfmldir .. "/include", + vs_imguidir + } + + libdirs {vs_sfmldir .."/lib"} + + --not visual studio -- + filter {"not action:vs*", "system:windows"} + targetdir (bindir) + objdir (intdir) + debugdir "%{wks.location}" + includedirs + { + "src", + include_dir, + sfmldir .. "/include", + imguidir + } + + libdirs {sfmldir .."/lib"} + + --windows specific settings-- + filter{"system:windows"} + defines {"PLATFORM_WINDOWS", "SFML_STATIC"} + staticruntime "on" + + filter {"system:windows", "configurations:debug"} + defines{"_DEBUG", "_CONSOLE"} + links + { + "sfml-main-d", + "sfml-graphics-s-d", + "sfml-window-s-d", + "opengl32", + "gdi32", + "freetyped", + "sfml-audio-s-d", + "flacd", + "vorbisfiled", + "vorbisd", + "oggd", + "sfml-system-s-d", + "winmm" + } + + filter {"system:windows", "configurations:release"} + defines{"NDEBUG"} + links + { + "sfml-main", + "sfml-graphics-s", + "sfml-window-s", + "opengl32", + "gdi32", + "freetype", + "sfml-audio-s", + "flac", + "vorbisfile", + "vorbis", + "ogg", + "sfml-system-s", + "winmm" + } + + + --linux specific settings-- + filter {"system:linux"} + defines {"PLATFORM_LINUX"} + targetdir (bindir) + objdir (intdir) + debugdir "%{wks.location}" + includedirs + { + "src", + include_dir, + imguidir + } + + links + { + "sfml-graphics", + "sfml-window", + "sfml-audio", + "sfml-system", + "OpenGL", + } + + + --config settings-- + filter "configurations:debug" + defines {"LOG_ENABLE", "GAME_DEBUG"} + symbols "on" + runtime "Debug" + warnings "Extra" + + filter "configurations:release" + defines {"GAME_RELEASE"} + optimize "Speed" + inlining "Auto" + symbols "off" + runtime "Release" \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..3da1e02 --- /dev/null +++ b/run.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +./bin/$1-linux-x86_64/breakout \ No newline at end of file diff --git a/src/Color.cpp b/src/Color.cpp new file mode 100644 index 0000000..09a461e --- /dev/null +++ b/src/Color.cpp @@ -0,0 +1,27 @@ +#include + +#include + +Color::Color(float r_in, float g_in, float b_in, float a_in = 1.0f) + : r(r_in) + , g(g_in) + , b(b_in) + , a(a_in) +{ } + +Color::Color(sf::Color color_in) + : r(color_in.r / 255.f) + , g(color_in.g / 255.f) + , b(color_in.b / 255.f) + , a(color_in.a / 255.f) +{ } + +sf::Color Color::sfml() +{ + return sf::Color{uint8_t(r * 255), uint8_t(g * 255), uint8_t(b * 255), uint8_t(a * 255)}; +} + +float* Color::imgui() +{ + return &r; +} diff --git a/src/Game.cpp b/src/Game.cpp new file mode 100644 index 0000000..e678188 --- /dev/null +++ b/src/Game.cpp @@ -0,0 +1,221 @@ +#include +#include + +#include + +#include +#include +#include + +#include +#include + + +Game::Game(bool useImgui_in) + : window({sf::VideoMode({ 1920u, 1080u }), "project-breakout"}) + , font("assets/fonts/ChakraPetch-Regular.ttf") + , lives(font) + , score(font) + , volume(10) + , useImgui(useImgui_in) +{ + + if (!ImGui::SFML::Init(window)) return; + + if (!parseConfigFile()) return; + + lives.setPosition({10, static_cast(window.getSize().y - 40)}); + score.setPosition({10, static_cast(window.getSize().y - 80)}); + + window.setFramerateLimit(framerate); + +} + +bool Game::parseConfigFile() +{ + std::ifstream configFile{"config/game-config.txt"}; + + if(!configFile) + { + std::cerr << "ERROR: CANNOT OPEN 'game-config.txt'\n"; + return false; + } + + std::string inputBuff; + while(configFile >> inputBuff) + { + + } + + return true; +} + +void Game::input() +{ + while (const std::optional event = window.pollEvent()) + { + ImGui::SFML::ProcessEvent(window, *event); + + if (event->is()) + { + window.close(); + } + + if (const auto* keyPressed = event->getIf()) + { + switch (keyPressed->scancode) + { + case sf::Keyboard::Scan::Escape: + window.close(); + break; + + case sf::Keyboard::Scan::Left: + case sf::Keyboard::Scan::A: + player.left = true; + break; + + case sf::Keyboard::Scan::Right: + case sf::Keyboard::Scan::D: + player.right = true; + break; + + case sf::Keyboard::Scan::Up: + case sf::Keyboard::Scan::W: + player.up = true; + break; + + case sf::Keyboard::Scan::Down: + case sf::Keyboard::Scan::S: + player.down = true; + break; + + case sf::Keyboard::Scan::R: + resetGame(); + break; + + default: + break; + } + } + + if (const auto* keyReleased = event->getIf()) + { + switch (keyReleased->scancode) + { + case sf::Keyboard::Scan::Left: + case sf::Keyboard::Scan::A: + player.left = false; + break; + + case sf::Keyboard::Scan::Right: + case sf::Keyboard::Scan::D: + player.right = false; + break; + + case sf::Keyboard::Scan::Up: + case sf::Keyboard::Scan::W: + player.up = false; + break; + + case sf::Keyboard::Scan::Down: + case sf::Keyboard::Scan::S: + player.down = false; + break; + + default: + break; + } + } + } +} + +void Game::collision() +{ + + +} + +void Game::movement() +{ + +} + +void Game::imgui() +{ + ImGui::SetNextWindowCollapsed(false, ImGuiCond_Once); + ImGui::SetNextWindowSize({490,375}, ImGuiCond_Once); + ImGui::SetNextWindowPos({26,29}, ImGuiCond_Once); + if(!ImGui::Begin("menu")) + { + ImGui::End(); + return; + } + ImGui::Text("Controls:"); + ImGui::Indent(); + ImGui::Text("A/D or arrow keys: move left and right"); + ImGui::Text("R: reset game"); + ImGui::Unindent(); + + if (ImGui::SliderFloat("Game Volume", &volume, 0, 100, "%.1f")) + { + + } + + + ImGui::End(); +} + +void Game::render() +{ + window.clear(); + + lives.setString("Lives: " + std::to_string(player.lives)); + score.setString("Score: " + std::to_string(player.score)); + + window.draw(lives); + window.draw(score); + + ImGui::SFML::Render(window); + + window.display(); +} + +void Game::soundSystem() +{ + +} + +void Game::scoreSystem() +{ + +} + +void Game::resetGame() +{ + +} + +void Game::run() +{ + while(window.isOpen()) + { + ImGui::SFML::Update(window, clock.restart()); + + input(); + + movement(); + + collision(); + + soundSystem(); + + scoreSystem(); + + imgui(); + + render(); + + } + + ImGui::SFML::Shutdown(); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..bea0c7d --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,18 @@ +#include + +int main(int argc, char* argv[]) +{ + // parse command-line arguments + bool useImgui{true}; + for (int i = 0; i < argc; i++) + { + if (!strcmp(argv[i], "--noImgui")) + { + useImgui = false; + } + } + + Game game(useImgui); + + game.run(); +} \ No newline at end of file diff --git a/vendor/SFML/include/SFML/Audio.hpp b/vendor/SFML/include/SFML/Audio.hpp new file mode 100644 index 0000000..50668fd --- /dev/null +++ b/vendor/SFML/include/SFML/Audio.hpp @@ -0,0 +1,55 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +//////////////////////////////////////////////////////////// +/// \defgroup audio Audio module +/// +/// Sounds, streaming (musics or custom sources), recording, +/// spatialization. +/// +//////////////////////////////////////////////////////////// diff --git a/vendor/SFML/include/SFML/Audio/AudioResource.hpp b/vendor/SFML/include/SFML/Audio/AudioResource.hpp new file mode 100644 index 0000000..b75840c --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/AudioResource.hpp @@ -0,0 +1,93 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \brief Base class for classes that require an audio device +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API AudioResource +{ +public: + //////////////////////////////////////////////////////////// + /// \brief Copy constructor + /// + //////////////////////////////////////////////////////////// + AudioResource(const AudioResource&) = default; + + //////////////////////////////////////////////////////////// + /// \brief Copy assignment + /// + //////////////////////////////////////////////////////////// + AudioResource& operator=(const AudioResource&) = default; + + //////////////////////////////////////////////////////////// + /// \brief Move constructor + /// + //////////////////////////////////////////////////////////// + AudioResource(AudioResource&&) noexcept = default; + + //////////////////////////////////////////////////////////// + /// \brief Move assignment + /// + //////////////////////////////////////////////////////////// + AudioResource& operator=(AudioResource&&) noexcept = default; + +protected: + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + AudioResource(); + +private: + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::shared_ptr m_device; //!< Sound device +}; + +} // namespace sf + + +//////////////////////////////////////////////////////////// +/// \class sf::AudioResource +/// \ingroup audio +/// +/// This class is for internal use only, it must be the base +/// of every class that requires a valid audio device in +/// order to work. +/// +//////////////////////////////////////////////////////////// diff --git a/vendor/SFML/include/SFML/Audio/Export.hpp b/vendor/SFML/include/SFML/Audio/Export.hpp new file mode 100644 index 0000000..4cf99c1 --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/Export.hpp @@ -0,0 +1,44 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +//////////////////////////////////////////////////////////// +// Portable import / export macros +//////////////////////////////////////////////////////////// +#if defined(SFML_AUDIO_EXPORTS) + +#define SFML_AUDIO_API SFML_API_EXPORT + +#else + +#define SFML_AUDIO_API SFML_API_IMPORT + +#endif diff --git a/vendor/SFML/include/SFML/Audio/InputSoundFile.hpp b/vendor/SFML/include/SFML/Audio/InputSoundFile.hpp new file mode 100644 index 0000000..253ed63 --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/InputSoundFile.hpp @@ -0,0 +1,336 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#include + +#include +#include +#include + +#include +#include + + +namespace sf +{ +class Time; +class InputStream; + +//////////////////////////////////////////////////////////// +/// \brief Provide read access to sound files +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API InputSoundFile +{ +public: + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Construct an input sound file that is not associated + /// with a file to read. + /// + //////////////////////////////////////////////////////////// + InputSoundFile() = default; + + //////////////////////////////////////////////////////////// + /// \brief Construct a sound file from the disk for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC, MP3. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// Because of minimp3_ex limitation, for MP3 files with big (>16kb) APEv2 tag, + /// it may not be properly removed, tag data will be treated as MP3 data + /// and there is a low chance of garbage decoded at the end of file. + /// See also: https://github.com/lieff/minimp3 + /// + /// \param filename Path of the sound file to load + /// + /// \throws sf::Exception if opening the file was unsuccessful + /// + //////////////////////////////////////////////////////////// + explicit InputSoundFile(const std::filesystem::path& filename); + + //////////////////////////////////////////////////////////// + /// \brief Construct a sound file in memory for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param data Pointer to the file data in memory + /// \param sizeInBytes Size of the data to load, in bytes + /// + /// \throws sf::Exception if opening the file was unsuccessful + /// + //////////////////////////////////////////////////////////// + InputSoundFile(const void* data, std::size_t sizeInBytes); + + //////////////////////////////////////////////////////////// + /// \brief Construct a sound file from a custom stream for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param stream Source stream to read from + /// + /// \throws sf::Exception if opening the file was unsuccessful + /// + //////////////////////////////////////////////////////////// + explicit InputSoundFile(InputStream& stream); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file from the disk for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC, MP3. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// Because of minimp3_ex limitation, for MP3 files with big (>16kb) APEv2 tag, + /// it may not be properly removed, tag data will be treated as MP3 data + /// and there is a low chance of garbage decoded at the end of file. + /// See also: https://github.com/lieff/minimp3 + /// + /// \param filename Path of the sound file to load + /// + /// \return `true` if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] bool openFromFile(const std::filesystem::path& filename); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file in memory for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param data Pointer to the file data in memory + /// \param sizeInBytes Size of the data to load, in bytes + /// + /// \return `true` if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] bool openFromMemory(const void* data, std::size_t sizeInBytes); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file from a custom stream for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param stream Source stream to read from + /// + /// \return `true` if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] bool openFromStream(InputStream& stream); + + //////////////////////////////////////////////////////////// + /// \brief Get the total number of audio samples in the file + /// + /// \return Number of samples + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] std::uint64_t getSampleCount() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the number of channels used by the sound + /// + /// \return Number of channels (1 = mono, 2 = stereo) + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] unsigned int getChannelCount() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the sample rate of the sound + /// + /// \return Sample rate, in samples per second + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] unsigned int getSampleRate() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the map of position in sample frame to sound channel + /// + /// This is used to map a sample in the sample stream to a + /// position during spatialization. + /// + /// \return Map of position in sample frame to sound channel + /// + /// \see `getSampleRate`, `getChannelCount`, `getDuration` + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] const std::vector& getChannelMap() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the total duration of the sound file + /// + /// This function is provided for convenience, the duration is + /// deduced from the other sound file attributes. + /// + /// \return Duration of the sound file + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] Time getDuration() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the read offset of the file in time + /// + /// \return Time position + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] Time getTimeOffset() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the read offset of the file in samples + /// + /// \return Sample position + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] std::uint64_t getSampleOffset() const; + + //////////////////////////////////////////////////////////// + /// \brief Change the current read position to the given sample offset + /// + /// This function takes a sample offset to provide maximum + /// precision. If you need to jump to a given time, use the + /// other overload. + /// + /// The sample offset takes the channels into account. + /// If you have a time offset instead, you can easily find + /// the corresponding sample offset with the following formula: + /// `timeInSeconds * sampleRate * channelCount` + /// If the given offset exceeds to total number of samples, + /// this function jumps to the end of the sound file. + /// + /// \param sampleOffset Index of the sample to jump to, relative to the beginning + /// + //////////////////////////////////////////////////////////// + void seek(std::uint64_t sampleOffset); + + //////////////////////////////////////////////////////////// + /// \brief Change the current read position to the given time offset + /// + /// Using a time offset is handy but imprecise. If you need an accurate + /// result, consider using the overload which takes a sample offset. + /// + /// If the given time exceeds to total duration, this function jumps + /// to the end of the sound file. + /// + /// \param timeOffset Time to jump to, relative to the beginning + /// + //////////////////////////////////////////////////////////// + void seek(Time timeOffset); + + //////////////////////////////////////////////////////////// + /// \brief Read audio samples from the open file + /// + /// \param samples Pointer to the sample array to fill + /// \param maxCount Maximum number of samples to read + /// + /// \return Number of samples actually read (may be less than \a maxCount) + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] std::uint64_t read(std::int16_t* samples, std::uint64_t maxCount); + + //////////////////////////////////////////////////////////// + /// \brief Close the current file + /// + //////////////////////////////////////////////////////////// + void close(); + +private: + //////////////////////////////////////////////////////////// + /// \brief Deleter for input streams that only conditionally deletes + /// + //////////////////////////////////////////////////////////// + struct SFML_AUDIO_API StreamDeleter + { + StreamDeleter(bool theOwned); + + // To accept ownership transfer from usual std::unique_ptr + template + StreamDeleter(const std::default_delete&); + + void operator()(InputStream* ptr) const; + + bool owned{true}; + }; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::unique_ptr m_reader; //!< Reader that handles I/O on the file's format + std::unique_ptr m_stream{nullptr, false}; //!< Input stream used to access the file's data + std::uint64_t m_sampleOffset{}; //!< Sample Read Position + std::uint64_t m_sampleCount{}; //!< Total number of samples in the file + unsigned int m_sampleRate{}; //!< Number of samples per second + std::vector m_channelMap; //!< The map of position in sample frame to sound channel +}; + +} // namespace sf + + +//////////////////////////////////////////////////////////// +/// \class sf::InputSoundFile +/// \ingroup audio +/// +/// This class decodes audio samples from a sound file. It is +/// used internally by higher-level classes such as `sf::SoundBuffer` +/// and `sf::Music`, but can also be useful if you want to process +/// or analyze audio files without playing them, or if you want to +/// implement your own version of `sf::Music` with more specific +/// features. +/// +/// Usage example: +/// \code +/// // Open a sound file +/// sf::InputSoundFile file("music.ogg"); +/// +/// // Print the sound attributes +/// std::cout << "duration: " << file.getDuration().asSeconds() << '\n' +/// << "channels: " << file.getChannelCount() << '\n' +/// << "sample rate: " << file.getSampleRate() << '\n' +/// << "sample count: " << file.getSampleCount() << std::endl; +/// +/// // Read and process batches of samples until the end of file is reached +/// std::array samples; +/// std::uint64_t count; +/// do +/// { +/// count = file.read(samples.data(), samples.size()); +/// +/// // process, analyze, play, convert, or whatever +/// // you want to do with the samples... +/// } +/// while (count > 0); +/// \endcode +/// +/// \see `sf::SoundFileReader`, `sf::OutputSoundFile` +/// +//////////////////////////////////////////////////////////// diff --git a/vendor/SFML/include/SFML/Audio/Listener.hpp b/vendor/SFML/include/SFML/Audio/Listener.hpp new file mode 100644 index 0000000..475b366 --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/Listener.hpp @@ -0,0 +1,234 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#include +#include + + +//////////////////////////////////////////////////////////// +/// \brief The audio listener is the point in the scene +/// from where all the sounds are heard +/// +//////////////////////////////////////////////////////////// +namespace sf::Listener +{ +//////////////////////////////////////////////////////////// +/// \brief Structure defining the properties of a directional cone +/// +/// Sounds will play at gain 1 when they are positioned +/// within the inner angle of the cone. Sounds will play +/// at `outerGain` when they are positioned outside the +/// outer angle of the cone. The gain declines linearly +/// from 1 to `outerGain` as the sound moves from the inner +/// angle to the outer angle. +/// +//////////////////////////////////////////////////////////// +struct Cone +{ + Angle innerAngle; //!< Inner angle + Angle outerAngle; //!< Outer angle + float outerGain{}; //!< Outer gain +}; + +//////////////////////////////////////////////////////////// +/// \brief Change the global volume of all the sounds and musics +/// +/// `volume` is a number between 0 and 100; it is combined +/// with the individual volume of each sound / music. +/// The default value for the volume is 100 (maximum). +/// +/// \param volume New global volume, in the range [0, 100] +/// +/// \see `getGlobalVolume` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setGlobalVolume(float volume); + +//////////////////////////////////////////////////////////// +/// \brief Get the current value of the global volume +/// +/// \return Current global volume, in the range [0, 100] +/// +/// \see `setGlobalVolume` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API float getGlobalVolume(); + +//////////////////////////////////////////////////////////// +/// \brief Set the position of the listener in the scene +/// +/// The default listener's position is (0, 0, 0). +/// +/// \param position New listener's position +/// +/// \see `getPosition`, `setDirection` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setPosition(const Vector3f& position); + +//////////////////////////////////////////////////////////// +/// \brief Get the current position of the listener in the scene +/// +/// \return Listener's position +/// +/// \see `setPosition` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Vector3f getPosition(); + +//////////////////////////////////////////////////////////// +/// \brief Set the forward vector of the listener in the scene +/// +/// The direction (also called "at vector") is the vector +/// pointing forward from the listener's perspective. Together +/// with the up vector, it defines the 3D orientation of the +/// listener in the scene. The direction vector doesn't +/// have to be normalized. +/// The default listener's direction is (0, 0, -1). +/// +/// \param direction New listener's direction +/// +/// \see `getDirection`, `setUpVector`, `setPosition` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setDirection(const Vector3f& direction); + +//////////////////////////////////////////////////////////// +/// \brief Get the current forward vector of the listener in the scene +/// +/// \return Listener's forward vector (not normalized) +/// +/// \see `setDirection` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Vector3f getDirection(); + +//////////////////////////////////////////////////////////// +/// \brief Set the velocity of the listener in the scene +/// +/// The default listener's velocity is (0, 0, -1). +/// +/// \param velocity New listener's velocity +/// +/// \see `getVelocity`, `getDirection`, `setUpVector`, `setPosition` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setVelocity(const Vector3f& velocity); + +//////////////////////////////////////////////////////////// +/// \brief Get the current forward vector of the listener in the scene +/// +/// \return Listener's velocity +/// +/// \see `setVelocity` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Vector3f getVelocity(); + +//////////////////////////////////////////////////////////// +/// \brief Set the cone properties of the listener in the audio scene +/// +/// The cone defines how directional attenuation is applied. +/// The default cone of a sound is (2 * PI, 2 * PI, 1). +/// +/// \param cone Cone properties of the listener in the scene +/// +/// \see `getCone` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setCone(const Listener::Cone& cone); + +//////////////////////////////////////////////////////////// +/// \brief Get the cone properties of the listener in the audio scene +/// +/// \return Cone properties of the listener +/// +/// \see `setCone` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Listener::Cone getCone(); + +//////////////////////////////////////////////////////////// +/// \brief Set the upward vector of the listener in the scene +/// +/// The up vector is the vector that points upward from the +/// listener's perspective. Together with the direction, it +/// defines the 3D orientation of the listener in the scene. +/// The up vector doesn't have to be normalized. +/// The default listener's up vector is (0, 1, 0). It is usually +/// not necessary to change it, especially in 2D scenarios. +/// +/// \param upVector New listener's up vector +/// +/// \see `getUpVector`, `setDirection`, `setPosition` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setUpVector(const Vector3f& upVector); + +//////////////////////////////////////////////////////////// +/// \brief Get the current upward vector of the listener in the scene +/// +/// \return Listener's upward vector (not normalized) +/// +/// \see `setUpVector` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Vector3f getUpVector(); +} // namespace sf::Listener + + +//////////////////////////////////////////////////////////// +/// \namespace sf::Listener +/// \ingroup audio +/// +/// The audio listener defines the global properties of the +/// audio environment, it defines where and how sounds and musics +/// are heard. If `sf::View` is the eyes of the user, then +/// `sf::Listener` are their ears (by the way, they are often linked +/// together -- same position, orientation, etc.). +/// +/// `sf::Listener` is a simple interface, which allows to setup the +/// listener in the 3D audio environment (position, direction and +/// up vector), and to adjust the global volume. +/// +/// Usage example: +/// \code +/// // Move the listener to the position (1, 0, -5) +/// sf::Listener::setPosition({1, 0, -5}); +/// +/// // Make it face the right axis (1, 0, 0) +/// sf::Listener::setDirection({1, 0, 0}); +/// +/// // Reduce the global volume +/// sf::Listener::setGlobalVolume(50); +/// \endcode +/// +//////////////////////////////////////////////////////////// diff --git a/vendor/SFML/include/SFML/Audio/Music.hpp b/vendor/SFML/include/SFML/Audio/Music.hpp new file mode 100644 index 0000000..c60acda --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/Music.hpp @@ -0,0 +1,377 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2025 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#include + +#include +#include +#include + +#include +#include + + +namespace sf +{ +class Time; +class InputStream; +class InputSoundFile; + +//////////////////////////////////////////////////////////// +/// \brief Streamed music played from an audio file +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API Music : public SoundStream +{ +public: + //////////////////////////////////////////////////////////// + /// \brief Structure defining a time range using the template type + /// + //////////////////////////////////////////////////////////// + template + struct Span + { + T offset{}; //!< The beginning offset of the time range + T length{}; //!< The length of the time range + }; + + // Associated `Span` type + using TimeSpan = Span