Advertisement
Moolah60

e+ Sequence Header Commands WIP

Apr 8th, 2019
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.01 KB | None | 0 0
  1. struct group;
  2. struct macro {
  3.     u8* data;
  4.     u8* stack[4];
  5.     s8 stackArgs[4];
  6.     s8 stackIdx;
  7.     s8 unk;
  8. }
  9.  
  10. typedef char s8;
  11. typedef unsigned char u8;
  12. typedef short s16;
  13. typedef unsigned short u16;
  14. typedef int s32;
  15. typedef unsigned int u32;
  16.  
  17. u16 Nas_ReadLengthData(macro* macro) {
  18.     u16 data = *macro->data;
  19.     macro->data++;
  20.     if ((data & 0x80) != 0) {
  21.         data = ((data & 0x7F) << 8) | *macro->data;
  22.         macro->data++;
  23.     }
  24.    
  25.     return data;
  26. }
  27.  
  28. // 0x0X
  29. void SeqHeaderCmd_0X(group* group, macro* macro, u8 cmd) {
  30.     group->macro.char_0x19 = (group->subTracks[cmd & 0xF]->flags >> 7) ^ 1;
  31. }
  32.  
  33. // 0x4X
  34. // Releases a sub-track. (Sub sequence aka. channel)
  35. void SeqHeaderCmd_4X(group* group, macro* macro, u8 cmd) {
  36.     Nas_ReleaseSubTrack(group->subTracks[cmd & 0xF];
  37. }
  38.  
  39. // 0x5X
  40. void SeqHeaderCmd_5X(group* group, macro* macro, u8 cmd) {
  41.     group->macro.char_0x19 -= group->pChar_0x15C[cmd & 0xF];
  42. }
  43.  
  44. // 0x6X
  45. void SeqHeaderCmd_6X(group* group, macro* macro, u8 cmd) {
  46.     MK_load(Nas_ReadByteData(macro), Nas_ReadByteData(macro), group->pChar_0x15C[cmd & 0xF]);
  47. }
  48.  
  49. // 0x7X
  50. void SeqHeaderCmd_7X(group* group, macro* macro, u8 cmd) {
  51.     group->pChar_0x15C[cmd & 0xF] = group->macro.char_0x19;
  52. }
  53.  
  54. // 0x8X
  55. void SeqHeaderCmd_8X(group* group, macro* macro, u8 cmd) {
  56.     group->macro.char_0x19 = group->pChar_0x15C[cmd & 0xF];
  57.     if (cmd & 0xF < 2) {
  58.         group->pChar_0x15C[cmd & 0xF] = -1;
  59.     }
  60. }
  61.  
  62. // 0x9X
  63. // Sets up a sub-track (aka. sub-sequence or channel)
  64. // This is a global pointer.
  65. void SeqHeaderCmd_9X(group* group, macro* macro, u8 cmd) {
  66.     Nas_OpenSub(group, cmd & 0xF, group->seqData + Nas_ReadWordData(macro));
  67. }
  68.  
  69. // 0xAX
  70. // Sets up a sub-track.
  71. // Same as 9X commands, except that the offset is relative to the current command.
  72. void SeqHeaderCmd_AX(group* group, macro* macro, u8 cmd) {
  73.     Nas_OpenSub(group, cmd & 0xF, macro->data + (s8)Nas_ReadWordData(macro));
  74. }
  75.  
  76. // 0xBX
  77. // Loads an entirely new sequence at the specified global offset.
  78. // The first byte argument is the sequence id.
  79. void SeqHeaderCmd_AX(group* group, macro* macro, u8 cmd) {
  80.     SeqLoad(Nas_ReadByteData(macro), group->seqData + Nas_ReadWordData(macro), group->pChar_0x15C[cmd & 0xF]);
  81. }
  82.  
  83. // 0xBE
  84. // Sets up a callback function.
  85. // This may only be in the N64 emulator as an addition.
  86. void SeqHeaderCmd_BE(group* group, macro* macro) {
  87.     u8 callbackIdx = Nas_ReadByteData(macro);
  88.     if (callbackIdx < 5) {
  89.         (s8 (*f)(s8, group*)) = sequenceMainCallbacks[callbackIdx];
  90.         if (f != NULL) {
  91.             s8 result = (*f)(group->macro->char_0x19, group);
  92.         }
  93.     }
  94. }
  95.  
  96. // 0xC2
  97. void SeqHeaderCmd_C2(group* group, macro* macro) {
  98.     unsigned short offset = Nas_ReadWordData(macro);
  99.     if (group->char_0x95 != -1) {
  100.         short macroPtrAdjust = ((short*)group->pByte_0x1C + offset)[group->char_0x95];
  101.         *macro = (macro)(group->pByte_0x1C + macroPtrAdjust);
  102.     }
  103. }
  104.  
  105. // 0xC3
  106. void SeqHeaderCmd_C3(group* group, macro* macro) {
  107.     u16 offset = Nas_ReadWordData(macro);
  108.     if (group->char_0x95 != -1) {
  109.         u16 bitfield = (u16)((short*)group->pByte_0x1C + offset)[group->char_0x95];
  110.         for (u32 i = 0; i < 16; i++) {
  111.             u8* value = group->arrayBytePtr_0x3C[i];
  112.             *value = (u8)(((bitfield & 1) << 4) | (*value & 0xEF));
  113.             bitfield >>= 1;
  114.         }
  115.     }
  116. }
  117.  
  118. // 0xC4
  119. // Calls another sequence.
  120. // If the sequence id? is equal to the current one, further command parsing is halted.
  121. void SeqHeaderCmd_C4(group* group, macro* macro) {
  122.     u8 val1 = Nas_ReadByteData(macro);
  123.     if (val1 == 0xFF) {
  124.         val1 = group->byte_0x8;
  125.     }
  126.    
  127.     u8 val2 = Nas_ReadByteData(macro);
  128.     Nas_StartMySeq(val1, val2);
  129.    
  130.     // Used when in switch format
  131.     if (val1 == group->byte_0x8) return;
  132. }
  133.  
  134. // C5
  135. void SeqHeaderCmd_C5(group* group, macro* macro) {
  136.     group->ushort_0x18 = Nas_ReadWordData(macro);
  137. }
  138.  
  139. // C6
  140. // Sets a flag and then stops parsing.
  141. // Sequence canceled flag?
  142. void SeqHeaderCmd_C6(group* group, macro* macro) {
  143.     group->byte_0x0 |= 2;
  144.     return; // Used in switch statement
  145. }
  146.  
  147. // C7
  148. // Patch sequence data?
  149. void SeqHeaderCmd_C7(group* group, macro* macro) {
  150.     u8 adjust = Nas_ReadByteData(macro);
  151.     u16 offset = Nas_ReadWordData(macro);
  152.    
  153.     group->pByte_0x1C[offset] = (byte)(group->char_0x95 + adjust);
  154. }
  155.  
  156. // C8
  157. // Subtract from work byte
  158. void SeqHeaderCmd_C8(group* group, macro* macro) {
  159.     group->char_0x95 -= Nas_ReadByteData(macro);
  160. }
  161.  
  162. // C9
  163. // Mask work byte
  164. void SeqHeaderCmd_C9(group* group, macro* macro) {
  165.     group->char_0x95 &= Nas_ReadByteData(macro);
  166. }
  167.  
  168. // CC
  169. // Set work byte
  170. void SeqHeaderCmd_CC(group* group, macro* macro) {
  171.     group->char_0x95 = Nas_ReadByteData(macro);
  172. }
  173.  
  174. // CD
  175. //
  176. void SeqHeaderCmd_CD(group* group, macro* macro) {
  177.     u8 adjust = Nas_ReadByteData(macro);
  178.     if (group->char_0x95 != -1) {
  179.         if (group->byte_0x94 != 3) {
  180.             group->byte_0x94++;
  181.             macro[group->byte_0x94] = *macro;
  182.             *macro = group->pByte_0x1C + ((short*)group->pByte_0x1C)[group->char_0x95 + adjust];
  183.         }
  184.     }
  185. }
  186.  
  187. // 0xCE
  188. void SeqHeaderCmd_CE(group* group, macro* macro) {
  189.     u8 val = Nas_ReadByteData(macro);
  190.     if (val == 0) {
  191.         group->char_0x95 = (char)(SET_WORD >> 2);
  192.     }
  193.     else {
  194.         group->char_0x95 = (char)((SET_WORD >> 2) - ((SET_WORD >> 2) / val) * val;
  195.     }
  196. }
  197.  
  198. // 0xD0
  199. void SeqHeaderCmd_D0(group* group, macro* macro) { {
  200.     group->byte_0x2 = Nas_ReadByteData(macro);
  201. }
  202.  
  203. // 0xD1
  204. void SeqHeaderCmd_D1(group* group, macro* macro) { {
  205.     group->pByte_0x9C = group->pByte_0x1C + Nas_ReadByteData(macro);
  206. }
  207.  
  208. // 0xD2
  209. void SeqHeaderCmd_D2(group* group, macro* macro) { {
  210.     group->pByte_0x98 = group->pByte_0x1C + Nas_ReadByteData(macro);
  211. }
  212.  
  213. // 0xD3
  214. void SeqHeaderCmd_D3(group* group, macro* macro) { {
  215.     group->byte_0x3 = Nas_ReadByteData(macro);
  216. }
  217.  
  218. // 0xD4
  219. void SeqHeaderCmd_D4(group* group, macro* macro) { {
  220.     group->byte_0x0 |= 0x20;
  221. }
  222.  
  223. // 0xD5
  224. void SeqHeaderCmd_D5(group* group, macro* macro) { {
  225.     group->float_0x2C = (float)Nas_ReadByteData(macro) / 127.0;
  226. }
  227.  
  228. // 0xD6
  229. // Disable channels. Unused.
  230. void SeqHeaderCmd_D6(group* group, macro* macro) { {
  231.     Nas_ReadWordData(macro);
  232. }
  233.  
  234. // 0xD7
  235. // Enable channels.
  236. void SeqHeaderCmd_D7(group* group, macro* macro) { {
  237.     Nas_AllocSub(group, Nas_ReadWordData(macro));
  238. }
  239.  
  240. // 0xD9
  241. void SeqHeaderCmd_D9(group* group, macro* macro) { {
  242.     group->float_0x30 = (float)Nas_ReadByteData(macro) / 127.0;
  243. }
  244.  
  245. // 0xDA
  246. void SeqHeaderCmd_DA(group* group, macro* macro) { {
  247.     u8 type = Nas_ReadByteData(macro);
  248.     u16 unk = Nas_ReadWordData(macro);
  249.    
  250.     if (type == 2) {
  251.         group->short_0x14 = unk;
  252.         group->byte_0x1 = type;
  253.         group->float_0x24 = -group->float_0x20 / (float)group->short_0x14;
  254.     }
  255.     else if (type < 2 && group->byte_0x1 != 2) {
  256.         group->short_0x16 = unk;
  257.         group->byte_0x1 = type;
  258.     }
  259. }
  260.  
  261. // 0xDB
  262. void SeqHeaderCmd_DB_SetMasterVolume(group* group, macro* macro);
  263.     masterVolume = (float)ReadByteData(macro) / 127.0f;
  264.     if (group->byte_0x1 == 1) {
  265.         group->float_0x20 = 1.0f;
  266.         group->byte_0x1 = 0; // Reset state?
  267.     }
  268.     else {
  269.         if (group->byte_0x1 != 0) break;
  270.     }
  271.  
  272.     group->short_0x14 = group->short_0x16;
  273.     if (group->short_0x16 == 0) {
  274.         group->float_0x20 = masterVolume;
  275.     }
  276.     else {
  277.         // Fade volume in?
  278.         group->float_0x24 = (masterVolume - group->float_0x20) / (float)group->short_0x14;
  279.     }
  280. }
  281.  
  282. // 0xDC
  283. // Something similar to tempo like 0xDD
  284. void SeqHeaderCmd_DC(group* group, macro* macro) {
  285.     group->short_0xE = (s16)(s8)ReadByteData(macro) * 48;
  286. }
  287.  
  288. // 0xDD
  289. // Tempo control
  290. void SeqHeaderCmd_DD_SetTempo(group* group, macro* macro) {
  291.     group->ushort_0xA = (u16)ReadByteData(macro) * 48; // Tempo
  292.     if ((int)SOME_DATA < (int)group->ushort_0xA) {
  293.         group->ushort_0xA = SOME_DATA;
  294.     }
  295.    
  296.     if ((s8)group->ushort_0xA < 1) {
  297.         group->ushort_0xA = 1;
  298.     }
  299. }
  300.  
  301. // 0xDE
  302. void SeqHeaderCmd_DE(group* group, macro* macro) {
  303.     group->short_0x10 += (short)(char)ReadByteData(macro);
  304. }
  305.  
  306. // 0xDF
  307. void SeqHeaderCmd_DF(group* group, macro* macro) {
  308.     group->short_0x10 = 0;
  309. }
  310.  
  311. // 0xEF
  312. // Unused
  313. void SeqHeaderCmd_EF(group* group, macro* macro) {
  314.     ReadByteData(macro);
  315.     ReadWordData(macro);
  316. }
  317.  
  318. // 0xF0
  319. void SeqHeaderCmd_F0(group* group, macro* macro) {
  320.     Nas_DeAllocAllVoices(group->channelNodes); // group->chnode_0xA0[4]
  321. }
  322.  
  323. // 0xF1
  324. void SeqHeaderCmd_F1(group* group, macro* macro) {
  325.     Nas_DeAllocAllVoices(group->channelNodes);
  326.     Nas_AllocVoices(group->channelNodes, Nas_ReadByteData(macro));
  327. }
  328.  
  329. // 0xF2
  330. // Conditional skip when macro->char_0x19 < 0
  331. // Skips 0xXXXX bytes of the header.
  332. void SeqHeaderCmd_F2(group* group, macro* macro) {
  333.     u16 offset = Nas_ReadWordData(macro);
  334.     if (macro->char_0x19 < 0) {
  335.         macro->data += offset;
  336.     }
  337. }
  338.  
  339. // 0xF3
  340. // Conditional skip when macro->char_0x19 == 0
  341. // Skips 0xXXXX bytes of the header.
  342. void SeqHeaderCmd_F3(group* group, macro* macro) {
  343.     u16 offset = Nas_ReadWordData(macro);
  344.     if (macro->char_0x19 == 0) {
  345.         macro->data += offset;
  346.     }
  347. }
  348.  
  349. // 0xF4
  350. // Skips some sequence header data.
  351. // Skips 0xXXXX bytes of the header.
  352. void SeqHeaderCmd_F3(group* group, macro* macro) {
  353.     macro->data += Nas_ReadWordData(macro);
  354. }
  355.  
  356. // 0xF5
  357. // Conditional jump when macro->char_0x19 > -1
  358. void SeqHeaderCmd_F5(group* group, macro* macro) {
  359.     u16 offset = Nas_ReadWordData(macro);
  360.     if (macro->char_0x19 > -1) {
  361.         macro->data = group->pByte_0x1C + offset;
  362.     }
  363. }
  364.  
  365. // 0xF6
  366. // Decrement stack idx in the macro.
  367. void SeqHeaderCmd_F6(group* group, macro* macro) {
  368.     macro->stackIdx -= 1;
  369. }
  370.  
  371. // 0xF7
  372. // Execute counted loop
  373. void SeqHeaderCmd_F6(group* group, macro* macro) {
  374.     macro->stackArgs[macro->stackIdx]--;
  375.     if (macro->stackArgs[macro->stackIdx] == 0) {
  376.         macro->stackIdx--;
  377.     }
  378.     else {
  379.         macro->data = macro->stack[macro->stackIdx];
  380.     }
  381. }
  382.  
  383. // 0xF8
  384. // Set counted cmd loop
  385. // Saves the address of the current command & the number of times the loop should execute.
  386. void SeqHeaderCmd_F8(group* group, macro* macro, u16 args) {
  387.     macro->stackArgs[macro->stackIdx] = (s8)args;
  388.     macro->stack[macro->stackIdx++] = macro->data;
  389. }
  390.  
  391. // 0xF9
  392. // Conditional jump when macro->char_0x19 < 0
  393. void SeqHeaderCmd_F9(group* group, macro* macro) {
  394.     u16 offset = Nas_ReadWordData(macro);
  395.     if (macro->char_0x19 < 0) {
  396.         macro->data = group->pByte_0x1C + offset;
  397.     }
  398. }
  399.  
  400. // 0xFA
  401. // Conditional jump when macro->char_0x19 == 0
  402. void SeqHeaderCmd_FA(group* group, macro* macro) {
  403.     u16 offset = Nas_ReadWordData(macro);
  404.     if (macro->char_0x19 == 0) {
  405.         macro->data = group->pByte_0x1C + offset;
  406.     }
  407. }
  408.  
  409. // 0xFB
  410. // Jump to offset (used in loops)
  411. void SeqHeaderCmd_FB(group* group, macro* macro) {
  412.     macro->data = group->pByte_0x1C + Nas_ReadWordData(macro);
  413. }
  414.  
  415. // 0xFC
  416. // Jump to offset with return stack link
  417. void SeqHeaderCmd_FC(group* group, macro* macro) {
  418.     macro->stack[macro->stackIdx++] = macro->data;
  419.     macro->data = group->pByte_0x1C + ReadWordData(macro);
  420. }
  421.  
  422. // 0xFD
  423. // Next command process time delay
  424. short SeqHeaderCmd_FD(group* group, macro* macro) {
  425.     return Nas_ReadLengthData(macro);
  426. }
  427.  
  428. // 0xFE
  429. short SeqHeaderCmd_FE(group* group, macro* macro) {
  430.     return 1;
  431. }
  432.  
  433. // 0xFF
  434. // Sequence Header Termination
  435. short SeqHeaderCmd_FF(group* group, macro* macro) {
  436.     if (macro->stackIdx == 0) {
  437.         return -1; // Ends the current header stack
  438.     }
  439.    
  440.     macro->stackIdx--;
  441.     macro->data = macro->stack[macro->stackIdx];
  442.    
  443.     return 0;
  444. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement