34#include "table/strings.h"
46 bool IsValid()
const {
return !this->
songname.empty(); }
48 typedef std::vector<PlaylistEntry> Playlist;
50 enum PlaylistChoices : uint8_t {
64 PlaylistChoices selected_playlist{};
92 int playlist_position = 0;
96 std::array<Playlist, PLCH_MAX> standard_playlists{};
108 for (
auto &playlist : this->standard_playlists) playlist.clear();
114 if (!entry.IsValid())
continue;
119 if (i == 0) this->standard_playlists[PLCH_THEMEONLY].push_back(std::move(entry));
123 this->standard_playlists[PLCH_ALLMUSIC].push_back(entry);
125 this->standard_playlists[PLCH_OLDSTYLE + theme].push_back(std::move(entry));
134 if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM1].push_back(std::move(entry));
138 if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM2].push_back(std::move(entry));
149 assert(pl < PLCH_MAX && pl >= PLCH_ALLMUSIC);
153 if (_game_mode != GM_MENU || pl == PLCH_THEMEONLY) {
154 this->selected_playlist = pl;
155 this->
active_playlist = this->standard_playlists[this->selected_playlist];
156 this->playlist_position = 0;
199 return static_cast<size_t>(this->playlist_position) < this->
active_playlist.size()
212 this->
active_playlist = this->standard_playlists[this->selected_playlist];
214 size_t shuffle_index = InteractiveRandom() % (this->
active_playlist.size() - i);
231 this->
active_playlist = this->standard_playlists[this->selected_playlist];
251 if (_game_mode == GM_MENU && this->selected_playlist == PLCH_THEMEONLY) song.
loop =
true;
287 if ((_game_mode == GM_MENU) != (this->selected_playlist == PLCH_THEMEONLY)) {
330 return (this->selected_playlist == PLCH_CUSTOM1) || (this->selected_playlist == PLCH_CUSTOM2);
343 if (song_index >= this->
music_set.size())
return;
347 if (this->standard_playlists[this->selected_playlist].size() >=
NUM_SONGS_PLAYLIST)
return;
350 this->standard_playlists[this->selected_playlist].push_back(entry);
359 size_t newpos = InteractiveRandom() % maxpos;
362 if ((
int)newpos <= this->playlist_position) this->playlist_position++;
385 Playlist &playlist = this->standard_playlists[this->selected_playlist];
386 auto it = std::end(playlist);
389 it = std::ranges::find_if(playlist, [&song](
const auto &s) {
return s.filename == song.
filename && s.cat_index == song.
cat_index; });
390 }
else if (song_index < playlist.size()) {
392 it = std::next(std::begin(playlist), song_index);
395 if (it == std::end(playlist))
return;
396 it = playlist.erase(it);
399 if (this->
IsPlaying() && std::distance(std::begin(playlist), it) == this->playlist_position) this->
Play();
414 this->standard_playlists[this->selected_playlist].clear();
428 this->playlist_position = 0;
430 this->playlist_position += ofs;
432 while (this->playlist_position < 0) this->playlist_position += (int)this->
active_playlist.size();
442 uint8_t *settings_pl;
443 if (pl == PLCH_CUSTOM1) {
445 }
else if (pl == PLCH_CUSTOM2) {
454 for (
const auto &song : this->standard_playlists[pl]) {
456 settings_pl[num++] = (uint8_t)song.set_index + 1;
490struct MusicTrackSelectionWindow :
public Window {
519 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
521 if (!gui_scope)
return;
522 for (
int i = 0; i < 6; i++) {
540 for (
int i = 0; i < 6; i++) {
543 d.width += padding.width;
544 d.height += padding.height;
552 for (
const auto &song : _music.music_set) {
557 d.width += padding.width;
558 d.height += padding.height;
572 for (
const auto &song : _music.music_set) {
583 for (
const auto &song : _music.active_playlist) {
597 _music.PlaylistAdd(y);
603 _music.PlaylistRemove(y);
609 ShowDropDownList(
this, BuildSetDropDownList<BaseMusic>(&selected), selected, widget);
614 _music.PlaylistClear();
619 _music.ChangePlaylist((MusicSystem::PlaylistChoices)(widget -
WID_MTS_ALL));
636static constexpr std::initializer_list<NWidgetPart> _nested_music_track_selection_widgets = {
677 _nested_music_track_selection_widgets
680static void ShowMusicTrackSelection()
692 UpdateDisabledButtons();
695 void UpdateDisabledButtons()
717 d.width += padding.width;
718 d.height += padding.height;
726 d.width += padding.width;
734 for (
const auto &song : _music.music_set) {
737 d.width += padding.width;
760 if (_music.IsPlaying()) {
775 }
else if (_music.IsPlaying()) {
799 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
801 if (!gui_scope)
return;
802 for (
int i = 0; i < 6; i++) {
806 UpdateDisabledButtons();
840 SetEffectVolume(vol);
851 if (_music.IsShuffle()) {
861 ShowMusicTrackSelection();
866 _music.ChangePlaylist((MusicSystem::PlaylistChoices)(widget -
WID_M_ALL));
872static constexpr std::initializer_list<NWidgetPart> _nested_music_window_widgets = {
895 NWidget(
WWT_EMPTY, INVALID_COLOUR,
WID_M_MUSIC_VOL),
SetMinimalSize(67, 0),
SetMinimalTextLines(1, 0),
SetFill(1, 0),
SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
899 NWidget(
WWT_EMPTY, INVALID_COLOUR,
WID_M_EFFECT_VOL),
SetMinimalSize(67, 0),
SetMinimalTextLines(1, 0),
SetFill(1, 0),
SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
936 _nested_music_window_widgets
939void ShowMusicWindow()
static std::string ini_set
The set as saved in the config file.
virtual void StopSong()=0
Stop playing the current song.
static MusicDriver * GetInstance()
Get the currently active instance of the music driver.
virtual void PlaySong(const MusicSongInfo &song)=0
Play a particular song.
virtual void SetVolume(uint8_t vol)=0
Set the volume, if possible.
static IDirectMusic * _music
The direct music object manages buffers and ports.
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, DropDownOptions options)
Show a drop down list.
Functions related to the drop down widget.
Types related to the drop down widget.
Functions related to errors.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
void GfxFillRect(int left, int top, int right, int bottom, const std::variant< PixelColour, PaletteID > &colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Functions related to the gfx engine.
@ FS_SMALL
Index of the small font in the font tables.
@ SA_HOR_CENTER
Horizontally center the text.
void SetDirty() const
Mark entire window as dirty (in need of re-paint).
#define Point
Macro that prevents name conflicts between included headers.
Functions to mix sound samples.
Base for all music playback.
void MusicLoop()
Check music playback status and start/stop/song-finished.
void ChangeMusicSet(int index)
Change the configured music set and reset playback.
void InitializeMusic()
Prepare the music system for use.
static constexpr PixelColour PC_BLACK
Black palette colour.
Pseudo random number generator.
A number of safeguards to prevent using unsafe methods.
ClientSettings _settings_client
The current settings for this game.
Functions for setting GUIs.
Types related to global configuration settings.
void DrawSliderWidget(Rect r, Colours wedge_colour, Colours handle_colour, TextColour text_colour, int min_value, int max_value, int nmarks, int value, SliderMarkFunc *mark_func)
Draw a slider widget with knob at given value.
bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int nmarks, int &value)
Handle click on a slider widget to change the value.
Functions related to the horizontal slider widget.
Functions related to sound.
This file contains all sprite-related enums and defines.
Definition of base types and functions in a cross-platform compatible way.
Functions related to low-level strings.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
TextDirection _current_text_dir
Text direction of the currently selected language.
uint64_t GetParamMaxDigits(uint count, FontSize size)
Get some number that is suitable for string size computations.
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
@ TD_RTL
Text is written right-to-left by default.
Dimensions (a width and height) of a rectangle in 2D.
Metadata about a music track.
std::string songname
name of song displayed in UI
std::string filename
file on disk containing song (when used in MusicSet class)
bool loop
song should play in a tight loop if possible, never ending
int cat_index
entry index in CAT file, for filetype==MTT_MPSMIDI
const MusicSet * set
music set the song comes from
uint set_index
index of song in set
void SaveCustomPlaylist(PlaylistChoices pl)
Save a custom playlist to settings after modification.
void CheckStatus()
Check that music is playing if it should, and that appropriate playlist is active for game/main menu.
void ChangeMusicSet(const std::string &set_name)
Change to named music set, and reset playback.
void ChangePlaylist(PlaylistChoices pl)
Switch to another playlist, or reload the current one.
void Shuffle()
Enable shuffle mode.
void Stop()
Stop playback and set flag that we don't intend to play music.
void BuildPlaylists()
Rebuild all playlists for the current music set.
void Next()
Skip to next track.
void Play()
Start/restart playback at current song.
bool IsPlaying() const
Is the player getting music right now?
void Unshuffle()
Disable shuffle mode.
void PlaylistRemove(size_t song_index)
Remove a song from a custom playlist.
PlaylistEntry GetCurrentSong() const
Return the current song, or a dummy if none.
void PlaylistAdd(size_t song_index)
Append a song to a custom playlist.
void ChangePlaylistPosition(int ofs)
Change playlist position pointer by the given offset, making sure to keep it within valid range.
Playlist active_playlist
current play order of songs, including any shuffle
void Prev()
Skip to previous track.
void PlaylistClear()
Remove all songs from the current custom playlist.
void SetPositionBySetIndex(uint set_index)
Set playlist position by set index.
bool IsCustomPlaylist() const
Is one of the custom playlists selected?
bool IsShuffle() const
Is shuffle mode enabled?
Playlist music_set
all songs in current music set, in set order
uint GetSetIndex()
Get set index from current playlist position.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Specification of a rectangle with absolute coordinates of all edges.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
High level window description.
Number to differentiate different windows of the same class.
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
WidgetID mouse_capture_widget
ID of current mouse capture widget (e.g. dragged scrollbar). INVALID_WIDGET if no widget has mouse ca...
ResizeInfo resize
Resize information.
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
int GetRowFromWidget(int clickpos, WidgetID widget, int padding, int line_height=-1) const
Compute the row of a widget that a user clicked in.
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting).
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
Twindow * AllocateWindowDescFront(WindowDesc &desc, WindowNumber window_number, Targs... extra_arguments)
Open a new window.
@ WDP_AUTO
Find a place automatically.
@ WN_GAME_OPTIONS_GAME_OPTIONS
Game options.
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
@ WC_MUSIC_TRACK_SELECTION
Music track selection; Window numbers:
@ WC_MUSIC_WINDOW
Music window; Window numbers:
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Functions related to zooming.