sequence.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "sequence.h"
  2. void delete_sequence_step(FlizzerTrackerApp* tracker) {
  3. uint8_t sequence_position = tracker->tracker_engine.sequence_position;
  4. uint8_t* pattern = &tracker->tracker_engine.song->sequence.sequence_step[sequence_position]
  5. .pattern_indices[tracker->current_channel];
  6. *pattern = 0;
  7. }
  8. void edit_sequence_step(FlizzerTrackerApp* tracker, int8_t delta) {
  9. uint8_t digit = tracker->current_digit;
  10. uint8_t sequence_position = tracker->tracker_engine.sequence_position;
  11. uint8_t pattern_index = tracker->tracker_engine.song->sequence.sequence_step[sequence_position]
  12. .pattern_indices[tracker->current_channel];
  13. uint8_t* pattern = &tracker->tracker_engine.song->sequence.sequence_step[sequence_position]
  14. .pattern_indices[tracker->current_channel];
  15. uint8_t temp_pattern = *pattern;
  16. switch(digit) {
  17. case 0: // upper nibble
  18. {
  19. int8_t nibble = ((pattern_index & 0xf0) >> 4);
  20. if(nibble + delta < 0) {
  21. nibble = 0xf;
  22. }
  23. else if(nibble + delta > 0xf) {
  24. nibble = 0;
  25. }
  26. else {
  27. nibble += delta;
  28. }
  29. temp_pattern &= 0x0f;
  30. temp_pattern |= (nibble << 4);
  31. break;
  32. }
  33. case 1: // lower nibble
  34. {
  35. int8_t nibble = (pattern_index & 0x0f);
  36. if(nibble + delta < 0) {
  37. nibble = 0xf;
  38. }
  39. else if(nibble + delta > 0xf) {
  40. nibble = 0;
  41. }
  42. else {
  43. nibble += delta;
  44. }
  45. temp_pattern &= 0xf0;
  46. temp_pattern |= nibble;
  47. break;
  48. }
  49. }
  50. if(check_and_allocate_pattern(&tracker->song, temp_pattern)) {
  51. *pattern = temp_pattern;
  52. }
  53. }
  54. void sequence_edit_event(FlizzerTrackerApp* tracker, FlizzerTrackerEvent* event) {
  55. if(event->input.key == InputKeyOk && event->input.type == InputTypeShort &&
  56. !tracker->tracker_engine.playing) {
  57. tracker->editing = !tracker->editing;
  58. }
  59. if(event->input.key == InputKeyOk && event->input.type == InputTypeLong) {
  60. if(!(tracker->editing)) {
  61. if(tracker->tracker_engine.playing) {
  62. stop_song(tracker);
  63. }
  64. else {
  65. if(tracker->tracker_engine.pattern_position == tracker->song.pattern_length - 1 &&
  66. tracker->tracker_engine.sequence_position ==
  67. tracker->song.num_sequence_steps -
  68. 1) // if we are at the very end of the song
  69. {
  70. stop_song(tracker);
  71. }
  72. else {
  73. play_song(tracker, true);
  74. }
  75. }
  76. }
  77. }
  78. if(event->input.key == InputKeyRight && event->input.type == InputTypeShort) {
  79. tracker->current_digit++;
  80. if(tracker->current_digit > 1) {
  81. tracker->current_channel++;
  82. tracker->current_digit = 0;
  83. if(tracker->current_channel > SONG_MAX_CHANNELS - 1) {
  84. tracker->current_channel = 0;
  85. }
  86. }
  87. }
  88. if(event->input.key == InputKeyLeft && event->input.type == InputTypeShort) {
  89. tracker->current_digit--;
  90. if(tracker->current_digit > 1) // unsigned int overflow
  91. {
  92. tracker->current_channel--;
  93. tracker->current_digit = 1;
  94. if(tracker->current_channel > SONG_MAX_CHANNELS - 1) // unsigned int overflow
  95. {
  96. tracker->current_channel = SONG_MAX_CHANNELS - 1;
  97. }
  98. }
  99. }
  100. if(event->input.key == InputKeyDown && event->input.type == InputTypeShort) {
  101. if(!(tracker->editing)) {
  102. tracker->tracker_engine.sequence_position++;
  103. if(tracker->tracker_engine.sequence_position >=
  104. tracker->tracker_engine.song->num_sequence_steps) {
  105. tracker->tracker_engine.sequence_position = 0;
  106. }
  107. }
  108. if(tracker->editing) {
  109. edit_sequence_step(tracker, -1);
  110. }
  111. }
  112. if(event->input.key == InputKeyUp && event->input.type == InputTypeShort) {
  113. if(!(tracker->editing)) {
  114. int16_t temp_sequence_position = tracker->tracker_engine.sequence_position - 1;
  115. if(temp_sequence_position < 0) {
  116. tracker->tracker_engine.sequence_position =
  117. tracker->tracker_engine.song->num_sequence_steps - 1;
  118. }
  119. else {
  120. tracker->tracker_engine.sequence_position--;
  121. }
  122. }
  123. if(tracker->editing) {
  124. edit_sequence_step(tracker, 1);
  125. }
  126. }
  127. if(event->input.key == InputKeyRight && event->input.type == InputTypeLong &&
  128. !(tracker->editing)) // set loop begin or loop end for the song
  129. {
  130. TrackerSong* song = &tracker->song;
  131. if(song->loop_start == song->loop_end && song->loop_end == 0) // if both are 0
  132. {
  133. song->loop_end = tracker->tracker_engine.sequence_position;
  134. }
  135. else {
  136. if(tracker->tracker_engine.sequence_position < song->loop_end) {
  137. song->loop_start = tracker->tracker_engine.sequence_position;
  138. }
  139. if(tracker->tracker_engine.sequence_position > song->loop_start) {
  140. song->loop_end = tracker->tracker_engine.sequence_position;
  141. }
  142. }
  143. }
  144. if(event->input.key == InputKeyLeft && event->input.type == InputTypeLong &&
  145. !(tracker->editing)) // erase loop begin and loop end points
  146. {
  147. TrackerSong* song = &tracker->song;
  148. song->loop_start = song->loop_end = 0;
  149. }
  150. if(event->input.key == InputKeyUp && event->input.type == InputTypeLong &&
  151. !(tracker->editing)) // jump to the beginning
  152. {
  153. tracker->tracker_engine.sequence_position = 0;
  154. }
  155. if(event->input.key == InputKeyDown && event->input.type == InputTypeLong &&
  156. !(tracker->editing)) // jump to the end
  157. {
  158. tracker->tracker_engine.sequence_position = tracker->song.num_sequence_steps - 1;
  159. }
  160. if(event->input.key == InputKeyBack && event->input.type == InputTypeShort &&
  161. tracker->editing) {
  162. delete_sequence_step(tracker);
  163. }
  164. }