cp_loader_mod.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*************************************************************************/
  2. /* cp_loader_mod.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2020 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. #include "cp_loader_mod.h"
  31. static bool tag_equal_to(const char *p_tag, const char *p_string) {
  32. return (p_tag[0] == p_string[0] &&
  33. p_tag[1] == p_string[1] &&
  34. p_tag[2] == p_string[2] &&
  35. p_tag[3] == p_string[3]);
  36. }
  37. /* ProTracker period table */
  38. uint16_t period_table[6 * 12] = {
  39. 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 907,
  40. 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
  41. 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
  42. 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
  43. 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56,
  44. 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28
  45. };
  46. CPLoader::Error CPLoader_MOD::load_song(const char *p_file, CPSong *p_song, bool p_sampleset) {
  47. if (file->open(p_file, CPFileAccessWrapper::READ)) {
  48. //printf("Can't open file! %s\n",p_file);
  49. return FILE_CANNOT_OPEN;
  50. };
  51. /* FIRST OF ALL, one needs to read the .mod file format tag */
  52. file->seek(1080); //located at 1080
  53. char format_tag[4];
  54. file->get_byte_array((uint8_t *)format_tag, 4);
  55. int channels = -1;
  56. /** THE PAIN!! - COMPARE TAGS */
  57. /* Classic 4-chan */
  58. if (tag_equal_to(format_tag, "M.K."))
  59. channels = 4;
  60. if (tag_equal_to(format_tag, "FLT4"))
  61. channels = 4;
  62. if (tag_equal_to(format_tag, "M!K!"))
  63. channels = 4;
  64. /* 8 Channel MODS */
  65. if (tag_equal_to(format_tag, "FLT8"))
  66. channels = 2;
  67. if (tag_equal_to(format_tag, "CD81"))
  68. channels = 2;
  69. /* Custom channel MODS */
  70. for (int i = 1; i <= 32; i++) {
  71. if (i < 10) { // up to 9 channels mods
  72. /* Old Take Tracker */
  73. char old_take_tracker[4] = { 'T', 'D', 'Z', char('0' + i) };
  74. if (tag_equal_to(format_tag, old_take_tracker)) {
  75. channels = i;
  76. break;
  77. }
  78. /* Contemplates many XCHN Formats */
  79. char xchn[4] = { char('0' + i), 'C', 'H', 'N' };
  80. if (tag_equal_to(format_tag, xchn)) {
  81. channels = i;
  82. break;
  83. }
  84. }
  85. /* Fast Tracker */
  86. char fast_tracker[4] = { char('0' + (i / 10)), char('0' + (i % 10)), 'C', 'H' };
  87. if (tag_equal_to(format_tag, fast_tracker)) {
  88. channels = i;
  89. break;
  90. }
  91. }
  92. if (channels == -1) {
  93. file->close();
  94. return FILE_UNRECOGNIZED;
  95. }
  96. /** Load CPSong INFO */
  97. file->seek(0); //go to begining of file
  98. file->set_endian_conversion(true);
  99. p_song->reset();
  100. p_song->set_instruments(false);
  101. char name[21];
  102. file->get_byte_array((uint8_t *)name, 20);
  103. name[20] = 0;
  104. p_song->set_name(name);
  105. p_song->set_old_effects(true);
  106. p_song->set_linear_slides(false);
  107. p_song->set_compatible_gxx(true);
  108. CPSampleManager *sm = CPSampleManager::get_singleton();
  109. int instruments = 31;
  110. for (int i = 0; i < instruments; i++) {
  111. char sample_name[23];
  112. file->get_byte_array((uint8_t *)sample_name, 22);
  113. sample_name[22] = 0;
  114. uint32_t sample_len = file->get_word();
  115. sample_len <<= 1;
  116. uint8_t fine_nibble = file->get_byte() & 0xF;
  117. //(int8_t)(fine_nibble & 7) - (int8_t)(fine_nibble & 8); //yesso's genius trick
  118. // boo, I can't use it :( but i leave it here because of how cool it is
  119. uint8_t linear_volume = file->get_byte(); //0 .. ?
  120. uint32_t loop_begin = file->get_word(); //0 .. ?
  121. loop_begin <<= 1;
  122. uint32_t loop_end = file->get_word(); //0 .. ?
  123. loop_end <<= 1;
  124. if (sample_len > 0) {
  125. CPSample_ID sid = sm->create(false, false, sample_len);
  126. if (sid.is_null()) {
  127. file->close();
  128. return FILE_OUT_OF_MEMORY;
  129. }
  130. if (loop_end > 2) {
  131. sm->set_loop_begin(sid, loop_begin);
  132. sm->set_loop_end(sid, loop_end + loop_begin);
  133. sm->set_loop_type(sid, CP_LOOP_FORWARD);
  134. }
  135. static const uint16_t fine_to_freq[16] = {
  136. 8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757,
  137. 7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280
  138. };
  139. sm->set_c5_freq(sid, fine_to_freq[fine_nibble]);
  140. p_song->get_sample(i)->set_sample_data(sid);
  141. }
  142. p_song->get_sample(i)->set_name(sample_name);
  143. p_song->get_sample(i)->set_default_volume(linear_volume);
  144. }
  145. /* pan for MODs */
  146. for (int i = 0; i < channels; i++)
  147. p_song->set_channel_pan(i, (((i & 3) == 1) || ((i & 3) == 2)) ? 0 : 64);
  148. uint8_t order_count = file->get_byte();
  149. // uint8_t loop_to=file->get_byte();
  150. int pattern_count = 0;
  151. for (int i = 0; i < 128; i++) {
  152. uint8_t order = file->get_byte();
  153. if (i < order_count) {
  154. p_song->set_order(i, order);
  155. /* Determine the amount of patterns */
  156. if ((order + 1) > pattern_count)
  157. pattern_count = order + 1;
  158. } else
  159. p_song->set_order(i, CP_ORDER_NONE);
  160. }
  161. if (instruments == 31)
  162. file->get_dword(); // identiefier, now skip it
  163. for (int i = 0; i < pattern_count; i++) {
  164. for (int line = 0; line < 64; line++) {
  165. for (int column = 0; column < channels; column++) {
  166. uint32_t note_w = file->get_dword();
  167. CPNote note;
  168. note.instrument = (note_w >> 12) & 0xF;
  169. note.instrument |= (note_w >> 24) & 0xF0;
  170. if (note.instrument == 0)
  171. note.instrument = CPNote::EMPTY;
  172. else
  173. note.instrument--;
  174. note.parameter = note_w & 0xFF;
  175. int cmd = (note_w >> 8) & 0xF;
  176. uint32_t period = (note_w >> 16) & 0xFFF;
  177. if (period > 0 && period < 0xFFF) {
  178. //period>>=2;
  179. //period<<=1;
  180. for (int n = 0; n < 6 * 12; n++) {
  181. if (period >= period_table[n]) {
  182. if ((period != period_table[n]) && (n)) {
  183. uint32_t p1 = period_table[n - 1];
  184. uint32_t p2 = period_table[n];
  185. if (p1 - period < (period - p2)) {
  186. note.note = n + 36;
  187. break;
  188. }
  189. }
  190. note.note = n + 1 + 36;
  191. break;
  192. }
  193. }
  194. if (note.note == CPNote::EMPTY)
  195. note.note = 6 * 12 + 36;
  196. note.note--;
  197. }
  198. switch (cmd) {
  199. case 0x0: {
  200. if (note.parameter > 0)
  201. note.command = 'J' - 'A';
  202. } break;
  203. case 0x1: {
  204. note.command = 'F' - 'A';
  205. } break;
  206. case 0x2: {
  207. note.command = 'E' - 'A';
  208. } break;
  209. case 0x3: {
  210. note.command = 'G' - 'A';
  211. } break;
  212. case 0x4: {
  213. note.command = 'H' - 'A';
  214. } break;
  215. case 0x5: {
  216. note.command = 'L' - 'A';
  217. } break;
  218. case 0x6: {
  219. note.command = 'K' - 'A';
  220. } break;
  221. case 0x7: {
  222. note.command = 'R' - 'A';
  223. } break;
  224. case 0x8: {
  225. note.command = 'X' - 'A';
  226. } break;
  227. case 0x9: {
  228. note.command = 'O' - 'A';
  229. } break;
  230. case 0xA: {
  231. note.command = 'D' - 'A';
  232. } break;
  233. case 0xB: {
  234. note.command = 'B' - 'A';
  235. } break;
  236. case 0xC: {
  237. note.volume = note.parameter;
  238. if (note.volume > 64)
  239. note.volume = 64;
  240. note.parameter = 0;
  241. } break;
  242. case 0xD: {
  243. note.command = 'C' - 'A';
  244. note.parameter = (note.parameter >> 4) * 10 + (note.parameter & 0xF);
  245. } break;
  246. case 0xE: { //SPECIAL EFFECT!
  247. note.command = 'S' - 'A';
  248. switch (note.parameter >> 4) {
  249. case 0x1: {
  250. note.command = 'F' - 'A';
  251. note.parameter = 0xF0 | (note.parameter & 0xF);
  252. } break;
  253. case 0x2: {
  254. note.command = 'E' - 'A';
  255. note.parameter = 0xF0 | (note.parameter & 0xF);
  256. } break;
  257. case 0x4: {
  258. note.command = 'S' - 'A';
  259. note.parameter = 0x30 | (note.parameter & 0x3);
  260. } break;
  261. case 0x6: {
  262. note.command = 'S' - 'A';
  263. note.parameter = 0xB0 | (note.parameter & 0xF);
  264. } break;
  265. case 0x7: {
  266. note.command = 'S' - 'A';
  267. note.parameter = 0x40 | (note.parameter & 0x3);
  268. } break;
  269. case 0x8: {
  270. note.command = 'S' - 'A'; // wow, it's the same!
  271. } break;
  272. case 0x9: {
  273. note.command = 'Q' - 'A';
  274. note.parameter = (note.parameter & 0xF);
  275. } break;
  276. case 0xA: {
  277. note.command = 'D' - 'A';
  278. note.parameter = 0xF | ((note.parameter & 0xF) << 4);
  279. } break;
  280. case 0xB: {
  281. note.command = 'D' - 'A';
  282. note.parameter = 0xF0 | (note.parameter & 0xF);
  283. } break;
  284. case 0xC:
  285. case 0xD: {
  286. note.command = 'S' - 'A'; //wow, they are the same!
  287. } break;
  288. case 0xE: {
  289. note.command = 'S' - 'A';
  290. note.parameter = 0x60 | (note.parameter & 0xF);
  291. } break;
  292. default: {
  293. note.command = CPNote::EMPTY;
  294. note.parameter = 0;
  295. } break;
  296. }
  297. } break;
  298. case 0xF: {
  299. if (note.parameter < 32)
  300. note.command = 'A' - 'A';
  301. else
  302. note.command = 'T' - 'A';
  303. } break;
  304. }
  305. p_song->get_pattern(i)->set_note(column, line, note);
  306. }
  307. }
  308. }
  309. for (int i = 0; i < instruments; i++) {
  310. CPSample_ID sid = p_song->get_sample(i)->get_sample_data();
  311. if (sid.is_null()) {
  312. continue; //empty sample, not stored?
  313. }
  314. sm->lock_data(sid);
  315. uint8_t *dataptr = (uint8_t *)sm->get_data(sid);
  316. int len = sm->get_size(sid);
  317. for (int s = 0; s < len; s++) {
  318. uint8_t d = file->get_byte();
  319. //d-=128; //convert to signed
  320. int8_t *ds = (int8_t *)&d;
  321. dataptr[s] = *ds;
  322. }
  323. sm->unlock_data(sid);
  324. }
  325. file->close();
  326. return FILE_OK;
  327. }
  328. CPLoader_MOD::CPLoader_MOD(CPFileAccessWrapper *p_file) {
  329. file = p_file;
  330. }
  331. CPLoader_MOD::~CPLoader_MOD() {
  332. }