1 /*************************************************************************/
2 /* cp_player_data_control.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30
31 #include "cp_player_data.h"
32
play_start_pattern(int p_pattern)33 void CPPlayer::play_start_pattern(int p_pattern) {
34
35 play_start(p_pattern, -1, -1);
36 }
37
play_start_song()38 void CPPlayer::play_start_song() {
39
40 play_start(-1, -1, -1);
41 }
42
play_start_song_from_order(int p_order)43 void CPPlayer::play_start_song_from_order(int p_order) {
44
45 play_start(-1, p_order, -1);
46 }
47
play_start_song_from_order_and_row(int p_order,int p_row)48 void CPPlayer::play_start_song_from_order_and_row(int p_order, int p_row) {
49
50 play_start(-1, p_order, p_row);
51 }
52
play_start(int p_pattern,int p_order,int p_row,bool p_lock)53 void CPPlayer::play_start(int p_pattern, int p_order, int p_row, bool p_lock) {
54
55 if (control.play_mode != PLAY_NOTHING) play_stop();
56
57 reset();
58
59 if (p_pattern != -1) {
60
61 control.play_mode = PLAY_PATTERN;
62 control.position.current_pattern = p_pattern;
63 control.position.current_row = (p_row != -1) ? p_row : 0;
64
65 } else {
66
67 control.position.current_order = get_song_next_order_idx(song, (p_order == -1) ? p_order : p_order - 1);
68 if (control.position.current_order != -1) {
69
70 control.play_mode = PLAY_SONG;
71 control.position.current_pattern = song->get_order(control.position.current_order);
72 control.position.current_row = (p_row != -1) ? p_row : 0;
73 }
74 }
75
76 control.reached_end = (control.play_mode == PLAY_NOTHING);
77 }
78
play_stop()79 void CPPlayer::play_stop() {
80
81 int i;
82
83 control.play_mode = PLAY_NOTHING;
84
85 for (i = 0; i < control.max_voices; i++) {
86
87 voice[i].reset();
88 mixer->stop_voice(i);
89 }
90
91 for (i = 0; i < CPPattern::WIDTH; i++) {
92
93 control.channel[i].reset();
94 }
95
96 reset();
97 }
98
play_note(int p_channel,CPNote note,bool p_reserve)99 void CPPlayer::play_note(int p_channel, CPNote note, bool p_reserve) {
100
101 if (control.play_mode == PLAY_NOTHING) {
102
103 control.ticks_counter = 0;
104 }
105
106 /*control.channel[p_channel].reset();
107 control.channel[p_channel].channel_volume=song->get_channel_volume(p_channel);
108 control.channel[p_channel].channel_panning=((int)song->get_channel_pan( p_channel)*255/64);*/
109 if (p_reserve) {
110 control.channel[p_channel].mute = false;
111 control.channel[p_channel].reserved = true;
112 } else {
113
114 control.channel[p_channel].reserved = false;
115 }
116 process_note(p_channel, note);
117 }
118
get_voice_volume(int p_voice)119 int CPPlayer::get_voice_volume(int p_voice) {
120
121 return voice[p_voice].display_volume;
122 }
123
get_voice_envelope_pos(int p_voice,CPEnvelope * p_envelope)124 int CPPlayer::get_voice_envelope_pos(int p_voice, CPEnvelope *p_envelope) {
125
126 int i, tmp_index = -1;
127
128 i = p_voice;
129
130 if ((song->has_instruments()) && (voice[i].instrument_ptr != NULL) && (voice[i].fadeout_volume > 0)) {
131
132 if ((p_envelope == voice[i].instrument_ptr->get_volume_envelope()) && (voice[i].instrument_ptr->get_volume_envelope()->is_enabled())) {
133
134 tmp_index = voice[i].volume_envelope_ctrl.pos_index;
135 }
136
137 if ((p_envelope == voice[i].instrument_ptr->get_pan_envelope()) && (voice[i].instrument_ptr->get_pan_envelope()->is_enabled())) {
138
139 tmp_index = voice[i].panning_envelope_ctrl.pos_index;
140 }
141
142 if ((p_envelope == voice[i].instrument_ptr->get_pitch_filter_envelope()) && (voice[i].instrument_ptr->get_pitch_filter_envelope()->is_enabled())) {
143
144 tmp_index = voice[i].pitch_envelope_ctrl.pos_index;
145 }
146 }
147
148 return tmp_index;
149 }
150
goto_next_order()151 void CPPlayer::goto_next_order() {
152
153 if (control.play_mode != PLAY_SONG) return;
154
155 control.position.current_row = 0;
156
157 control.position.current_order = get_song_next_order_idx(song, control.position.current_order);
158
159 if (control.position.current_order == -1) {
160
161 reset();
162 }
163
164 control.position.current_pattern = song->get_order(control.position.current_order);
165 }
goto_previous_order()166 void CPPlayer::goto_previous_order() {
167
168 if (control.play_mode != PLAY_SONG) return;
169
170 int next_order, current_order;
171
172 control.position.current_row = 0;
173
174 current_order = control.position.current_order;
175
176 next_order = get_song_next_order_idx(song, current_order);
177
178 while ((next_order != control.position.current_order) && (next_order != -1)) {
179
180 current_order = next_order;
181 next_order = get_song_next_order_idx(song, current_order);
182 }
183
184 if (next_order == -1) {
185
186 reset();
187 } else {
188
189 control.position.current_order = current_order;
190 control.position.current_pattern = song->get_order(control.position.current_order);
191 }
192 }
193
get_channel_voice(int p_channel)194 int CPPlayer::get_channel_voice(int p_channel) {
195
196 if (control.channel[p_channel].slave_voice == NULL)
197 return -1;
198 else
199 return control.channel[p_channel].slave_voice_index;
200 }
201
get_voice_sample_name(int p_voice)202 const char *CPPlayer::get_voice_sample_name(int p_voice) {
203
204 const char *name = NULL;
205
206 if (!voice[p_voice].sample_ptr) name = voice[p_voice].sample_ptr->get_name();
207
208 return name;
209 }
210
is_voice_active(int p_voice)211 bool CPPlayer::is_voice_active(int p_voice) {
212
213 return !(((voice[p_voice].kick == KICK_NOTHING) || (voice[p_voice].kick == KICK_ENVELOPE)) && !mixer->is_voice_active(p_voice));
214 }
215
get_voice_envelope_pos(int p_voice,CPInstrument::EnvelopeType p_env_type)216 int CPPlayer::get_voice_envelope_pos(int p_voice, CPInstrument::EnvelopeType p_env_type) {
217
218 if (!is_voice_active(p_voice))
219 return -1;
220
221 Voice_Control::Envelope_Control *env = 0;
222
223 switch (p_env_type) {
224
225 case CPInstrument::VOLUME_ENVELOPE: env = &voice[p_voice].volume_envelope_ctrl; break;
226 case CPInstrument::PAN_ENVELOPE: env = &voice[p_voice].panning_envelope_ctrl; break;
227 case CPInstrument::PITCH_ENVELOPE: env = &voice[p_voice].pitch_envelope_ctrl; break;
228 }
229
230 if (!env)
231 return -1;
232
233 if (!env->active || env->terminated)
234 return -1;
235
236 return env->pos_index;
237 }
238
get_voice_envelope(int p_voice,CPInstrument::EnvelopeType p_env_type)239 CPEnvelope *CPPlayer::get_voice_envelope(int p_voice, CPInstrument::EnvelopeType p_env_type) {
240
241 CPInstrument *ins = voice[p_voice].instrument_ptr;
242
243 if (!ins)
244 return 0;
245
246 switch (p_env_type) {
247
248 case CPInstrument::VOLUME_ENVELOPE: return ins->get_volume_envelope();
249 case CPInstrument::PAN_ENVELOPE: return ins->get_pan_envelope();
250 case CPInstrument::PITCH_ENVELOPE: return ins->get_pitch_filter_envelope();
251 };
252
253 return 0;
254 }
255
get_voice_instrument_name(int p_voice)256 const char *CPPlayer::get_voice_instrument_name(int p_voice) {
257
258 const char *name = NULL;
259
260 if (voice[p_voice].instrument_ptr != NULL) name = voice[p_voice].instrument_ptr->get_name();
261
262 return name;
263 }
set_filters_enabled(bool p_enable)264 void CPPlayer::set_filters_enabled(bool p_enable) {
265
266 control.filters = p_enable;
267 }
268
get_voice_sample_index(int p_voice)269 int CPPlayer::get_voice_sample_index(int p_voice) {
270
271 return voice[p_voice].sample_index;
272 }
273