29 #include "slider_func.h"
34 #include "table/strings.h"
46 bool IsValid()
const {
return !this->
songname.empty(); }
48 typedef std::vector<PlaylistEntry> Playlist;
50 enum PlaylistChoices {
65 PlaylistChoices selected_playlist;
93 int playlist_position;
97 Playlist standard_playlists[PLCH_MAX];
109 for (
auto &playlist : this->standard_playlists) playlist.clear();
115 if (!entry.IsValid())
continue;
120 if (i == 0) this->standard_playlists[PLCH_THEMEONLY].push_back(entry);
124 this->standard_playlists[PLCH_ALLMUSIC].push_back(entry);
126 this->standard_playlists[PLCH_OLDSTYLE + theme].push_back(entry);
135 if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM1].push_back(entry);
139 if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM2].push_back(entry);
150 assert(pl < PLCH_MAX && pl >= PLCH_ALLMUSIC);
154 if (_game_mode != GM_MENU || pl == PLCH_THEMEONLY) {
157 this->selected_playlist = pl;
158 this->playlist_position = 0;
201 return static_cast<size_t>(this->playlist_position) < this->
active_playlist.size()
216 size_t shuffle_index = InteractiveRandom() % (this->
active_playlist.size() - i);
253 if (_game_mode == GM_MENU && this->selected_playlist == PLCH_THEMEONLY) song.
loop =
true;
289 if ((_game_mode == GM_MENU) != (this->selected_playlist == PLCH_THEMEONLY)) {
320 return (this->selected_playlist == PLCH_CUSTOM1) || (this->selected_playlist == PLCH_CUSTOM2);
333 if (song_index >= this->
music_set.size())
return;
337 if (this->standard_playlists[this->selected_playlist].size() >=
NUM_SONGS_PLAYLIST)
return;
340 this->standard_playlists[this->selected_playlist].push_back(entry);
350 size_t newpos = InteractiveRandom() % maxpos;
353 if ((
int)newpos <= this->playlist_position) this->playlist_position++;
371 Playlist &pl = this->standard_playlists[this->selected_playlist];
372 if (song_index >= pl.size())
return;
376 pl.erase(pl.begin() + song_index);
385 if ((
int)i == this->playlist_position && this->
IsPlaying()) this->
Play();
403 this->standard_playlists[this->selected_playlist].clear();
417 this->playlist_position = 0;
419 this->playlist_position += ofs;
421 while (this->playlist_position < 0) this->playlist_position += (int)this->
active_playlist.size();
431 uint8_t *settings_pl;
432 if (pl == PLCH_CUSTOM1) {
434 }
else if (pl == PLCH_CUSTOM2) {
443 for (
const auto &song : this->standard_playlists[pl]) {
445 settings_pl[num++] = (uint8_t)song.set_index + 1;
489 void SetStringParameters(
WidgetID widget)
const override
506 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
508 if (!gui_scope)
return;
509 for (
int i = 0; i < 6; i++) {
527 for (
int i = 0; i < 6; i++) {
528 SetDParam(0, STR_MUSIC_PLAYLIST_ALL + i);
531 d.width += padding.width;
532 d.height += padding.height;
540 for (
const auto &song :
_music.music_set) {
545 d.width = std::max(d.width, d2.width);
546 d.height += d2.height;
548 d.width += padding.width;
549 d.height += padding.height;
556 void DrawWidget(
const Rect &r,
WidgetID widget)
const override
563 for (
const auto &song :
_music.music_set) {
577 for (
const auto &song :
_music.active_playlist) {
589 void OnClick([[maybe_unused]]
Point pt,
WidgetID widget, [[maybe_unused]]
int click_count)
override
606 ShowDropDownList(
this, BuildSetDropDownList<BaseMusic>(&selected), selected, widget);
621 void OnDropdownSelect(
WidgetID widget,
int index)
override
633 static constexpr
NWidgetPart _nested_music_track_selection_widgets[] = {
644 NWidget(
WWT_PANEL, COLOUR_GREY,
WID_MTS_LIST_LEFT),
SetFill(1, 1),
SetMinimalSize(180, 194),
SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK),
EndContainer(),
663 NWidget(
WWT_PANEL, COLOUR_GREY,
WID_MTS_LIST_RIGHT),
SetFill(1, 1),
SetMinimalSize(180, 194),
SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK),
EndContainer(),
670 static WindowDesc _music_track_selection_desc(
674 _nested_music_track_selection_widgets
677 static void ShowMusicTrackSelection()
679 AllocateWindowDescFront<MusicTrackSelectionWindow>(_music_track_selection_desc, 0);
689 UpdateDisabledButtons();
692 void UpdateDisabledButtons()
711 d.width += padding.width;
712 d.height += padding.height;
719 d.width += padding.width;
720 d.height += padding.height;
727 for (
const auto &song :
_music.music_set) {
731 d.width += padding.width;
732 d.height += padding.height;
745 void DrawWidget(
const Rect &r,
WidgetID widget)
const override
753 StringID str = STR_MUSIC_TRACK_NONE;
757 str = STR_MUSIC_TRACK_DIGIT;
765 StringID str = STR_MUSIC_TITLE_NONE;
768 str = STR_MUSIC_TITLE_NOMUSIC;
769 }
else if (
_music.IsPlaying()) {
770 str = STR_MUSIC_TITLE_NAME;
792 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
794 if (!gui_scope)
return;
795 for (
int i = 0; i < 6; i++) {
799 UpdateDisabledButtons();
808 void OnClick([[maybe_unused]]
Point pt,
WidgetID widget, [[maybe_unused]]
int click_count)
override
829 if (
ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, 0, INT8_MAX, 0, vol)) {
833 SetEffectVolume(vol);
854 ShowMusicTrackSelection();
859 _music.ChangePlaylist((MusicSystem::PlaylistChoices)(widget -
WID_M_ALL));
865 static constexpr
NWidgetPart _nested_music_window_widgets[] = {
888 NWidget(
WWT_EMPTY, COLOUR_GREY,
WID_M_MUSIC_VOL),
SetMinimalSize(67, 0),
SetPadding(2),
SetMinimalTextLines(1, 0),
SetFill(1, 0),
SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
892 NWidget(
WWT_EMPTY, COLOUR_GREY,
WID_M_EFFECT_VOL),
SetMinimalSize(67, 0),
SetPadding(2),
SetMinimalTextLines(1, 0),
SetFill(1, 0),
SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
933 _nested_music_window_widgets
936 void ShowMusicWindow()
938 AllocateWindowDescFront<MusicWindow>(_music_window_desc, 0);
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, bool instant_close, bool persist)
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, int 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.
@ SA_HOR_CENTER
Horizontally center the text.
@ FS_SMALL
Index of the small font in the font tables.
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Functions related to memory operations.
void MemSetT(T *ptr, uint8_t value, size_t num=1)
Type-safe version of memset().
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 const uint8_t 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, 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 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.
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
TextDirection _current_text_dir
Text direction of the currently selected language.
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Functions related to OTTD's strings.
@ TD_RTL
Text is written right-to-left by default.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
MusicSettings music
settings related to music/sound
Dimensions (a width and height) of a rectangle in 2D.
uint8_t effect_vol
The requested effects volume.
bool playing
Whether music is playing.
uint8_t music_vol
The requested music volume.
uint8_t custom_1[33]
The order of the first custom playlist.
uint8_t custom_2[33]
The order of the second custom playlist.
uint8_t playlist
The playlist (number) to play.
bool shuffle
Whether to shuffle the music.
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 displayed_playlist
current playlist as displayed in GUI, never in shuffled order
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 OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
Coordinates of a point in 2D.
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.
Data structure for an opened window.
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.
WidgetID mouse_capture_widget
ID of current mouse capture widget (e.g. dragged scrollbar). -1 if no widget has mouse capture.
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.
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.
@ WDP_AUTO
Find a place automatically.
@ WN_GAME_OPTIONS_GAME_OPTIONS
Game options.
int32_t WindowNumber
Number to differentiate different windows of the same class.
@ 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.