From a2a02bc853ef819e947e3028b5ba33b375a97c8f Mon Sep 17 00:00:00 2001 From: terencehill Date: Sun, 15 Apr 2012 15:58:57 +0200 Subject: [PATCH] Music player in the menu to play the various tracks of the game --- qcsrc/menu/classes.c | 2 + qcsrc/menu/xonotic/dialog_multiplayer.c | 3 +- .../xonotic/dialog_multiplayer_musicplayer.c | 61 +++++ qcsrc/menu/xonotic/soundlist.c | 239 ++++++++++++++++++ 4 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 qcsrc/menu/xonotic/dialog_multiplayer_musicplayer.c create mode 100644 qcsrc/menu/xonotic/soundlist.c diff --git a/qcsrc/menu/classes.c b/qcsrc/menu/classes.c index f838257c5..dfa7ebe7b 100644 --- a/qcsrc/menu/classes.c +++ b/qcsrc/menu/classes.c @@ -88,6 +88,8 @@ #include "xonotic/weaponslist.c" #include "xonotic/dialog_multiplayer_demo.c" #include "xonotic/demolist.c" +#include "xonotic/dialog_multiplayer_musicplayer.c" +#include "xonotic/soundlist.c" #include "xonotic/colorpicker.c" #include "xonotic/colorpicker_string.c" #include "xonotic/cvarlist.c" diff --git a/qcsrc/menu/xonotic/dialog_multiplayer.c b/qcsrc/menu/xonotic/dialog_multiplayer.c index 2c86f79c3..f94148157 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer.c +++ b/qcsrc/menu/xonotic/dialog_multiplayer.c @@ -5,7 +5,7 @@ CLASS(XonoticMultiplayerDialog) EXTENDS(XonoticDialog) ATTRIB(XonoticMultiplayerDialog, color, vector, SKINCOLOR_DIALOG_MULTIPLAYER) ATTRIB(XonoticMultiplayerDialog, intendedWidth, float, 0.96) ATTRIB(XonoticMultiplayerDialog, rows, float, 24) - ATTRIB(XonoticMultiplayerDialog, columns, float, 4) + ATTRIB(XonoticMultiplayerDialog, columns, float, 5) ENDCLASS(XonoticMultiplayerDialog) #endif @@ -18,6 +18,7 @@ void XonoticMultiplayerDialog_fill(entity me) me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Servers"), makeXonoticServerListTab())); me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Create"), makeXonoticServerCreateTab())); me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Demos"), makeXonoticDemoBrowserTab())); + me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Music Player"), makeXonoticMusicPlayerTab())); me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Player Setup"), makeXonoticPlayerSettingsTab())); me.TR(me); diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_musicplayer.c b/qcsrc/menu/xonotic/dialog_multiplayer_musicplayer.c new file mode 100644 index 000000000..b2f72bca1 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_musicplayer.c @@ -0,0 +1,61 @@ +#ifdef INTERFACE +CLASS(XonoticMusicPlayerTab) EXTENDS(XonoticTab) + METHOD(XonoticMusicPlayerTab, fill, void(entity)) + ATTRIB(XonoticMusicPlayerTab, title, string, _("Music")) + ATTRIB(XonoticMusicPlayerTab, intendedWidth, float, 0.9) + ATTRIB(XonoticMusicPlayerTab, rows, float, 22) + ATTRIB(XonoticMusicPlayerTab, columns, float, 4) + ATTRIB(XonoticMusicPlayerTab, name, string, "MusicPlayer") +ENDCLASS(XonoticMusicPlayerTab) +entity makeXonoticMusicPlayerTab(); +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticMusicPlayerTab() +{ + entity me; + me = spawnXonoticMusicPlayerTab(); + me.configureDialog(me); + return me; +} +void XonoticMusicPlayerTab_fill(entity me) +{ + entity e; + entity btn; + entity soundList; + + me.TR(me); + me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "music_playlist_random0", _("Random order"))); + me.TR(me); + me.TR(me); + me.TD(me, 1, 0.5, e = makeXonoticTextLabel(0, _("Filter:"))); + me.TD(me, 1, 0.5, btn = makeXonoticButton(_("Clear"), '0 0 0')); + btn.onClick = InputBox_Clear_Click; + me.TD(me, 1, 3, e = makeXonoticInputBox(0, string_null)); + soundList = makeXonoticSoundList(); + e.onChange = SoundList_Filter_Change; + e.onChangeEntity = soundList; + btn.onClickEntity = e; + soundList.controlledTextbox = e; + + me.TR(me); + me.TD(me, me.rows - 4, me.columns, soundList); + + me.gotoRC(me, me.rows - 1, 0); + me.TD(me, 1, me.columns / 5, e = makeXonoticButton(ZCTX(_("MP^Stop")), '0 0 0')); + e.onClick = StopSound_Click; + e.onClickEntity = soundList; + me.TD(me, 1, me.columns / 5, e = makeXonoticButton(ZCTX(_("MP^Play")), '0 0 0')); + e.onClick = StartSound_Click; + e.onClickEntity = soundList; + me.TD(me, 1, me.columns / 5, e = makeXonoticButton(ZCTX(_("MP^Pause/Play")), '0 0 0')); + e.onClick = PauseSound_Click; + e.onClickEntity = soundList; + me.TD(me, 1, me.columns / 5, e = makeXonoticButton(ZCTX(_("MP^Prev")), '0 0 0')); + e.onClick = PrevSound_Click; + e.onClickEntity = soundList; + me.TD(me, 1, me.columns / 5, e = makeXonoticButton(ZCTX(_("MP^Next")), '0 0 0')); + e.onClick = NextSound_Click; + e.onClickEntity = soundList; +} +#endif diff --git a/qcsrc/menu/xonotic/soundlist.c b/qcsrc/menu/xonotic/soundlist.c new file mode 100644 index 000000000..32a35e341 --- /dev/null +++ b/qcsrc/menu/xonotic/soundlist.c @@ -0,0 +1,239 @@ +#ifdef INTERFACE +CLASS(XonoticSoundList) EXTENDS(XonoticListBox) + METHOD(XonoticSoundList, configureXonoticSoundList, void(entity)) + ATTRIB(XonoticSoundList, rowsPerItem, float, 1) + METHOD(XonoticSoundList, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(XonoticSoundList, drawListBoxItem, void(entity, float, vector, float)) + METHOD(XonoticSoundList, getSounds, void(entity)) + METHOD(XonoticSoundList, stopSound, void(entity)) + METHOD(XonoticSoundList, startSound, void(entity, float)) + METHOD(XonoticSoundList, pauseSound, void(entity)) + METHOD(XonoticSoundList, soundName, string(entity, float)) + METHOD(XonoticSoundList, clickListBoxItem, void(entity, float, vector)) + METHOD(XonoticSoundList, keyDown, float(entity, float, float, float)) + METHOD(XonoticSoundList, destroy, void(entity)) + METHOD(XonoticSoundList, showNotify, void(entity)) + + ATTRIB(XonoticSoundList, listSound, float, -1) + ATTRIB(XonoticSoundList, realFontSize, vector, '0 0 0') + ATTRIB(XonoticSoundList, columnNameOrigin, float, 0) + ATTRIB(XonoticSoundList, columnNameSize, float, 0) + ATTRIB(XonoticSoundList, realUpperMargin, float, 0) + ATTRIB(XonoticSoundList, origin, vector, '0 0 0') + ATTRIB(XonoticSoundList, itemAbsSize, vector, '0 0 0') + + ATTRIB(XonoticSoundList, lastClickedSound, float, -1) + ATTRIB(XonoticSoundList, lastClickedTime, float, 0) + ATTRIB(XonoticSoundList, filterString, string, string_null) +ENDCLASS(XonoticSoundList) + +entity makeXonoticSoundList(); +void StopSound_Click(entity btn, entity me); +void StartSound_Click(entity btn, entity me); +void PauseSound_Click(entity btn, entity me); +void PrevSound_Click(entity btn, entity me); +void NextSound_Click(entity btn, entity me); +void SoundList_Filter_Change(entity box, entity me); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticSoundList() +{ + entity me; + me = spawnXonoticSoundList(); + me.configureXonoticSoundList(me); + return me; +} + +void XonoticSoundList_configureXonoticSoundList(entity me) +{ + me.configureXonoticListBox(me); + me.getSounds(me); +} + +string XonoticSoundList_soundName(entity me, float i ) +{ + string s; + s = search_getfilename(me.listSound, i); + s = substring(s, 15, strlen(s) - 15 - 4); // sound/cdtracks/, .ogg + return s; +} + + +void XonoticSoundList_getSounds(entity me) +{ + string s; + float i; + + if(me.filterString) + //subdirectory in filterString allowed + s=strcat("sound/cdtracks/*", me.filterString, "*.ogg"); + else + s="sound/cdtracks/*.ogg"; + + if(me.listSound >= 0) + search_end(me.listSound); + + me.listSound = search_begin(s, FALSE, TRUE); + + if(me.listSound < 0) + me.nItems=0; + else + me.nItems=search_getsize(me.listSound); + + cvar_set("music_playlist_list0", ""); + s = ""; + for(i=0; i 0)) + s = ">"; + draw_Text(me.realUpperMargin * eY, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); + } + + s = me.soundName(me,i); + s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize); + draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); +} + +void XonoticSoundList_showNotify(entity me) +{ + me.getSounds(me); +} + +void SoundList_Filter_Change(entity box, entity me) +{ + if(me.filterString) + strunzone(me.filterString); + + if(box.text != "") + me.filterString = strzone(box.text); + else + me.filterString = string_null; + + me.getSounds(me); +} + +void XonoticSoundList_stopSound(entity me) +{ + // STOP: list 0 is disabled by setting the index to 999 + // we set sampleposition0 to -1 to indicate that music is stopped + cvar_set("music_playlist_index", "999"); + localcmd("wait; music_playlist_sampleposition0 -1\n"); +} + +void StopSound_Click(entity btn, entity me) +{ + me.stopSound(me); +} + +void XonoticSoundList_startSound(entity me, float offset) +{ + float f; + if(offset) + { + f = bound(0, cvar("music_playlist_current0") + offset, me.nItems - 1); + if(f == cvar("music_playlist_current0")) + return; + } + else + f = me.selectedItem; + // START: list 0 is disabled by setting the index to 999 + // we set current0 to the selected track and sampleposition0 to 0 to forget value saved by the engine + // then we switch back to list 0 + cvar_set("music_playlist_index", "999"); + cvar_set("music_playlist_current0", ftos(f)); + localcmd("wait; music_playlist_sampleposition0 0; wait; music_playlist_index 0\n"); +} + +void StartSound_Click(entity btn, entity me) +{ + me.startSound(me, 0); +} + +void PrevSound_Click(entity btn, entity me) +{ + me.startSound(me, -1); +} + +void NextSound_Click(entity btn, entity me) +{ + me.startSound(me, +1); +} + +void XonoticSoundList_pauseSound(entity me) +{ + // PAUSE: list 0 is disabled by setting the index to 999 + // (we know the track is paused because the engine sets sampleposition0 to remember current position) + // RESUME: list 0 is enabled by setting the index to 0 + // (we reset sampleposition0 to 0 to mark the track as in playing back state) + if(cvar("music_playlist_index") == 0) + localcmd("music_playlist_index 999"); + else + localcmd("music_playlist_index 0; wait; music_playlist_sampleposition0 0\n"); +} + +void PauseSound_Click(entity btn, entity me) +{ + me.pauseSound(me); +} + +void XonoticSoundList_clickListBoxItem(entity me, float i, vector where) +{ + if(i == me.lastClickedSound) + if(time < me.lastClickedTime + 0.3) + { + // DOUBLE CLICK! + me.setSelected(me, i); + me.startSound(me, 0); + } + me.lastClickedSound = i; + me.lastClickedTime = time; +} + +float XonoticSoundList_keyDown(entity me, float scan, float ascii, float shift) +{ + if(scan == K_ENTER || scan == K_KP_ENTER) { + me.startSound(me, 0); + return 1; + } + else if(scan == K_SPACE) { + me.pauseSound(me); + return 1; + } + else + return SUPER(XonoticSoundList).keyDown(me, scan, ascii, shift); +} +#endif + -- 2.39.2