added function to disable audio chunks, colors default to fully transparent, add public getters for Pad::box and Pad::visible
This commit is contained in:
parent
8498dfa004
commit
102d1749a5
14
README.md
14
README.md
|
@ -5,7 +5,7 @@
|
|||
|
||||
/\ +-------------------------------------------------------+
|
||||
____/ \____ /| Open source game framework licensed to freely use, |
|
||||
\ / / | copy, and modify. Created for [dank.game] |
|
||||
\ / / | copy, and modify, created for dank.game |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | Download at https://open.shampoo.ooo/shampoo/spacebox |
|
||||
| ~~~~~~~~~~~~ | +-------------------------------------------------------+
|
||||
|
@ -577,11 +577,11 @@ When initializing a Game object, the framework will attempt to load the font fil
|
|||
License
|
||||
-------
|
||||
|
||||
[SPACEBOX] is released under the zlib license. It is free to use, copy, modify and sell. See LICENSE.txt for details.
|
||||
SPACE🪐BOX is released under the zlib license. It is free to use, copy, modify and sell. See [LICENSE.txt](LICENSE.txt) for details.
|
||||
|
||||
Included libraries are included under various permissive licenses compatible with the zlib license:
|
||||
|
||||
* BPmono.ttf is licensed under the Creative Commons Attribution * No Derivative Works 3.0 license. See [LICENSE_BPmono.txt]()
|
||||
* BPmono.ttf is licensed under the Creative Commons Attribution, No Derivative Works 3.0 license. See [LICENSE_BPmono.txt]()
|
||||
* gif-h is unlicensed, public domain code released under the The Unlicense. See [lib/gif-h/LICENSE]()
|
||||
* GLEW is included under the license in [lib/glew/LICENSE.txt]()
|
||||
* GLM is included under the MIT license in [lib/glm/LICENSE]()
|
||||
|
@ -592,8 +592,12 @@ Included libraries are included under various permissive licenses compatible wit
|
|||
Contact
|
||||
-------
|
||||
|
||||
mailbox at shampoo.ooo
|
||||
https://twitter.com/diskmem
|
||||
| Method | Contact information |
|
||||
| :------ | :---------------------------- |
|
||||
| E-mail | cocktail.frank@dank.game |
|
||||
| Web | <https://dank.game> |
|
||||
| X | <https://x.com/diskmem> |
|
||||
| PayPal | <https://paypal.me/ohsqueezy> |
|
||||
|
||||
[SDL wiki Android page]: https://wiki.libsdl.org/Android
|
||||
[SDL docs Android README]: https://github.com/libsdl-org/SDL/blob/main/docs/README-android.md
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
/* +------------------------------------------------------+
|
||||
____/ \____ /| - Open source game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
||||
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+-------------*/
|
||||
|
||||
#include "Audio.hpp"
|
||||
|
||||
using namespace sb::audio;
|
||||
|
@ -101,29 +111,36 @@ void Chunk::loop(int count)
|
|||
|
||||
int Chunk::play(float fade, int channel)
|
||||
{
|
||||
/* Play the audio with a fade in time if any was specified. */
|
||||
int assignment;
|
||||
if (fade <= 0.0f)
|
||||
if (enabled())
|
||||
{
|
||||
assignment = Mix_PlayChannel(channel, chunk.get(), loops);
|
||||
/* Play the audio with a fade in time if any was specified. */
|
||||
int assignment;
|
||||
if (fade <= 0.0f)
|
||||
{
|
||||
assignment = Mix_PlayChannel(channel, chunk.get(), loops);
|
||||
}
|
||||
else
|
||||
{
|
||||
int milliseconds = static_cast<int>(std::round(fade * 1000.0f));
|
||||
assignment = Mix_FadeInChannel(channel, chunk.get(), loops, milliseconds);
|
||||
}
|
||||
|
||||
/* Check if the audio is paused on other channels. If so, stop the audio on those channels. */
|
||||
int count = Mix_GroupCount(-1);
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
if (index != assignment && Mix_GetChunk(index) == chunk.get() && Mix_Paused(index))
|
||||
{
|
||||
Mix_HaltChannel(index);
|
||||
}
|
||||
}
|
||||
|
||||
return assignment;
|
||||
}
|
||||
else
|
||||
{
|
||||
int milliseconds = static_cast<int>(std::round(fade * 1000.0f));
|
||||
assignment = Mix_FadeInChannel(channel, chunk.get(), loops, milliseconds);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if the audio is paused on other channels. If so, stop the audio on those channels. */
|
||||
int count = Mix_GroupCount(-1);
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
if (index != assignment && Mix_GetChunk(index) == chunk.get() && Mix_Paused(index))
|
||||
{
|
||||
Mix_HaltChannel(index);
|
||||
}
|
||||
}
|
||||
|
||||
return assignment;
|
||||
}
|
||||
|
||||
void Chunk::stop(float fade)
|
||||
|
@ -160,12 +177,15 @@ void Chunk::pause()
|
|||
|
||||
void Chunk::resume()
|
||||
{
|
||||
int count = Mix_GroupCount(-1);
|
||||
for (int channel = 0; channel < count; channel++)
|
||||
if (enabled())
|
||||
{
|
||||
if (Mix_GetChunk(channel) == chunk.get())
|
||||
int count = Mix_GroupCount(-1);
|
||||
for (int channel = 0; channel < count; channel++)
|
||||
{
|
||||
Mix_Resume(channel);
|
||||
if (Mix_GetChunk(channel) == chunk.get())
|
||||
{
|
||||
Mix_Resume(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +229,15 @@ bool Chunk::fading() const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Chunk::enabled(std::optional<bool> state)
|
||||
{
|
||||
if (state.has_value())
|
||||
{
|
||||
_enabled = state.value();
|
||||
}
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
Music::Music(const fs::path& path)
|
||||
{
|
||||
load(path);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* +------------------------------------------------------+
|
||||
____/ \____ /| - Open source game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
||||
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
||||
/* +-------------------------------------------------------+
|
||||
____/ \____ /| Open source game framework licensed to freely use, |
|
||||
\ / / | copy, and modify, created for dank.game |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | Download at https://open.shampoo.ooo/shampoo/spacebox |
|
||||
| ~~~~~~~~~~~~ | +-------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+-------------*/
|
||||
|
@ -15,6 +15,7 @@
|
|||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
#include "SDL.h"
|
||||
#include "SDL_mixer.h"
|
||||
#include "filesystem.hpp"
|
||||
|
@ -52,12 +53,13 @@ namespace sb::audio
|
|||
/*!
|
||||
* Load audio from an OGG or WAV file and play it.
|
||||
*
|
||||
* Each instance contains an SDL `Mix_Chunk` audio data struct and automatically finds a open channel to play it on when play is requested. The chunk
|
||||
* can be playing on multiple channels simultaneously.
|
||||
* Each instance contains an SDL `Mix_Chunk` audio data struct and automatically finds a open channel to play it on when play is
|
||||
* requested. The chunk can be playing on multiple channels simultaneously.
|
||||
*
|
||||
* There are some differences between how `Mix_Chunk` and `Mix_Music` can be used with the API, most notably that multiple chunks can be playing on
|
||||
* multiple channels simultaneously, but only one music object can be playing at a time. This is most likely because `Mix_Music` objects are streamed
|
||||
* and `Mix_Chunk` are loaded into memory, but I haven't verified that by looking at the internal code.
|
||||
* There are some differences between how `Mix_Chunk` and `Mix_Music` can be used with the API, most notably that multiple chunks
|
||||
* can be playing on multiple channels simultaneously, but only one music object can be playing at a time. This is most likely
|
||||
* because `Mix_Music` objects are streamed and `Mix_Chunk` are loaded into memory, but I haven't verified that by looking at SDL's
|
||||
* code.
|
||||
*/
|
||||
class Chunk
|
||||
{
|
||||
|
@ -65,6 +67,7 @@ namespace sb::audio
|
|||
private:
|
||||
|
||||
std::shared_ptr<Mix_Chunk> chunk;
|
||||
bool _enabled = true;
|
||||
|
||||
/* -1 means loop forever, any other value is the number of times to loop */
|
||||
int loops = 0;
|
||||
|
@ -77,8 +80,8 @@ namespace sb::audio
|
|||
Chunk() = default;
|
||||
|
||||
/*!
|
||||
* Create an audio chunk and load it with data from an OGG or WAV file at the given path. If the given path does not contain loadable data,
|
||||
* a warning will be printed, and an empty chunk will be created.
|
||||
* Create an audio chunk and load it with data from an OGG or WAV file at the given path. If the given path does not contain
|
||||
* loadable data, a warning will be printed, and an empty chunk will be created.
|
||||
*
|
||||
* This will call Chunk::load(const fs::path&) automatically.
|
||||
*
|
||||
|
@ -87,8 +90,8 @@ namespace sb::audio
|
|||
Chunk(const fs::path& path);
|
||||
|
||||
/*!
|
||||
* Load audio data from an OGG or WAV file at the given path, replacing any existing audio data in this object. If the given path does not contain
|
||||
* loadable data, a warning will be printed, and existing audio data will not be overwritten.
|
||||
* Load audio data from an OGG or WAV file at the given path, replacing any existing audio data in this object. If the given
|
||||
* path does not contain loadable data, a warning will be printed, and existing audio data will not be overwritten.
|
||||
*
|
||||
* @param path path to an OGG or WAV file
|
||||
*/
|
||||
|
@ -105,7 +108,8 @@ namespace sb::audio
|
|||
void volume(float level);
|
||||
|
||||
/*!
|
||||
* Set the volume of all channels currently playing the audio chunk to a given level. This does not modify the volume of the chunk itself.
|
||||
* Set the volume of all channels currently playing the audio chunk to a given level. This does not modify the volume of the
|
||||
* chunk itself.
|
||||
*
|
||||
* @param level Volume between 0.0 and 1.0
|
||||
*/
|
||||
|
@ -122,14 +126,15 @@ namespace sb::audio
|
|||
void loop(int count);
|
||||
|
||||
/*!
|
||||
* Play the audio data loaded into this object once on the first available free channel. Optionally fade in playback over a given amount of time
|
||||
* in seconds.
|
||||
* Play the audio data loaded into this object once on the first available free channel. Optionally fade in playback over a
|
||||
* given amount of time in seconds. If chunk has been disabled using `Chunk::enabled(bool)`, do nothing instead, and return
|
||||
* -1.
|
||||
*
|
||||
* This always plays the audio from the beginning even if the audio is paused. To resume instead, use Chunk::resume(). Any audio chunks currently
|
||||
* paused will be stopped.
|
||||
* This always plays the audio from the beginning even if the audio is paused. To resume instead, use Chunk::resume(). Any
|
||||
* audio chunks currently paused will be stopped.
|
||||
*
|
||||
* If the audio is playing already, however, it will continue to play on that channel, and it will be played again from the beginning on another
|
||||
* channel.
|
||||
* If the audio is playing already, however, it will continue to play on that channel, and it will be played again from the
|
||||
* beginning on another channel.
|
||||
*
|
||||
* @param fade Length of fade in in seconds
|
||||
* @param channel The SDL mixer channel to play the sound on. A value of -1 means choose a channel automatically.
|
||||
|
@ -138,7 +143,8 @@ namespace sb::audio
|
|||
int play(float fade = 0.0f, int channel = -1);
|
||||
|
||||
/*!
|
||||
* Stop playback of this audio chunk on all channels it is playing on. Optionally fade out over the given amount of time in seconds.
|
||||
* Stop playback of this audio chunk on all channels it is playing on. Optionally fade out over the given amount of time in
|
||||
* seconds.
|
||||
*
|
||||
* @param fade length of fade out in seconds
|
||||
*/
|
||||
|
@ -155,7 +161,8 @@ namespace sb::audio
|
|||
void resume();
|
||||
|
||||
/*!
|
||||
* @return True if the audio is playing on any channel, false otherwise. Note that paused or fading audio is considered playing.
|
||||
* @return True if the audio is playing on any channel, false otherwise. Note that paused or fading audio is considered
|
||||
* playing.
|
||||
*/
|
||||
bool playing() const;
|
||||
|
||||
|
@ -168,16 +175,26 @@ namespace sb::audio
|
|||
* @return True if the audio is fading in or out on any channels, false otherwise.
|
||||
*/
|
||||
bool fading() const;
|
||||
|
||||
/*!
|
||||
* By default, a chunk object is enabled to play audio. If the chunk is disabled, however, the play function will not
|
||||
* be able to be used. This function can be used both to check the state and to set the state.
|
||||
*
|
||||
* @param state Set to false to disable, true to enable, or omit to check the current state
|
||||
* @return True if button is set to enabled
|
||||
*/
|
||||
bool enabled(std::optional<bool> state = std::nullopt);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Load audio from an OGG or WAV file and play it on a single channel dedicated to music. Only one music object can be playing at a time.
|
||||
* Load audio from an OGG or WAV file and play it on a single channel dedicated to music. Only one music object can be playing
|
||||
* at a time.
|
||||
*
|
||||
* This class interfaces with SDL mixer's API and Mix_Music audio data pointer.
|
||||
*
|
||||
* There are some differences between how Mix_Chunk and Mix_Music can be used with the API, most notably that multiple chunks can be playing on
|
||||
* multiple channels simultaneously, but only one music object can be playing at a time. This is most likely because Mix_Music objects are streamed
|
||||
* and Mix_Chunk are loaded into memory, but I haven't verified that by looking at the internal code.
|
||||
* There are some differences between how Mix_Chunk and Mix_Music can be used with the API, most notably that multiple chunks can
|
||||
* be playing on multiple channels simultaneously, but only one music object can be playing at a time. This is most likely because
|
||||
* Mix_Music objects are streamed and Mix_Chunk are loaded into memory, but I haven't verified that by looking at the internal code.
|
||||
*/
|
||||
class Music
|
||||
{
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
/* +------------------------------------------------------+
|
||||
____/ \____ /| - Open source game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
||||
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
||||
/* +-------------------------------------------------------+
|
||||
____/ \____ /| Open source game framework licensed to freely use, |
|
||||
\ / / | copy, and modify, created for dank.game |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | Download at https://open.shampoo.ooo/shampoo/spacebox |
|
||||
| ~~~~~~~~~~~~ | +-------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+-------------*/
|
||||
|
||||
#include "Color.hpp"
|
||||
|
||||
sb::Color::Color() : sb::Color(0, 0, 0, 255) {}
|
||||
sb::Color::Color() : sb::Color(0, 0, 0, 0) {}
|
||||
|
||||
sb::Color::Color(const SDL_Color& color) : sb::Color(color.r, color.g, color.b, color.a) {};
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* +------------------------------------------------------+
|
||||
____/ \____ /| - Open source game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - created for <https://foam.ooo> |
|
||||
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
||||
/* +-------------------------------------------------------+
|
||||
____/ \____ /| Open source game framework licensed to freely use, |
|
||||
\ / / | copy, and modify, created for dank.game |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | Download at https://open.shampoo.ooo/shampoo/spacebox |
|
||||
| ~~~~~~~~~~~~ | +-------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+-------------*/
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include "Configuration.hpp"
|
||||
|
||||
Configuration::Configuration(Node* parent) : Node(parent)
|
||||
Configuration::Configuration()
|
||||
{
|
||||
set_defaults();
|
||||
}
|
||||
|
|
|
@ -21,12 +21,11 @@
|
|||
|
||||
/* SPACEBOX */
|
||||
#include "filesystem.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Animation.hpp"
|
||||
#include "Log.hpp"
|
||||
#include "extension.hpp"
|
||||
|
||||
class Configuration : public Node
|
||||
class Configuration
|
||||
{
|
||||
|
||||
private:
|
||||
|
@ -36,10 +35,10 @@ private:
|
|||
std::vector<fs::path> files_to_refresh;
|
||||
|
||||
/*!
|
||||
* @warning This JSON will be copied when the object is copied, and it is potentially a large copy because it can copy an arbitrary amount of
|
||||
* JSON data. Because a game object by definition has a single configuration, this can be optimized in the future so that the JSON is stored
|
||||
* in a member of the game object. Arguably it also doesn't make sense to be copying the data because the JSON is expected to change during
|
||||
* runtime.
|
||||
* @warning This JSON will be copied when the object is copied, and it is potentially a large copy because it can copy an arbitrary
|
||||
* amount of JSON data. Because a game object by definition has a single configuration, this can be optimized in the future so that
|
||||
* the JSON is stored in a member of the game object. Arguably it also doesn't make sense to be copying the data because the JSON is
|
||||
* expected to change during runtime.
|
||||
*/
|
||||
nlohmann::json config;
|
||||
|
||||
|
@ -91,10 +90,8 @@ public:
|
|||
* Construct a Configuration object. The path argument is the location to look for a user configuration. If valid JSON is found,
|
||||
* it will be merged into the hard-coded default assignments, overwriting any existing key/value pairs. The path will be watched
|
||||
* for changes if auto refresh is turned on.
|
||||
*
|
||||
* @param parent SPACEBOX Node rooted at the Game object
|
||||
*/
|
||||
Configuration(Node* parent);
|
||||
Configuration();
|
||||
|
||||
/*!
|
||||
* Get a writable JSON object corresponding to a key in the configuration.
|
||||
|
@ -127,13 +124,14 @@ public:
|
|||
* Example,
|
||||
*
|
||||
* std::cout << _configuration() << std::endl;
|
||||
* std::cout << _configuration("recording", "enabled") << " " << _configuration("input") << " " << _configuration("levels", 0, 3, 1) << std::endl;
|
||||
* std::cout << _configuration("recording", "enabled") << " " << _configuration("input") << " " <<
|
||||
* _configuration("levels", 0, 3, 1) << std::endl;
|
||||
*
|
||||
* Prints,
|
||||
*
|
||||
* [full config...]
|
||||
* true {"any-key-ignore-commands":[],"default-unsuppress-delay":0.7,"ignore-repeat-keypress":true,"suppress-any-key-on-mods":true, \
|
||||
* "system-any-key-ignore-commands":["fullscreen","screenshot","record","quit"]} 261.0
|
||||
* true {"any-key-ignore-commands":[],"default-unsuppress-delay":0.7,"ignore-repeat-keypress":true,\
|
||||
* "suppress-any-key-on-mods":true, "system-any-key-ignore-commands":["fullscreen","screenshot","record","quit"]} 261.0
|
||||
*
|
||||
* @param keys hierarchy of keys used to look up a specific JSON object in the config
|
||||
* @return read-only reference to JSON object specified by keys
|
||||
|
|
|
@ -74,9 +74,8 @@ bool Delegate::compare(SDL_Event& event, const std::vector<std::string>& command
|
|||
|
||||
bool Delegate::compare(SDL_Event& event, const std::string& command, bool neutral, bool cancel)
|
||||
{
|
||||
return event.type == command_event_type &&
|
||||
(command == "" || command == get_event_command(event)) &&
|
||||
(neutral || (cancel == get_event_cancel_state(event)));
|
||||
return event.type == command_event_type && (command == "" || command == event_command(event)) &&
|
||||
(neutral || (cancel == event_cancel_state(event)));
|
||||
}
|
||||
|
||||
bool Delegate::compare_cancel(SDL_Event& event, const std::string& command)
|
||||
|
@ -94,12 +93,12 @@ void Delegate::cancel_propagation()
|
|||
cancelling_propagation = true;
|
||||
}
|
||||
|
||||
const std::string& Delegate::get_event_command(SDL_Event& event)
|
||||
const std::string& Delegate::event_command(SDL_Event& event)
|
||||
{
|
||||
return *static_cast<std::string*>(event.user.data1);
|
||||
}
|
||||
|
||||
bool Delegate::get_event_cancel_state(SDL_Event& event)
|
||||
bool Delegate::event_cancel_state(SDL_Event& event)
|
||||
{
|
||||
return *static_cast<bool*>(event.user.data2);
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ namespace sb
|
|||
static bool compare_cancel(SDL_Event&, const std::string& = "");
|
||||
static bool compare_neutral(SDL_Event&, const std::string& = "");
|
||||
void cancel_propagation();
|
||||
static const std::string& get_event_command(SDL_Event&);
|
||||
static bool get_event_cancel_state(SDL_Event&);
|
||||
static const std::string& event_command(SDL_Event&);
|
||||
static bool event_cancel_state(SDL_Event&);
|
||||
|
||||
/*!
|
||||
* Post a custom command to the queue. There is not currently support for passing custom data along with the command. The string
|
||||
|
|
|
@ -77,7 +77,7 @@ private:
|
|||
|
||||
protected:
|
||||
|
||||
Configuration _configuration {this};
|
||||
Configuration _configuration;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -37,13 +37,13 @@ namespace sb
|
|||
* this object is copied, its textures are copied with reference to the same GPU memory preserved. */
|
||||
std::vector<sb::Texture> _textures;
|
||||
|
||||
/* The attributes are associated with vertex data copied on the GPU. Shared pointers are used to store the attributes, so that if a
|
||||
* copy of this object is made, each attributes in the copied object will point to its originally constructed attributes object, preserving
|
||||
* the association with the vertex data on the GPU. */
|
||||
/* The attributes are associated with vertex data copied on the GPU. Shared pointers are used to store the attributes, so that if
|
||||
* a copy of this object is made, each attributes in the copied object will point to its originally constructed attributes object,
|
||||
* preserving the association with the vertex data on the GPU. */
|
||||
std::map<std::string, std::shared_ptr<sb::Attributes>> _attributes;
|
||||
|
||||
/* The model keeps a single transformation matrix. Specific types of transformation, like scale, translate, etc, can be combined into this
|
||||
* transformation. */
|
||||
/* The model keeps a single transformation matrix. Specific types of transformation, like scale, translate, etc, can be combined
|
||||
* into this transformation. */
|
||||
glm::mat4 _transformation {1.0f};
|
||||
|
||||
public:
|
||||
|
@ -173,25 +173,28 @@ namespace sb
|
|||
std::vector<sb::Texture>& textures();
|
||||
|
||||
/*!
|
||||
* Get a constant reference to the texture at the given index. If there are no textures, an exception will be thrown. If the index is greater
|
||||
* than the number of textures or is a negative number, modulus will be be used to wrap the value of the index to the size of the texture
|
||||
* list.
|
||||
* Get a constant reference to the texture at the given index. If there are no textures, an exception will be thrown. If the
|
||||
* index is greater than the number of textures or is a negative number, modulus will be be used to wrap the value of the index
|
||||
* to the size of the texture list.
|
||||
*
|
||||
* @param index index of texture to get
|
||||
*/
|
||||
const sb::Texture& texture(int index) const;
|
||||
|
||||
/*!
|
||||
* Get the texture at the given index. If there are no textures, an exception will be thrown. If the index is greater than the number of textures
|
||||
* or is a negative number, modulus will be be used to wrap the value of the index to the size of the texture list.
|
||||
* Get the texture at the given index. If there are no textures, an exception will be thrown. If the index is greater than the
|
||||
* number of textures or is a negative number, modulus will be be used to wrap the value of the index to the size of the texture
|
||||
* list.
|
||||
*
|
||||
* @param index index of texture to get
|
||||
*/
|
||||
sb::Texture& texture(int index);
|
||||
|
||||
/*!
|
||||
* Add a copy of the given texture to model's list of textures. Note that the texture object is copied, but the texture data is not copied.
|
||||
* The texture data is stored as a shared pointer in the texture object, so only the pointer is copied.
|
||||
* Add a copy of the given texture to model's list of textures.
|
||||
*
|
||||
* Note: the texture object is copied, but the texture data is not copied. The texture data is stored as a shared pointer in the
|
||||
* texture object, so only the pointer is copied.
|
||||
*
|
||||
* @param texture texture to add to model
|
||||
*/
|
||||
|
@ -216,20 +219,20 @@ namespace sb
|
|||
void add(sb::VBO& vbo);
|
||||
|
||||
/*!
|
||||
* Bind all of this model's textures by calling each of their bind methods. Textures must already have GL indices set, for example by
|
||||
* calling Texture::generate() on each.
|
||||
* Bind all of this model's textures by calling each of their bind methods. Textures must already have GL indices set, for
|
||||
* example by calling Texture::generate() on each.
|
||||
*/
|
||||
virtual void bind_textures() const;
|
||||
|
||||
/*!
|
||||
* Bind all of this model's attributes by calling each of their bind methods. Attributes must already have GL indices set, for example
|
||||
* by calling Attributes::index(GLint) on each.
|
||||
* Bind all of this model's attributes by calling each of their bind methods. Attributes must already have GL indices set, for
|
||||
* example by calling Attributes::index(GLint) on each.
|
||||
*/
|
||||
virtual void bind_attributes() const;
|
||||
|
||||
/*!
|
||||
* Bind all of this model's attributes and textures by calling each of their bind methods. Textures and attributes all must already
|
||||
* have GL indices set, for example by calling Texture::generate() and Attributes::index(GLint) on each.
|
||||
* Bind all of this model's attributes and textures by calling each of their bind methods. Textures and attributes all must
|
||||
* already have GL indices set, for example by calling Texture::generate() and Attributes::index(GLint) on each.
|
||||
*/
|
||||
virtual void bind() const;
|
||||
|
||||
|
|
83
src/Pad.hpp
83
src/Pad.hpp
|
@ -1,9 +1,9 @@
|
|||
/* +------------------------------------------------------+
|
||||
____/ \____ /| - Open source game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
||||
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
||||
/* +-------------------------------------------------------+
|
||||
____/ \____ /| Open source game framework licensed to freely use, |
|
||||
\ / / | copy, and modify, created for dank.game |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | Download at https://open.shampoo.ooo/shampoo/spacebox |
|
||||
| ~~~~~~~~~~~~ | +-------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+-------------*/
|
||||
|
@ -19,8 +19,8 @@
|
|||
namespace sb
|
||||
{
|
||||
/*!
|
||||
* A Pad is an object containing an sb::Plane which can be clicked to launch an arbitrary user function. It can be sized and placed by setting its
|
||||
* translation and scale values.
|
||||
* A Pad is an object containing an sb::Plane which can be clicked to launch an arbitrary user function. It can be sized and placed
|
||||
* by setting its translation and scale values.
|
||||
*
|
||||
* Each instance:
|
||||
*
|
||||
|
@ -30,8 +30,8 @@ namespace sb
|
|||
*
|
||||
* Example:
|
||||
*
|
||||
* glm::vec3 w = glm::mat3({{1, 0, 0}, {0, 1, 0}, {-0.6739, -0.74, 1}}) * glm::mat3({{.1, 0, 0}, {0, .1 * (460.0 / 768.0), 0}, {0, 0, 1}}) *
|
||||
* glm::vec3({-1, -1, 1});
|
||||
* glm::vec3 w = glm::mat3({{1, 0, 0}, {0, 1, 0}, {-0.6739, -0.74, 1}}) * glm::mat3({{.1, 0, 0}, {0, .1 * (460.0 / 768.0), 0}, \
|
||||
* {0, 0, 1}}) * glm::vec3({-1, -1, 1});
|
||||
* std::cout << w << std::endl << glm::translate(glm::vec3{-0.6739, -0.74, 0}) *
|
||||
* glm::scale(glm::vec3{.1, .1 * (460.0 / 768.0), 1}) * glm::vec4{-1, -1, 0, 1} << std::endl;
|
||||
* Pad p {background.current(), {-0.6739f, -0.74f}, 0.1f, get_display().window_box().aspect(), std::function<void()>()};
|
||||
|
@ -49,7 +49,7 @@ namespace sb
|
|||
using Reaction = std::function<ReturnType(bool, Arguments...)>;
|
||||
sb::Switch<ReturnType, Arguments...> connection;
|
||||
sb::Plane _plane;
|
||||
Box box;
|
||||
Box _box;
|
||||
int texture_index = 0;
|
||||
bool _enabled = true, _visible = true;
|
||||
|
||||
|
@ -60,17 +60,17 @@ namespace sb
|
|||
*
|
||||
* @see Pad(sb::Plane, const glm::vec2&, float, float, Reaction, float)
|
||||
*/
|
||||
Pad(const glm::vec2& translation = {0.0f, 0.0f}, float scale = 1.0f, float ratio = 1.0f, Reaction on_state_change = Reaction(), float rotation = 0.0f) :
|
||||
Pad(sb::Plane(), translation, scale, ratio, on_state_change, rotation) {}
|
||||
Pad(const glm::vec2& translation = {0.0f, 0.0f}, float scale = 1.0f, float ratio = 1.0f, Reaction on_state_change = Reaction(),
|
||||
float rotation = 0.0f) : Pad(sb::Plane(), translation, scale, ratio, on_state_change, rotation) {}
|
||||
|
||||
/*!
|
||||
* Construct a pad object from an sb::Plane, a translation amount, a scale factor, and a reaction function. The translation is relative
|
||||
* to (0.0, 0.0), and the scale is relative to the plane object.
|
||||
* Construct a pad object from an sb::Plane, a translation amount, a scale factor, and a reaction function. The translation is
|
||||
* relative to (0.0, 0.0), and the scale is relative to the plane object.
|
||||
*
|
||||
* The reaction function must accept a boolean as its first argument, which will be given the state of the pad object's switch.
|
||||
*
|
||||
* The plane object will be copied into the pad, so any edits must be made before constructing the pad, unless there is a Pad function
|
||||
* that applies the edit, such as Pad::scale(float, float).
|
||||
* The plane object will be copied into the pad, so any edits must be made before constructing the pad, unless there is a Pad
|
||||
* function that applies the edit, such as Pad::scale(float, float).
|
||||
*
|
||||
* @param plane plane or plane derivative to represent the pad visually
|
||||
* @param translation x, y amount to translate the position
|
||||
|
@ -82,7 +82,7 @@ namespace sb
|
|||
Pad(const sb::Plane& plane, glm::vec2 translation = {0.0f, 0.0f}, float scale = 1.0f, float ratio = 1.0f,
|
||||
Reaction on_state_change = Reaction(), float rotation = 0.0f) : _plane(plane)
|
||||
{
|
||||
box.size({2.0f, 2.0f}, true);
|
||||
_box.size({2.0f, 2.0f}, true);
|
||||
if (translation != glm::vec2{0.0f, 0.0f})
|
||||
{
|
||||
this->translate(translation);
|
||||
|
@ -116,6 +116,14 @@ namespace sb
|
|||
return _plane;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @return Constant reference to the pad's box object
|
||||
*/
|
||||
const sb::Box& box() const
|
||||
{
|
||||
return _box;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Rotate the pad around its center by 90 degrees. If a count is given, rotate by 90 degrees that many times, so for example,
|
||||
* a count of 3 will be a 270 degree rotation. If the count is negative, rotate -90 degrees.
|
||||
|
@ -149,8 +157,8 @@ namespace sb
|
|||
{
|
||||
scale.y *= ratio;
|
||||
}
|
||||
box.size({2.0f, 2.0f}, true);
|
||||
box.scale({scale.x, scale.y}, true);
|
||||
_box.size({2.0f, 2.0f}, true);
|
||||
_box.scale({scale.x, scale.y}, true);
|
||||
return _plane.scale(scale);
|
||||
}
|
||||
|
||||
|
@ -161,8 +169,8 @@ namespace sb
|
|||
*/
|
||||
const glm::mat4& translate(const glm::vec2& translation)
|
||||
{
|
||||
box.center({0.0f, 0.0f});
|
||||
box.move(translation);
|
||||
_box.center({0.0f, 0.0f});
|
||||
_box.move(translation);
|
||||
return _plane.translate({translation.x, translation.y, 0.0f});
|
||||
}
|
||||
|
||||
|
@ -199,7 +207,7 @@ namespace sb
|
|||
std::vector<glm::vec3> corners;
|
||||
|
||||
/* Transform each of the corners into NDC coordinates */
|
||||
for (const glm::vec2& vertex : {box.sw(), box.nw(), box.ne(), box.se()})
|
||||
for (const glm::vec2& vertex : {_box.sw(), _box.nw(), _box.ne(), _box.se()})
|
||||
{
|
||||
corners.push_back(sb::world_to_ndc(vertex, projection * view));
|
||||
}
|
||||
|
@ -223,7 +231,8 @@ namespace sb
|
|||
* @param projection projection matrix for transforming from camera space to clip space
|
||||
* @param texture_flag_uniform uniform ID for boolean enabling or disabling texture display
|
||||
*/
|
||||
void draw(GLuint transformation_uniform, glm::mat4 view, glm::mat4 projection, std::optional<GLuint> texture_flag_uniform = std::nullopt)
|
||||
void draw(GLuint transformation_uniform, glm::mat4 view, glm::mat4 projection,
|
||||
std::optional<GLuint> texture_flag_uniform = std::nullopt)
|
||||
{
|
||||
if (_visible)
|
||||
{
|
||||
|
@ -234,8 +243,8 @@ namespace sb
|
|||
glUniform1i(texture_flag_uniform.value(), true);
|
||||
}
|
||||
|
||||
/* Determine texture index by checking the state of the pad and the amount of available textures. If there is more than 1 texture,
|
||||
* the texture will correspond with the state. */
|
||||
/* Determine texture index by checking the state of the pad and the amount of available textures. If there is more
|
||||
* than 1 texture, the texture will correspond with the state. */
|
||||
if (connection && _plane.textures().size() > 1)
|
||||
{
|
||||
texture_index = 1;
|
||||
|
@ -269,7 +278,8 @@ namespace sb
|
|||
{
|
||||
if (!_enabled)
|
||||
{
|
||||
throw std::runtime_error("The pad cannot be pressed because it is currently disabled. Please check Pad::enabled before calling Pad::press.");
|
||||
throw std::runtime_error(
|
||||
"The pad cannot be pressed because it is currently disabled. Please check Pad::enabled before calling Pad::press.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -304,8 +314,8 @@ namespace sb
|
|||
}
|
||||
|
||||
/*!
|
||||
* By default, a pad object is enabled to accept input presses. If the pad is disabled, however, the press function will not be able to be
|
||||
* used and will throw an exception. This function can be used both to check the state and to set the state.
|
||||
* By default, a pad object is enabled to accept input presses. If the pad is disabled, however, the press function will not
|
||||
* be able to be used and will throw an exception. This function can be used both to check the state and to set the state.
|
||||
*
|
||||
* @param state Set to false to disable, true to enable, or omit to check the current state
|
||||
* @return True if button is set to enabled
|
||||
|
@ -320,14 +330,23 @@ namespace sb
|
|||
}
|
||||
|
||||
/*!
|
||||
* Use this function to prevent the draw function from running, which will prevent the pad object from being rendered. Note that this does
|
||||
* not disable input. To do that, use Pad::enabled(bool)
|
||||
* Use this function to prevent the draw function from running, which will prevent the pad object from being rendered. Note
|
||||
* that this does not disable input. To do that, use Pad::enabled(bool)
|
||||
*
|
||||
* @param state Set to false to prevent the pad from being drawn, set to true to re-enable drawing
|
||||
*/
|
||||
void visible(bool state = true)
|
||||
bool visible(bool state)
|
||||
{
|
||||
_visible = state;
|
||||
return _visible;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @return the pad's visibility state
|
||||
*/
|
||||
bool visible() const
|
||||
{
|
||||
return _visible;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
10
src/Text.cpp
10
src/Text.cpp
|
@ -1,3 +1,13 @@
|
|||
/* +-------------------------------------------------------+
|
||||
____/ \____ /| Open source game framework licensed to freely use, |
|
||||
\ / / | copy, and modify, created for dank.game |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | Download at https://open.shampoo.ooo/shampoo/spacebox |
|
||||
| ~~~~~~~~~~~~ | +-------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+-------------*/
|
||||
|
||||
#include "Text.hpp"
|
||||
|
||||
using namespace sb;
|
||||
|
|
22
src/Text.hpp
22
src/Text.hpp
|
@ -1,3 +1,13 @@
|
|||
/* +-------------------------------------------------------+
|
||||
____/ \____ /| Open source game framework licensed to freely use, |
|
||||
\ / / | copy, and modify, created for dank.game |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | Download at https://open.shampoo.ooo/shampoo/spacebox |
|
||||
| ~~~~~~~~~~~~ | +-------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+-------------*/
|
||||
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
|
||||
|
@ -30,15 +40,15 @@ namespace sb
|
|||
public:
|
||||
|
||||
/*!
|
||||
* Construct a sb::Text object from a font, string, and background and foreground colors. A texture will be created and attached at
|
||||
* texture index 0. The texture is not generated or rendered. Text::refresh() must be called afterward with the GL context loaded to render
|
||||
* the text to the constructed texture.
|
||||
* Construct a sb::Text object from a font, string, and background and foreground colors. A texture will be created and attached
|
||||
* at texture index 0. The texture is not generated or rendered. Text::refresh() must be called afterward with the GL context
|
||||
* loaded to render the text to the constructed texture.
|
||||
*
|
||||
* The font must be wrapped in a shared pointer. A default loaded font is available from Game::font().
|
||||
*
|
||||
* Dimensions can be given in pixels, in which case the text will be rendered at the center of a texture in exactly the given dimensions,
|
||||
* regardless of the length of the text. If the given dimensions are larger than the text, the resulting texture will have padding around
|
||||
* the text. This can be useful, for example, for creating identically sized text buttons.
|
||||
* Dimensions can be given in pixels, in which case the text will be rendered at the center of a texture in exactly the given
|
||||
* dimensions, regardless of the length of the text. If the given dimensions are larger than the text, the resulting texture will
|
||||
* have padding around the text. This can be useful, for example, for creating identically sized text buttons.
|
||||
*
|
||||
* @param font a TTF_Font object wrapped in a shared pointer
|
||||
* @param content text content
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <initializer_list>
|
||||
|
||||
/* SDL shared libraries */
|
||||
#include "SDL.h"
|
||||
|
@ -121,8 +122,9 @@ namespace sb
|
|||
/*!
|
||||
* Copy the pixel data in a given rectangular area of an SDL surface into a new SDL surface.
|
||||
*
|
||||
* @warning The coordinate system of the rectangular area is expected to be in SDL format, meaning y=0 at the top of the surface, and y=height
|
||||
* at the bottom. However, the Box class uses GL format by default. To set the Y-axis to SDL format, pass false to Box::invert_y(bool).
|
||||
* @warning The coordinate system of the rectangular area is expected to be in SDL format, meaning y=0 at the top of the surface, and
|
||||
* y=height at the bottom. However, the Box class uses GL format by default. To set the Y-axis to SDL format, pass false to
|
||||
* Box::invert_y(bool).
|
||||
*
|
||||
* @param source surface to copy pixels from
|
||||
* @param area rectangular area to copy
|
||||
|
@ -131,13 +133,13 @@ namespace sb
|
|||
std::shared_ptr<SDL_Surface> extract_area(const std::shared_ptr<SDL_Surface>& surface, const sb::Box& area);
|
||||
|
||||
/*!
|
||||
* Copy pixel data from a given SDL surface into a vector of new SDL surfaces, transforming the original surface into equally sized tiles.
|
||||
* The number of tiles and size of each tile is determined by the count parameter. Count is a 2D vector indicating how many tiles per row
|
||||
* and how many rows. For example, if count is {4, 3}, 12 tiles total will be created, 4 per row.
|
||||
* Copy pixel data from a given SDL surface into a vector of new SDL surfaces, transforming the original surface into equally sized
|
||||
* tiles. The number of tiles and size of each tile is determined by the count parameter. Count is a 2D vector indicating how many
|
||||
* tiles per row and how many rows. For example, if count is {4, 3}, 12 tiles total will be created, 4 per row.
|
||||
*
|
||||
* The tiles will be in order from the top left tile, going row by row until the bottom right tile. Note that y=0 at the top of image, not
|
||||
* the bottom, which is common in image manipulation, although is not the coordinate system GL uses, so tile 0 on the Y-axis is the top of
|
||||
* the image in this function.
|
||||
* The tiles will be in order from the top left tile, going row by row until the bottom right tile. Note that y=0 at the top of image,
|
||||
* not the bottom, which is common in image manipulation, although is not the coordinate system GL uses, so tile 0 on the Y-axis is
|
||||
* the top of the image in this function.
|
||||
*
|
||||
* If the count of tiles does not divide evenly into the number of pixels in the surface in either dimension, the rightmost and/or
|
||||
* bottommost tiles will be smaller than the rest.
|
||||
|
|
Loading…
Reference in New Issue