Advertisement
dragonbane

oot-music.c

Jan 20th, 2024 (edited)
983
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 47.32 KB | None | 0 0
  1. #include "oot-music.h"
  2. #include <math.h>
  3. #include <stdbool.h>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <emscripten/emscripten.h>
  9.  
  10. #define true 1
  11. #define false 0
  12. #define max(a, b) (((a) > (b)) ? (a) : (b))
  13. #define min(a, b) (((a) < (b)) ? (a) : (b))
  14. #define abs(a) (((a) > 0) ? (a) : (-(a)))
  15.  
  16. /********
  17. Sequence IDs
  18. ********/
  19.  
  20. typedef struct Sequence_id {
  21.   char* title;
  22.   int id;
  23.   const char* type;
  24.   int size;
  25. } Sequence_id;
  26.  
  27. const Sequence_id bgm_sequence_ids[] = {
  28.   {"Hyrule Field", 0x02, "bgm"},
  29.   {"Dodongos Cavern", 0x18, "bgm"},
  30.   {"Kakariko Adult", 0x19, "bgm"},
  31.   {"Battle", 0x1A, "bgm"},
  32.   {"Boss Battle", 0x1B, "bgm"},
  33.   {"Inside Deku Tree", 0x1C, "bgm"},
  34.   {"Market", 0x1D, "bgm"},
  35.   {"Title Theme", 0x1E, "bgm"},
  36.   {"House", 0x1F, "bgm"},
  37.   {"Jabu Jabu", 0x26, "bgm"},
  38.   {"Kakariko Child", 0x27, "bgm"},
  39.   {"Fairy Fountain", 0x28, "bgm"},
  40.   {"Zelda Theme", 0x29, "bgm"},
  41.   {"Fire Temple", 0x2A, "bgm"},
  42.   {"Forest Temple", 0x2C, "bgm"},
  43.   {"Castle Courtyard", 0x2D, "bgm"},
  44.   {"Ganondorf Theme", 0x2E, "bgm"},
  45.   {"Lon Lon Ranch", 0x2F, "bgm"},
  46.   {"Goron City", 0x30, "bgm"},
  47.   {"Miniboss Battle", 0x38, "bgm"},
  48.   {"Temple of Time", 0x3A, "bgm"},
  49.   {"Kokiri Forest", 0x3C, "bgm"},
  50.   {"Lost Woods", 0x3E, "bgm"},
  51.   {"Spirit Temple", 0x3F, "bgm"},
  52.   {"Horse Race", 0x40, "bgm"},
  53.   {"Ingo Theme", 0x42, "bgm"},
  54.   {"Fairy Flying", 0x4A, "bgm"},
  55.   {"Deku Tree", 0x4B, "bgm"},
  56.   {"Windmill Hut", 0x4C, "bgm"},
  57.   {"Shooting Gallery", 0x4E, "bgm"},
  58.   {"Sheik Theme", 0x4F, "bgm"},
  59.   {"Zoras Domain", 0x50, "bgm"},
  60.   {"Shop", 0x55, "bgm"},
  61.   {"Chamber of the Sages", 0x56, "bgm"},
  62.   {"Ice Cavern", 0x58, "bgm"},
  63.   {"Kaepora Gaebora", 0x5A, "bgm"},
  64.   {"Shadow Temple", 0x5B, "bgm"},
  65.   {"Water Temple", 0x5C, "bgm"},
  66.   {"Gerudo Valley", 0x5F, "bgm"},
  67.   {"Potion Shop", 0x60, "bgm"},
  68.   {"Kotake and Koume", 0x61, "bgm"},
  69.   {"Castle Escape", 0x62, "bgm"},
  70.   {"Castle Underground", 0x63, "bgm"},
  71.   {"Ganondorf Battle", 0x64, "bgm"},
  72.   {"Ganon Battle", 0x65, "bgm"},
  73.   {"Fire Boss", 0x6B, "bgm"},
  74.   {"Mini-game", 0x6C, "bgm"},
  75. };
  76. const Sequence_id fanfare_sequence_ids[] = {
  77.   {"Game Over", 0x20, "fanfare"},
  78.   {"Boss Defeated", 0x21, "fanfare"},
  79.   {"Item Get", 0x22, "fanfare"},
  80.   {"Ganondorf Appears", 0x23, "fanfare"},
  81.   {"Heart Container Get", 0x24, "fanfare"},
  82.   {"Treasure Chest", 0x2B, "fanfare"},
  83.   {"Spirit Stone Get", 0x32, "fanfare"},
  84.   {"Heart Piece Get", 0x39, "fanfare"},
  85.   {"Escape from Ranch", 0x3B, "fanfare"},
  86.   {"Learn Song", 0x3D, "fanfare"},
  87.   {"Epona Race Goal", 0x41, "fanfare"},
  88.   {"Medallion Get", 0x43, "fanfare"},
  89.   {"Zelda Turns Around", 0x51, "fanfare"},
  90.   {"Master Sword", 0x53, "fanfare"},
  91.   {"Door of Time", 0x59, "fanfare"},
  92.   {"Ganons Rainbow Bridge", 0x5D, "fanfare"},
  93. };
  94. const Sequence_id ocarina_sequence_ids[] = {
  95.   {"Prelude of Light", 0x25, "ocarina"},
  96.   {"Bolero of Fire", 0x33, "ocarina"},
  97.   {"Minuet of Forest", 0x34, "ocarina"},
  98.   {"Serenade of Water", 0x35, "ocarina"},
  99.   {"Requiem of Spirit", 0x36, "ocarina"},
  100.   {"Nocturne of Shadow", 0x37, "ocarina"},
  101.   {"Saria's Song", 0x44, "ocarina"},
  102.   {"Epona's Song", 0x45, "ocarina"},
  103.   {"Zelda's Lullaby", 0x46, "ocarina"},
  104.   {"Sun's Song", 0x47, "ocarina"},
  105.   {"Song of Time", 0x48, "ocarina"},
  106.   {"Song of Storms", 0x49, "ocarina"},
  107. };
  108. const Sequence_id credit_sequence_ids[] = {
  109.   {"Zeldas Theme Orchestra", 0x52, "credit"},
  110.   {"Zeldas Ocarina Son", 0x66, "credit"},
  111.   {"Ending Credits Part 4", 0x67, "credit"},
  112.   {"Ending Credits Part 4", 0x68, "credit"},
  113.   {"Ending Credits Part 4", 0x69, "credit"},
  114.   {"Ending Credits Part 4", 0x6A, "credit"},
  115. };
  116. const Sequence_id fileselect_sequence_ids[] = {
  117.   {"File Select", 0x57, "fileselect"},
  118. };
  119.  
  120. Sequence_id* get_sequence_ids(bool bgm, bool fanfare, bool ocarina, bool credit, bool fileselect) {
  121.   int size = 0;
  122.   size += bgm ? sizeof(bgm_sequence_ids) : 0;
  123.   size += fanfare ? sizeof(fanfare_sequence_ids) : 0;
  124.   size += ocarina ? sizeof(ocarina_sequence_ids) : 0;
  125.   size += credit ? sizeof(credit_sequence_ids) : 0;
  126.   size += fileselect ? sizeof(fileselect_sequence_ids) : 0;
  127.   Sequence_id* ids = (Sequence_id*)malloc(size);
  128.   int ids_index = 0;
  129.   if (bgm) {
  130.     for (int i = 0; i < sizeof(bgm_sequence_ids) / sizeof(Sequence_id); i++) {
  131.       ids[ids_index] = bgm_sequence_ids[i];
  132.       ids_index++;
  133.     }
  134.   }
  135.   if (fanfare) {
  136.     for (int i = 0; i < sizeof(fanfare_sequence_ids) / sizeof(Sequence_id); i++) {
  137.       ids[ids_index] = fanfare_sequence_ids[i];
  138.       ids_index++;
  139.     }
  140.   }
  141.   if (ocarina) {
  142.     for (int i = 0; i < sizeof(ocarina_sequence_ids) / sizeof(Sequence_id); i++) {
  143.       ids[ids_index] = ocarina_sequence_ids[i];
  144.       ids_index++;
  145.     }
  146.   }
  147.   if (credit) {
  148.     for (int i = 0; i < sizeof(credit_sequence_ids) / sizeof(Sequence_id); i++) {
  149.       ids[ids_index] = credit_sequence_ids[i];
  150.       ids_index++;
  151.     }
  152.   }
  153.   if (fileselect) {
  154.     for (int i = 0; i < sizeof(fileselect_sequence_ids) / sizeof(Sequence_id); i++) {
  155.       ids[ids_index] = fileselect_sequence_ids[i];
  156.       ids_index++;
  157.     }
  158.   }
  159.   ids->size = size;
  160.   return ids;
  161. }
  162.  
  163. /********
  164. Sound vector
  165. ********/
  166.  
  167. void sound_Vector_Init(sound_Vector* vector) {
  168.   vector->len = 0;
  169.   vector->size = 64;
  170.   vector->data = (sound*)malloc(vector->size); //ToDo: Does this make sense?
  171.   if (vector->data == NULL) {
  172.     vector->size = 0;
  173.   }
  174. }
  175.  
  176. bool sound_Vector_grow(sound_Vector* vector, int newSize) {
  177.   int size_new = vector->size + newSize;
  178.   if (vector->size == 0) {
  179.     size_new = 64;
  180.   }
  181.   sound* data_new = (sound*)malloc(size_new);
  182.   if (data_new == NULL) {
  183.     return false;
  184.   }
  185.   if (vector->size > 0) {
  186.     memcpy(data_new, vector->data, vector->size);
  187.   }
  188.  
  189.   if (vector->data != NULL)
  190.     free(vector->data);
  191.  
  192.   vector->data = data_new;
  193.   vector->size = size_new;
  194.   return true;
  195. }
  196.  
  197. void sound_Vector_push(sound_Vector* vector, sound newSound) {
  198.   if (!sound_Vector_grow(vector, sizeof(sound))) {
  199.     return;
  200.   }
  201.  
  202.   printf("[C] Adding sound to vector, not yet supported!\n"); //ToDo:
  203.  
  204.   vector->data[vector->len] = newSound;
  205.   vector->len++;
  206. }
  207.  
  208. sound sound_Vector_pop(sound_Vector* vector) {
  209.   if (vector->len == 0) {
  210.     sound empty;
  211.     return empty;
  212.   }
  213.  
  214.   sound val = vector->data[vector->len - 1];
  215.   vector->len--;
  216.   return val;
  217. }
  218.  
  219. void sound_Vector_extend(sound_Vector* vector, const sound* new_data, int length) {
  220.   int i = 0;
  221.   while ((vector->len + length) >= vector->size) {
  222.     int newSize = sizeof(sound);
  223.     if (!sound_Vector_grow(vector, newSize)) {
  224.       return;
  225.     }
  226.     i++;
  227.   }
  228.  
  229.   memcpy(vector->data + vector->len, new_data, length);
  230.   vector->len += length;
  231. }
  232.  
  233. void sound_Vector_free(sound_Vector* vector) {
  234.   if (vector->data != NULL) {
  235.     for (int i = 0; i < vector->len; i++) {
  236.       //free(vector->data[i].file); //ToDo: Not the responsibility of this code to clean external passed in data
  237.       //free(vector->data[i].data);
  238.     }
  239.     free(vector->data);
  240.     vector->data = NULL;
  241.   }
  242.   vector->size = 0;
  243.   vector->len = 0;
  244. }
  245.  
  246. /********
  247. Bank
  248. ********/
  249.  
  250. typedef struct Bank {
  251.   uint16_t index;
  252.   char* meta;
  253.   uint8_t* data;
  254.   int data_length;
  255.   sound_Vector zsounds;
  256.   int offset;
  257. } Bank;
  258.  
  259. void Bank_Init(Bank* bank, uint16_t index, char* meta, uint8_t* data) {
  260.   bank->index = index;
  261.   bank->meta = meta;
  262.   bank->data = data;
  263.   sound_Vector sounds;
  264.   sound_Vector_Init(&sounds);
  265.   bank->zsounds = sounds;
  266.   bank->offset = 0;
  267. }
  268.  
  269. void Bank_Free(Bank* bank) {
  270.   sound_Vector_free(&bank->zsounds);
  271. }
  272.  
  273. void Bank_add_zsound(Bank* bank, int tempaddr, sound zsound) {
  274.   sound_Vector_push(&bank->zsounds, zsound);
  275.   printf("[C] Adding zsound, not yet supported!\n"); //ToDo:
  276. }
  277.  
  278. uint8_t* Bank_get_entry(Bank* bank, int offset) {
  279.   //Size: 4 (offset) + 4 (datalen) + size of meta
  280.   int entry_size = 8 + strlen(bank->meta);
  281.   uint8_t* entry = (uint8_t*)malloc(entry_size);
  282.   int datalen = bank->data_length;
  283.   for (int i = 0; i < entry_size; i++) {
  284.     //First 4 bytes
  285.     if (i < 4) {
  286.       entry[i] = (offset >> ((3 - i) * 8)) & 0xFF;
  287.     }
  288.     //Second 4 bytes
  289.     else if (i < 8) {
  290.       entry[i] = (datalen >> ((3 - (i - 4)) * 8)) & 0xFF;
  291.     }
  292.     //Rest of the bytes
  293.     else {
  294.       entry[i] = bank->meta[i - 8];
  295.     }
  296.   }
  297.   return entry;
  298. }
  299.  
  300. int Bank_get_entry_size(Bank* bank, int offset) {
  301.   //Size: 4 (offset) + 4 (datalen) + size of meta
  302.   int entry_size = 8 + strlen(bank->meta);
  303.   return entry_size;
  304. }
  305.  
  306. void Bank_update_zsound_pointers(Bank* bank) {
  307.   for (int vectorIndex = 0; vectorIndex < bank->zsounds.len; vectorIndex++) {
  308.     int datalen = bank->data_length;
  309.     char addressBytes[4];
  310.     addressBytes[0] = 0;
  311.     addressBytes[1] = 0;
  312.     for (int i = 0; i < 2; i++) {
  313.       addressBytes[2 + i] = (bank->zsounds.data[vectorIndex].temp_addr >> ((1 - i) * 8)) & 0xFF;
  314.     }
  315.     //Loop through data and see if we find any matches for the address
  316.     for (int dataIndex = 0; dataIndex < (datalen - 3); dataIndex++) {
  317.       bool match = true;
  318.       for (int i = 0; i < 4; i++) {
  319.         if (!(bank->data[dataIndex + i] == addressBytes[i])) {
  320.           match = false;
  321.           break;
  322.         }
  323.       }
  324.       //If we find a match, replace the bytes
  325.       if (match) {
  326.         for (int i = 0; i < 4; i++) {
  327.           bank->data[dataIndex + i] = (bank->zsounds.data[vectorIndex].offset >> ((3 - i) * 8)) & 0xFF;
  328.         }
  329.       }
  330.     }
  331.   }
  332. }
  333.  
  334. /********
  335. Bank vector
  336. ********/
  337.  
  338. typedef struct Bank_Vector {
  339.   Bank* data;
  340.   int len;
  341.   int size;
  342. } Bank_Vector;
  343.  
  344. void Bank_Vector_Init(Bank_Vector* vector) {
  345.   vector->len = 0;
  346.   vector->size = 64;
  347.   vector->data = (Bank*)malloc(vector->size); //ToDo: Unclear, should this allocate sizeof Bank structs, why just 64 bytes at the start?
  348.   if (vector->data == NULL) {
  349.     vector->size = 0;
  350.   }
  351. }
  352.  
  353. bool Bank_Vector_grow(Bank_Vector* vector, int newSize) {
  354.   int size_new = vector->size + newSize;
  355.   if (vector->size == 0) {
  356.     size_new = 64;
  357.   }
  358.   Bank* data_new = (Bank*)malloc(size_new);
  359.   if (data_new == NULL) {
  360.     return false;
  361.   }
  362.   if (vector->size > 0) {
  363.     memcpy(data_new, vector->data, vector->size);
  364.   }
  365.  
  366.   if (vector->data != NULL)
  367.     free(vector->data);
  368.  
  369.   vector->data = data_new;
  370.   vector->size = size_new;
  371.   return true;
  372. }
  373.  
  374. void Bank_Vector_push(Bank_Vector* vector, Bank newBank) {
  375.   if (!Bank_Vector_grow(vector, sizeof(Bank))) {
  376.     return;
  377.   }
  378.  
  379.   vector->data[vector->len] = newBank;
  380.   vector->len++;
  381. }
  382.  
  383. Bank Bank_Vector_pop(Bank_Vector* vector) {
  384.   if (vector->len == 0) {
  385.     Bank empty;
  386.     return empty;
  387.   }
  388.  
  389.   Bank val = vector->data[vector->len - 1];
  390.   vector->len--;
  391.   return val;
  392. }
  393.  
  394. void Bank_Vector_extend(Bank_Vector* vector, const Bank* new_data, int length) {
  395.   int i = 0;
  396.   while ((vector->len + length) >= vector->size) {
  397.     int newSize = sizeof(Bank);
  398.     if (!Bank_Vector_grow(vector, newSize)) {
  399.       return;
  400.     }
  401.     i++;
  402.   }
  403.  
  404.   memcpy(vector->data + vector->len, new_data, length);
  405.   vector->len += length;
  406. }
  407.  
  408. void Bank_Vector_free(Bank_Vector* vector) {
  409.   if (vector->data != NULL) {
  410.     for (int i = 0; i < vector->len; i++) {
  411.       //free(vector->data[i].data); //ToDo: Not the responsibility of this code to clean the passed in external data
  412.       //free(vector->data[i].meta);
  413.       Bank_Free(&vector->data[i]);
  414.     }
  415.     free(vector->data);
  416.     vector->data = NULL;
  417.   }
  418.   vector->size = 0;
  419.   vector->len = 0;
  420. }
  421.  
  422. /********
  423. Sequence
  424. ********/
  425.  
  426. void Sequence_Init(Sequence* sequence, char* name, char* cosmetic_name, int type, int instrument_set, char* instrument_set_str,
  427.   int replaces, int vanilla_id, uint8_t* seq_file, int seq_file_length, bool new_instrument_set /*, Vector zsounds*/) {
  428.   //Required params
  429.   sequence->name = name;
  430.   sequence->seq_file = seq_file;
  431.   sequence->seq_file_length = seq_file_length;
  432.   sequence->cosmetic_name = cosmetic_name;
  433.   //Optional params
  434.   sequence->type = type;
  435.   if (sequence->type == 0) {
  436.     sequence->type = 0x0202;
  437.   }
  438.   sequence->instrument_set = instrument_set;
  439.   if (sequence->instrument_set == 0) {
  440.     sequence->instrument_set = 0x03;
  441.   }
  442.   sequence->replaces = replaces;
  443.   if (sequence->replaces == 0) {
  444.     sequence->replaces = -1;
  445.   }
  446.   sequence->vanilla_id = vanilla_id;
  447.   if (sequence->vanilla_id == 0) {
  448.     sequence->vanilla_id = -1;
  449.   }
  450.   sequence->new_instrument_set = new_instrument_set;
  451.   // sequence->zsounds = zsounds;
  452.   // if (sequence->zsounds == NULL) {
  453.   //   Vector sounds;
  454.   //   bank->zsounds = Vector_Init(sounds);
  455.   // }
  456.   //Init as null
  457.   sequence->zbank_file = NULL;
  458.   sequence->bankmeta = NULL;
  459.   //If we were passed a string instrument set, then we need to parse the instrument set from the string version
  460.   if (instrument_set_str != NULL) {
  461.     if (instrument_set_str[0] == '-') {
  462.       sequence->new_instrument_set = true;
  463.     } else {
  464.       sequence->instrument_set = atoi(instrument_set_str);
  465.     }
  466.   }
  467. }
  468.  
  469. void Sequence_copy(Sequence* copy, Sequence* original) {
  470.   Sequence_Init(copy, original->name, original->cosmetic_name, original->type, original->instrument_set, NULL,
  471.     original->replaces, original->vanilla_id, original->seq_file, original->seq_file_length, original->new_instrument_set);
  472.   copy->zbank_file = original->zbank_file;
  473.   copy->bankmeta = original->bankmeta;
  474. }
  475.  
  476. Sequence* get_replacement_sequence(Sequence* sequences, int sequences_length, int id) {
  477.   for (int i = 0; i < sequences_length; i++) {
  478.     if (sequences[i].replaces == id) {
  479.       return &sequences[i];
  480.     }
  481.   }
  482.   return NULL;
  483. }
  484.  
  485. /********
  486. SequenceData
  487. ********/
  488.  
  489. typedef struct SequenceData {
  490.   int address;
  491.   int size;
  492.   uint8_t* data;
  493. } SequenceData;
  494.  
  495. void SequenceData_Init(SequenceData* sequence_data) {
  496.   sequence_data->address = -1;
  497.   sequence_data->size = -1;
  498. }
  499.  
  500. /********
  501. Rom
  502. ********/
  503.  
  504. #define RANDO_CONTEXT 0x03480000
  505. #define COSMETICS_CONTEXT_ADDR (RANDO_CONTEXT + 0x4)
  506. #define CFG_AUDIOBANK_TABLE_EXTENDED_ADDR_VERSION 0x1F073FDD
  507. #define CFG_AUDIOBANK_TABLE_EXTENDED_ADDR_OFFSET 0x64
  508.  
  509. #define DMA_START 0x00007430
  510. #define DMA_SIZE 0x10
  511.  
  512. #define AUDIOBANK_DMADATA_INDEX 3
  513. #define AUDIOSEQ_DMADATA_INDEX 4
  514. #define AUDIOTABLE_DMADATA_INDEX 5
  515. #define file_start AUDIOBANK_DMADATA_INDEX
  516. #define file_end AUDIOTABLE_DMADATA_INDEX
  517.  
  518. typedef struct DMAEntry {
  519.   int index;
  520.   int start;
  521.   int end;
  522.   int size;
  523. } DMAEntry;
  524.  
  525. typedef struct Rom {
  526.   uint8_t* original;
  527.   DMAEntry* dma_original;
  528.   uint8_t* modified;
  529.   DMAEntry* dma;
  530.   //int dma_start;
  531. } Rom;
  532.  
  533. const int rom_size = 0x4000000;
  534.  
  535. //The python function has size as optional, but for our purposes size will always be provided
  536. int Rom_dma_freespace(Rom* rom, int size) {
  537.   //Get the free space and sizes of all files
  538.   int free_space_sizes[file_end - file_start + 1];
  539.   int free_space_starts[file_end - file_start + 1];
  540.   for (int i = file_start; i <= file_end; i++) {
  541.     int end_current = ((rom->dma[i].end + 0x0F) >> 4) << 4;
  542.     //If it's not the last entry, do bit stuff, othersize just get the length of the rom
  543.     int start_next = i < AUDIOTABLE_DMADATA_INDEX ? ((rom->dma[i + 1].start + 0x0F) >> 4) << 4 : rom_size;
  544.     if (end_current < start_next) {
  545.       free_space_sizes[i - file_start] = start_next - end_current;
  546.       free_space_starts[i - file_start] = end_current;
  547.     }
  548.   }
  549.   //Find the smallest free space that fits the size requirement
  550.   int chosen_index = -1;
  551.   int smallest_size = 2147483647;
  552.   int largest_size = 0; //For error printing
  553.   for (int i = 0; i < (file_end - file_start + 1); i++) {
  554.     int free_size = free_space_sizes[i];
  555.     if (free_size >= size && free_size < smallest_size) {
  556.       chosen_index = i;
  557.       smallest_size = free_size;
  558.     }
  559.     if (free_size > largest_size) {
  560.       largest_size = free_size;
  561.     }
  562.   }
  563.   //No appropriate size found, throw error
  564.   if (chosen_index == -1) {
  565.     printf("[C]Error: Not enough free space in ROM to file a file of size %i. Largest region of free space available: %i.\n", size, largest_size);
  566.     return -1;
  567.   } else {
  568.     return free_space_starts[chosen_index];
  569.   }
  570. }
  571.  
  572. bool Rom_dma_changed(Rom* rom, int entry) {
  573.   DMAEntry changed = rom->dma[entry];
  574.   DMAEntry original = rom->dma_original[entry];
  575.   return changed.index != original.index || changed.start != original.start || changed.end != original.end || changed.size != original.size;
  576. }
  577.  
  578. void Rom_dma_update(Rom* rom, int entry, int start, int end, int from_file) {
  579.   //Set from_file if not provided
  580.   if (from_file == 0) {
  581.     //Check if this dma entry has been changed
  582.     if (Rom_dma_changed(rom, entry)) {
  583.       from_file = rom->dma[rom->dma[entry].index].start;
  584.     } else {
  585.       from_file = rom->dma[entry].start;
  586.     }
  587.   }
  588.   int dma_location = DMA_START + rom->dma[entry].index * 0x10;
  589.   //int dma_location = rom->dma_start + rom->dma[entry].index * 0x10;
  590.   for (int i = 0; i < 16; i++) {
  591.     //First 4 bytes: start
  592.     if (i < 4) {
  593.       rom->modified[dma_location + i] = (start >> (24 - ((3 - i) * 8))) & 0xFF;
  594.     }
  595.     //Second 4 bytes: end
  596.     else if (i < 8) {
  597.       rom->modified[dma_location + i] = (end >> (24 - ((3 - (i - 4)) * 8))) & 0xFF;
  598.     }
  599.     //Third 4 bytes: start again
  600.     else if (i < 12) {
  601.       rom->modified[dma_location + i] = (start >> (24 - ((3 - (i - 8)) * 8))) & 0xFF;
  602.     }
  603.     //Last 4 bytes: 0
  604.     else {
  605.       rom->modified[dma_location + i] = 0;
  606.     }
  607.   }
  608.   rom->dma[entry].start = from_file;
  609.   rom->dma[entry].end = start;
  610.   rom->dma[entry].size = end - start;
  611. }
  612.  
  613. uint16_t Rom_readint16(Rom* rom, int address, bool original) {
  614.   uint16_t result = 0;
  615.   for (int i = 0; i < 2; i++) {
  616.     if (original) {
  617.       result |= (rom->original[address + i] << ((1 - i) * 8));
  618.     } else {
  619.       result |= (rom->modified[address + i] << ((1 - i) * 8));
  620.     }
  621.   }
  622.   return result;
  623. }
  624.  
  625. void Rom_writeint16(Rom* rom, int address, uint16_t value) {
  626.   for (int i = 0; i < 2; i++) {
  627.     rom->modified[address + i] = (value >> (1 - i) * 8) & 0xFF;
  628.   }
  629. }
  630.  
  631. int Rom_readint32(Rom* rom, int address, bool original) {
  632.   int result = 0;
  633.   for (int i = 0; i < 4; i++) {
  634.     if (original) {
  635.       result |= (rom->original[address + i] << ((3 - i) * 8));
  636.     } else {
  637.       result |= (rom->modified[address + i] << ((3 - i) * 8));
  638.     }
  639.   }
  640.   return result;
  641. }
  642.  
  643. void Rom_writeint32(Rom* rom, int address, int value) {
  644.   for (int i = 0; i < 4; i++) {
  645.     rom->modified[address + i] = (value >> (3 - i) * 8) & 0xFF;
  646.   }
  647. }
  648.  
  649. /********
  650. Functions
  651. ********/
  652.  
  653. // typedef struct Group {
  654. //   char* name;
  655. // } Group;
  656.  
  657. // typedef struct Groups {
  658. //   char* name;
  659. //   Group* groups;
  660. // } Groups;
  661.  
  662. //Returns true if the specified sequence name is in the list of disabled sequences
  663. bool disabled_sequence(char* name, Sequence* disabled_sequences, int disabled_sequences_length) {
  664.   for (int disabledIndex = 0; disabledIndex < disabled_sequences_length; disabledIndex++) {
  665.     char* disabled_name = disabled_sequences[disabledIndex].name;
  666.     if (strlen(name) == strlen(disabled_name)) {
  667.       for (int i = 0; i < strlen(name); i++) {
  668.         if (name[i] != disabled_name[i]) {
  669.           break;
  670.         }
  671.         return true;
  672.       }
  673.     }
  674.   }
  675.   return false;
  676. }
  677.  
  678. //This function is mainly file handling, not sure what this'll look like with how data will be passed
  679. //For now, I will write the part of this function that deals with the ROM and leave out the parts that deal with files
  680. //ToDo: Currently unused, will need malloc free fixes if it gets re-enabled
  681. /*
  682. void process_sequences(Rom rom, Sequence_id* ids, int ids_length, Sequence* disabled_source_sequences, int disabled_source_sequences_length,
  683.   Sequence* disabled_target_sequences, int disabled_target_sequences_length, bool include_custom,
  684.   Sequence* sequences, Sequence* target_sequences, Sequence_id* vanilla_ids) {
  685.   //Initialize sizes for sequences
  686.   sequences = (Sequence*)malloc(ids_length * sizeof(Sequence));
  687.   target_sequences = (Sequence*)malloc(ids_length * sizeof(Sequence));
  688.   for (int idIndex = 0; idIndex < ids_length; idIndex++) {
  689.     //Initialize sequence data
  690.     Sequence_id bgm = ids[idIndex];
  691.     char* name = bgm.title;
  692.     char* cosmetic_name = bgm.title;
  693.     int id = bgm.id;
  694.     //Get the 2-byte type from rom
  695.     uint16_t type = Rom_readint16(&rom, 0xB89AE8 + (id * 0x10), false);
  696.     uint8_t instrument_set = rom.modified[0xB89911 + 0xDD + (id * 2)];
  697.     Sequence seq;
  698.     Sequence_Init(&seq, name, cosmetic_name, type, instrument_set, NULL, 0, id, NULL, 0, NULL);
  699.     Sequence target;
  700.     Sequence_Init(&target, name, cosmetic_name, type, instrument_set, NULL, id, 0, NULL, 0, NULL);
  701.  
  702.     //Write the sequences into the array
  703.     if (seq.vanilla_id != 0x57 && !disabled_sequence(cosmetic_name, disabled_source_sequences, disabled_source_sequences_length)) {
  704.       sequences[idIndex] = seq;
  705.     }
  706.     if (!disabled_sequence(cosmetic_name, disabled_target_sequences, disabled_target_sequences_length)) {
  707.       target_sequences[idIndex] = target;
  708.     }
  709.   }
  710. }
  711. */
  712.  
  713. // typedef struct Mapping {
  714. //   char* key;
  715. //   char* value;
  716. // } Mapping;
  717.  
  718. // typedef struct Symbol {
  719. //   char* symbol;
  720. //   int value;
  721. // } Symbol;
  722.  
  723. // int find_symbol(Symbol* symbols, char* searchSymbol) {
  724. //   int value = -1;
  725. //   for (int i = 0; i < sizeof(symbols) / sizeof(Symbol); i++) {
  726. //     bool match = true;
  727. //     for (int j = 0; j < sizeof(symbols[i].symbol); j++) {
  728. //       if (symbols[i].symbol[j] != searchSymbol[j]) {
  729. //         match = false;
  730. //         break;
  731. //       }
  732. //     }
  733. //     if (match) {
  734. //       value = symbols[i].value;
  735. //       break;
  736. //     }
  737. //   }
  738. //   return value;
  739. // }
  740.  
  741. //First line of this one checks the rom.dma property, need to figure out how to do that
  742. void rebuild_sequences(Rom rom, Sequence* sequences, int sequences_length, int CFG_AUDIOBANK_TABLE_EXTENDED_ADDR) {
  743.  
  744.   bool CUSTOM_BANKS_SUPPORTED = CFG_AUDIOBANK_TABLE_EXTENDED_ADDR != -1;
  745.  
  746.   int audioseq_start = rom.dma[AUDIOSEQ_DMADATA_INDEX].start;
  747.   int audioseq_end = rom.dma[AUDIOSEQ_DMADATA_INDEX].end;
  748.   int audioseq_size = rom.dma[AUDIOSEQ_DMADATA_INDEX].size;
  749.  
  750.   SequenceData* old_sequences = (SequenceData*)malloc(0x6E * sizeof(SequenceData));
  751.   for (int i = 0; i < 0x6E; i++) {
  752.     //Set up SequenceData object
  753.     SequenceData entry;
  754.     SequenceData_Init(&entry);
  755.     int entry_address = 0xB89AE0 + (i * 0x10);
  756.     entry.address = Rom_readint32(&rom, entry_address, false);
  757.     entry.size = Rom_readint32(&rom, entry_address + 4, false);
  758.  
  759.     //If size > 0, read the sequence data from the rom into the sequence object
  760.     if (entry.size > 0) {
  761.       entry.data = (uint8_t*)malloc(entry.size);
  762.       for (int j = 0; j < entry.size; j++) {
  763.         entry.data[j] = rom.modified[entry.address + audioseq_start + j];
  764.       }
  765.     } else {
  766.       Sequence* seq = get_replacement_sequence(sequences, sequences_length, i);
  767.       if (seq != NULL && (0 < entry.address && entry.address < 128)) {
  768.         if (seq->replaces != 0x28) {
  769.           seq->replaces = entry.address;
  770.         } else {
  771.           entry.size = old_sequences[0x57].size;
  772.           entry.data = (uint8_t*)malloc(entry.size);
  773.           memcpy(entry.data, old_sequences[0x57].data, entry.size);
  774.         }
  775.       }
  776.     }
  777.  
  778.     //Add to old sequence list
  779.     old_sequences[i] = entry;
  780.   }
  781.  
  782.   SequenceData* new_sequences = (SequenceData*)malloc(0x6E * sizeof(SequenceData));
  783.   int address = 0;
  784.   for (int i = 0; i < 0x6E; i++) {
  785.     //Set up SequenceData object
  786.     SequenceData new_entry;
  787.     SequenceData_Init(&new_entry);
  788.     SequenceData old_sequence = old_sequences[i];
  789.     if (old_sequence.size == 0) {
  790.       new_entry.address = old_sequence.address;
  791.     } else {
  792.       new_entry.address = address;
  793.     }
  794.  
  795.     //If size > 0, read the sequence data from the rom into the sequence object
  796.     Sequence* seq = get_replacement_sequence(sequences, sequences_length, i);
  797.     if (seq != NULL) {
  798.       //Vanilla sequence: Get data from old sequences
  799.       if (seq->vanilla_id != -1) {
  800.         new_entry.size = old_sequences[seq->vanilla_id].size;
  801.         new_entry.data = (uint8_t*)malloc(new_entry.size);
  802.         memcpy(new_entry.data, old_sequences[seq->vanilla_id].data, new_entry.size);
  803.       } else {
  804.         //In the Python code, this is where the custom sequence data is read from the file
  805.         //I think we are assuming here that the custom data has already been read into the sequence list, however
  806.         //So where in the python code seq_file is the name of the file, here I'm using it as the content of the file
  807.         new_entry.size = seq->seq_file_length;
  808.         new_entry.data = (uint8_t*)malloc(new_entry.size);
  809.         memcpy(new_entry.data, seq->seq_file, new_entry.size);
  810.       }
  811.     } else {
  812.       new_entry.size = old_sequence.size;
  813.       new_entry.data = (uint8_t*)malloc(new_entry.size);
  814.       memcpy(new_entry.data, old_sequence.data, new_entry.size);
  815.     }
  816.  
  817.     //Concatenate the full audio sequence and the new sequence data
  818.     if (new_entry.size > 0) {
  819.       //Align sequences to 0x10
  820.       if (new_entry.size % 0x10 != 0) {
  821.         //Extend size of data
  822.         int difference = 0x10 - (new_entry.size % 0x10);
  823.         new_entry.data = (uint8_t*)realloc(new_entry.data, new_entry.size + difference);
  824.         //Pad out with 0s
  825.         for (int j = new_entry.size; j < new_entry.size + difference; j++) {
  826.           new_entry.data[j] = 0;
  827.         }
  828.         new_entry.size += difference;
  829.       }
  830.       //Increment the current address by the size of the new sequence
  831.       address += new_entry.size;
  832.     }
  833.  
  834.     //Add to new sequence list
  835.     //In the original code this is before the previous stanza, but I think with Python "pointers", this is meant to store the version of the entry with the padded size?
  836.     new_sequences[i] = new_entry;
  837.   }
  838.  
  839.   //Combine the data into a big sequence
  840.   //Address has been keeping track of the necessary size for us
  841.   uint8_t* new_audio_sequence = (uint8_t*)malloc(address);
  842.   address = 0;
  843.   for (int i = 0; i < 0x6E; i++) {
  844.     SequenceData entry = new_sequences[i];
  845.     for (int j = 0; j < entry.size; j++) {
  846.       new_audio_sequence[address] = entry.data[j];
  847.       address++;
  848.     }
  849.   }
  850.  
  851.   //Find a value for the new address
  852.   int new_address = audioseq_start;
  853.   //Adjust the DMA table if necessary
  854.   if (address > audioseq_size) {
  855.     //Zero out the old audio sequence
  856.     for (int i = audioseq_start; i < audioseq_end; i++) {
  857.       rom.modified[i] = 0;
  858.     }
  859.     //Find free space and update dmatable
  860.     new_address = Rom_dma_freespace(&rom, address);
  861.     Rom_dma_update(&rom, AUDIOSEQ_DMADATA_INDEX, new_address, new_address + address, 0);
  862.   }
  863.  
  864.   //Write new audio sequence file
  865.   for (int i = 0; i < address; i++) {
  866.     rom.modified[new_address + i] = new_audio_sequence[i];
  867.   }
  868.  
  869.   int fanfare_bank_shift = CUSTOM_BANKS_SUPPORTED ? 0x26 : 0;
  870.  
  871.   //Update pointer table
  872.   for (int i = 0; i < 0x6E; i++) {
  873.     Rom_writeint32(&rom, 0xB89AE0 + (i * 0x10), new_sequences[i].address);
  874.     Rom_writeint32(&rom, 0xB89AE0 + (i * 0x10) + 4, new_sequences[i].size);
  875.     //Sequence* seq = get_replacement_sequence(sequences, sequences_length, i); //ToDo: No point to this?
  876.   }
  877.  
  878.   //Update instrument sets
  879.   Sequence_id* sequence_ids = get_sequence_ids(true, true, true, true, true);
  880.   for (int i = 0; i < sequence_ids->size / sizeof(Sequence_id); i++) {
  881.     Sequence_id seqId = sequence_ids[i];
  882.     //Get the replacement sequeunce
  883.     int id = seqId.id;
  884.     if (new_sequences[id].size == 0) {
  885.       id = new_sequences[id].address;
  886.     }
  887.     Sequence* seq = get_replacement_sequence(sequences, sequences_length, id);
  888.     //If one was found, then write the new instrument set
  889.     if (seq != NULL) {
  890.       int set = seq->instrument_set;
  891.       if (strncmp(seqId.type, "fanfare", 7) == 0 || strncmp(seqId.type, "ocarina", 7) == 0) {
  892.         set += fanfare_bank_shift;
  893.       }
  894.       rom.modified[0xB89911 + 0xDD + (seqId.id * 2)] = set;
  895.     }
  896.   }
  897.  
  898.   //Patch new instrument sets (banks) and add new instrument sounds
  899.   //Only if we were passed CFG_AUDIOBANK_TABLE_EXTENDED_ADDR via symbols which means we're on the right version.
  900.   if (!CUSTOM_BANKS_SUPPORTED) {
  901.     goto cleanup;
  902.   }
  903.  
  904.   //Builds new audio bank entrys for fanfares to prevent fanfares killing bgm in areas like Goron City
  905.   int bank_index_base = Rom_readint32(&rom, CFG_AUDIOBANK_TABLE_EXTENDED_ADDR, false) - 0x80400000 + 0x03480000;
  906.   //Build new fanfare banks by copying each entry in audiobank_index
  907.   for (int i = 0; i < 0x26; i++) {
  908.     uint8_t bank_entry[10];
  909.     for (int j = 0; j < 10; j++) {
  910.       bank_entry[j] = rom.modified[bank_index_base + 0x10 + 0x10 * i + j]; //Get the vanilla entry
  911.     }
  912.     bank_entry[9] = 1; //Update the cache type to 1
  913.     for (int j = 0; j < 10; j++) {
  914.       rom.modified[bank_index_base + 0x270 + 0x10 * i + j] = bank_entry[j]; //Write the new entry at the end of the bank table.
  915.     }
  916.   }
  917.   rom.modified[bank_index_base + 0x01] = 0x4C; //Updates AudioBank Index Header if no custom banks are present as this would be 0x26 which would crash the game if a fanfare was played
  918.  
  919.   Bank_Vector added_banks;
  920.   Bank_Vector_Init(&added_banks);
  921.  
  922.   sound_Vector added_instruments;
  923.   sound_Vector_Init(&added_instruments);
  924.  
  925.   uint8_t* instr_data;
  926.   int instr_data_size = 0;
  927.  
  928.   uint16_t new_bank_index = 0x4C;
  929.   int audiobank_start = rom.dma[AUDIOBANK_DMADATA_INDEX].start;
  930.   int audiobank_size = rom.dma[AUDIOBANK_DMADATA_INDEX].size;
  931.   int audiotable_start = rom.dma[AUDIOTABLE_DMADATA_INDEX].start;
  932.   int audiotable_size = rom.dma[AUDIOTABLE_DMADATA_INDEX].size;
  933.   int instr_offset_in_file = audiobank_size;
  934.   int bank_table_base = 0;
  935.  
  936.   //Process each sequence
  937.   for (int sequenceIndex = 0; sequenceIndex < 0x6E; sequenceIndex++) {
  938.     int bank_table_base = Rom_readint32(&rom, CFG_AUDIOBANK_TABLE_EXTENDED_ADDR, false) - 0x80400000 + 0x3480000;
  939.     int replacement_id = sequenceIndex;
  940.     if (new_sequences[sequenceIndex].size <= 0) {
  941.       replacement_id = new_sequences[sequenceIndex].address;
  942.     }
  943.     Sequence* seq = get_replacement_sequence(sequences, sequences_length, replacement_id);
  944.     if (seq != NULL && seq->new_instrument_set) {
  945.       //See if this bank has already been added
  946.       bool alreadyAdded = false;
  947.       uint16_t seq_bank_index = -1;
  948.       for (int bankIndex = 0; bankIndex < added_banks.len; bankIndex++) {
  949.         bool match = true;
  950.         //Check if the data is found in the added banks list already
  951.         if (added_banks.data[bankIndex].data_length == seq->zbank_file_length) {
  952.           for (int i = 0; i < seq->zbank_file_length; i++) {
  953.             if (added_banks.data[bankIndex].data[i] != seq->zbank_file[i]) {
  954.               match = false;
  955.               break;
  956.             }
  957.           }
  958.         } else {
  959.           match = false;
  960.         }
  961.         if (match) {
  962.           alreadyAdded = true;
  963.           seq_bank_index = added_banks.data[bankIndex].index;
  964.           break;
  965.         }
  966.       }
  967.       if (!alreadyAdded) {
  968.         Bank bank;
  969.         Bank_Init(&bank, new_bank_index, seq->bankmeta, seq->zbank_file);
  970.         //Handle any new instruments
  971.         for (int zsoundIndex = 0; zsoundIndex < seq->zsounds.size; zsoundIndex++) {
  972.           sound zsound = seq->zsounds.data[zsoundIndex];
  973.           uint16_t tempaddr = zsound.temp_addr;
  974.           uint8_t* curr_instrument_data = zsound.data;
  975.           int curr_instrument_data_size = zsound.size;
  976.           //See if this instrument has already been added
  977.           int addedInstrIndex = -1;
  978.           for (int instrIndex = 0; instrIndex < added_instruments.len; instrIndex++) {
  979.             bool match = true;
  980.             //Check if the data is found in the added banks list already
  981.             if (added_instruments.data[instrIndex].size == zsound.size) {
  982.               for (int i = 0; i < zsound.size; i++) {
  983.                 if (added_instruments.data[instrIndex].data[i] != zsound.data[i]) {
  984.                   match = false;
  985.                   break;
  986.                 }
  987.               }
  988.             } else {
  989.               match = false;
  990.             }
  991.             if (match) {
  992.               addedInstrIndex = instrIndex;
  993.               break;
  994.             }
  995.           }
  996.           //Already added this instrument. Just add it to the bank
  997.           if (addedInstrIndex != -1) {
  998.             Bank_add_zsound(&bank, tempaddr, zsound);
  999.           } else {
  1000.             //Add current to the total instrument data and pad out to 0x10
  1001.             int prevSize = instr_data_size;
  1002.             int nextSize = prevSize + curr_instrument_data_size;
  1003.             int padDifference = nextSize % 10 == 0 ? 0 : 0x10 - (nextSize % 0x10);
  1004.             instr_data_size = nextSize + padDifference;
  1005.             instr_data = (uint8_t*)realloc(instr_data, instr_data_size);
  1006.             for (int i = 0; i < curr_instrument_data_size + padDifference; i++) {
  1007.               if (i < curr_instrument_data_size) {
  1008.                 instr_data[prevSize + i] = curr_instrument_data[i];
  1009.               } else { //Pad out the rest with 0s
  1010.                 instr_data[prevSize + i] = 0;
  1011.               }
  1012.             }
  1013.             zsound.size = curr_instrument_data_size + padDifference;
  1014.             zsound.offset = instr_offset_in_file;
  1015.             instr_offset_in_file += zsound.size;
  1016.             Bank_add_zsound(&bank, tempaddr, zsound);
  1017.             sound_Vector_push(&added_instruments, zsound);
  1018.           }
  1019.         }
  1020.         seq_bank_index = bank.index;
  1021.         Bank_Vector_push(&added_banks, bank);
  1022.         new_bank_index++;
  1023.       }
  1024.       //Write a single byte for the bank index, although it is a 2 byte value elsewhere
  1025.       rom.modified[0xB89911 + 0xDD + (sequenceIndex * 2)] = seq_bank_index & 0xFF;
  1026.     }
  1027.   }
  1028.  
  1029.   //Patch the new instrument data into the ROM in a new file.
  1030.   //If there is any instrument data to add, move the entire audiotable file to a new location in the ROM.
  1031.   if (instr_data_size > 0) {
  1032.     //Read in original audiotable data and zero out existing file
  1033.     int audiotable_data_size = audiotable_size + instr_data_size;
  1034.     uint8_t* audiotable_data = (uint8_t*)malloc(audiotable_data_size);
  1035.  
  1036.     for (int i = 0; i < audiobank_size; i++) {
  1037.       audiotable_data[i] = rom.modified[audiotable_start + i];
  1038.       rom.modified[audiotable_start + i] = 0;
  1039.     }
  1040.  
  1041.     //Add the new data
  1042.     for (int i = 0; i < instr_data_size; i++) {
  1043.       audiotable_data[audiotable_size + i] = instr_data[i];
  1044.     }
  1045.  
  1046.     //Get new address for the file
  1047.     int new_audiotable_start = Rom_dma_freespace(&rom, audiotable_data_size);
  1048.  
  1049.     //Write the file to the new address
  1050.     for (int i = 0; i < audiotable_data_size; i++) {
  1051.       rom.modified[new_audiotable_start + i] = audiotable_data[i];
  1052.     }
  1053.  
  1054.     //Update DMA
  1055.     Rom_dma_update(&rom, AUDIOTABLE_DMADATA_INDEX, new_audiotable_start, new_audiotable_start + audiotable_data_size, 0);
  1056.  
  1057.     //Cleanup audiotable
  1058.     free(audiotable_data);
  1059.   }
  1060.  
  1061.   //Add new audio banks
  1062.   uint8_t* new_bank_data;
  1063.   //Read the original audiobank data
  1064.   uint8_t* audiobank_data = (uint8_t*)malloc(audiobank_size);
  1065.  
  1066.   for (int i = 0; i < audiobank_size; i++) {
  1067.     audiobank_data[i] = rom.modified[audiobank_start + i];
  1068.   }
  1069.  
  1070.   int new_bank_offset = audiobank_size;
  1071.   int new_bank_size = 0;
  1072.  
  1073.   for (int bankIndex = 0; bankIndex < added_banks.len; bankIndex++) {
  1074.     //Write bank data to rom
  1075.     Bank bank = added_banks.data[bankIndex];
  1076.     Bank_update_zsound_pointers(&bank);
  1077.     bank.offset = new_bank_offset;
  1078.     uint8_t* bank_entry = Bank_get_entry(&bank, new_bank_offset);
  1079.     int bank_entry_size = Bank_get_entry_size(&bank, new_bank_offset);
  1080.     for (int i = 0; i < bank_entry_size; i++) {
  1081.       rom.modified[bank_table_base + 0x10 + bank.index * 0x10 + i] = bank_entry[i];
  1082.     }
  1083.     //Add to total new bank data
  1084.     int prevSize = new_bank_size;
  1085.     int nextSize = prevSize + bank_entry_size;
  1086.     new_bank_data = (uint8_t*)realloc(new_bank_data, nextSize);
  1087.     for (int i = 0; i < bank_entry_size; i++) {
  1088.       new_bank_data[prevSize + i] = bank_entry[i];
  1089.     }
  1090.     new_bank_offset += nextSize;
  1091.     new_bank_size = nextSize;
  1092.  
  1093.     //Clean bank entry
  1094.     free(bank_entry);
  1095.   }
  1096.  
  1097.   //If there is any audiobank data to add, move the entire audiobank file to a new place in ROM. Update the existing dmadata record
  1098.   if (new_bank_size > 0) {
  1099.     //Zero out existing file
  1100.     for (int i = 0; i < audiobank_size; i++) {
  1101.       rom.modified[audiobank_start + i] = 0;
  1102.     }
  1103.     //Add the new data
  1104.     int prevSize = audiobank_size;
  1105.     int nextSize = prevSize + new_bank_size;
  1106.     audiobank_data = (uint8_t*)realloc(audiobank_data, nextSize);
  1107.     for (int i = 0; i < new_bank_size; i++) {
  1108.       audiobank_data[prevSize + i] = new_bank_data[i];
  1109.     }
  1110.     //Get new address for the file
  1111.     int new_audio_banks_addr = Rom_dma_freespace(&rom, nextSize);
  1112.     //Write the file to the new address
  1113.     for (int i = 0; i < nextSize; i++) {
  1114.       rom.modified[new_audio_banks_addr + i] = audiobank_data[i];
  1115.     }
  1116.     //Update DMA
  1117.     Rom_dma_update(&rom, AUDIOBANK_DMADATA_INDEX, new_audio_banks_addr, new_audio_banks_addr + nextSize, 0);
  1118.     //Update size of bank table in the Audiobank table header
  1119.     Rom_writeint16(&rom, bank_table_base, new_bank_index);
  1120.   }
  1121.  
  1122.   //Update the init heap size. This size is normally hardcoded based on the number of audio banks.
  1123.   int init_heap_size = Rom_readint32(&rom, 0xB80118, false);
  1124.   init_heap_size += (new_bank_index - 0x26) * 0x20;
  1125.   Rom_writeint32(&rom, 0xB80118, init_heap_size);
  1126.  
  1127.   //Cleanup buffers
  1128.   if (new_bank_data != NULL)
  1129.     free(new_bank_data);
  1130.  
  1131.   free(audiobank_data);
  1132.  
  1133.   if (instr_data != NULL)
  1134.     free(instr_data);
  1135.  
  1136.   //Cleanup vectors
  1137.   Bank_Vector_free(&added_banks);
  1138.   sound_Vector_free(&added_instruments);
  1139.  
  1140.   //Global cleanup
  1141. cleanup:
  1142.  
  1143.   free(sequence_ids);
  1144.   free(new_audio_sequence);
  1145.  
  1146.   //ToDo: Clean old_sequences and new_sequences data first
  1147.   for (int i = 0; i < 0x6E; i++) {
  1148.     SequenceData entry = new_sequences[i];
  1149.  
  1150.     if (entry.data != NULL)
  1151.       free(entry.data);
  1152.   }
  1153.  
  1154.   free(new_sequences);
  1155.  
  1156.   for (int i = 0; i < 0x6E; i++) {
  1157.     SequenceData entry = old_sequences[i];
  1158.  
  1159.     if (entry.data != NULL)
  1160.       free(entry.data);
  1161.   }
  1162.  
  1163.   free(old_sequences);
  1164. }
  1165.  
  1166. void rebuild_pointers_table(Rom rom, Sequence* sequences, int sequences_length) {
  1167.   for (int sequenceIndex = 0; sequenceIndex < sequences_length; sequenceIndex++) {
  1168.     Sequence sequence = sequences[sequenceIndex];
  1169.     //Get the original values
  1170.     uint8_t bgm_sequence[0x10];
  1171.     for (int i = 0; i < 0x10; i++) {
  1172.       bgm_sequence[i] = rom.original[0xB89AE0 + (sequence.vanilla_id * 0x10) + i];
  1173.     }
  1174.     uint8_t instr_1 = rom.original[0xB89910 + 0xDD + (sequence.vanilla_id * 2)];
  1175.     uint8_t instr_2 = rom.original[0xB89910 + 0xDD + (sequence.vanilla_id * 2) + 1];
  1176.     //Replace the values at the addresses we want
  1177.     for (int i = 0; i < 0x10; i++) {
  1178.       rom.modified[0xB89AE0 + (sequence.replaces * 0x10) + i] = bgm_sequence[i];
  1179.     }
  1180.     rom.modified[0xB89910 + 0xDD + (sequence.replaces * 2)] = instr_1;
  1181.     rom.modified[0xB89910 + 0xDD + (sequence.replaces * 2) + 1] = instr_2;
  1182.   }
  1183.   //Special handling for fairy fountain file select music
  1184.   uint8_t fairy_1 = rom.modified[0xB89910 + 0xDD + (0x28 * 2)]; //Based on the python code looks like this reads from the modified rather than the original
  1185.   uint8_t fairy_2 = rom.modified[0xB89910 + 0xDD + (0x28 * 2) + 1];
  1186.   rom.modified[0xB89910 + 0xDD + (0x57 * 2)] = fairy_1;
  1187.   rom.modified[0xB89910 + 0xDD + (0x57 * 2) + 1] = fairy_2;
  1188. }
  1189.  
  1190. void disable_music(Rom rom, int* ids, int ids_length) {
  1191.   uint8_t blank_track[0x10];
  1192.   //First track is blank, extract from rom
  1193.   for (int i = 0; i < 0x10; i++) {
  1194.     blank_track[i] = rom.modified[0xB89AE0 + i];
  1195.   }
  1196.   for (int idIndex = 0; idIndex < ids_length; idIndex++) {
  1197.     for (int i = 0; i < 0x10; i++) {
  1198.       rom.modified[0xB89AE0 + (ids[idIndex] * 0x10) + i] = blank_track[i];
  1199.     }
  1200.   }
  1201. }
  1202.  
  1203. void restore_music(Rom rom) {
  1204.   //Restore all music from original
  1205.   Sequence_id* sequence_ids = get_sequence_ids(true, true, true, true, true);
  1206.  
  1207.   for (int i = 0; i < sequence_ids->size / sizeof(Sequence_id); i++) {
  1208.  
  1209.     Sequence_id bgm = sequence_ids[i];
  1210.  
  1211.     //Get the original values
  1212.     uint8_t bgm_sequence[0x10];
  1213.     for (int i = 0; i < 0x10; i++) {
  1214.       bgm_sequence[i] = rom.original[0xB89AE0 + (bgm.id * 0x10) + i];
  1215.     }
  1216.  
  1217.     uint8_t instr_1 = rom.original[0xB89910 + 0xDD + (bgm.id * 2)];
  1218.     uint8_t instr_2 = rom.original[0xB89910 + 0xDD + (bgm.id * 2) + 1];
  1219.  
  1220.     //Replace the values at the addresses we want
  1221.     for (int i = 0; i < 0x10; i++) {
  1222.       rom.modified[0xB89AE0 + (bgm.id * 0x10) + i] = bgm_sequence[i];
  1223.       rom.modified[0xB89910 + 0xDD + (bgm.id * 2)] = instr_1;
  1224.       rom.modified[0xB89910 + 0xDD + (bgm.id * 2) + 1] = instr_2;
  1225.     }
  1226.  
  1227.     //Restore file select instrument
  1228.     uint8_t file_1 = rom.original[0xB89910 + 0xDD + (0x57 * 2)]; //Based on the python code looks like this reads from the modified rather than the original
  1229.     uint8_t file_2 = rom.original[0xB89910 + 0xDD + (0x57 * 2) + 1];
  1230.     rom.modified[0xB89910 + 0xDD + (0x57 * 2)] = file_1;
  1231.     rom.modified[0xB89910 + 0xDD + (0x57 * 2) + 1] = file_2;
  1232.  
  1233.     //Rebuild audioseq
  1234.     int orig_start = rom.dma_original[AUDIOSEQ_DMADATA_INDEX].start;
  1235.     int orig_end = rom.dma_original[AUDIOSEQ_DMADATA_INDEX].end;
  1236.     //Check if this needs to be <= instead of <
  1237.     for (int i = orig_start; i < orig_end; i++) {
  1238.       rom.modified[i] = rom.original[i];
  1239.     }
  1240.  
  1241.     //If audioseq was relocated
  1242.     int start = rom.dma[AUDIOSEQ_DMADATA_INDEX].start;
  1243.     if (start != orig_start) {
  1244.       //Zero out old audioseq
  1245.       for (int i = start; i < rom.dma[AUDIOSEQ_DMADATA_INDEX].end; i++) {
  1246.         rom.modified[i] = 0;
  1247.       }
  1248.       Rom_dma_update(&rom, AUDIOSEQ_DMADATA_INDEX, orig_start, orig_end, start);
  1249.     }
  1250.   }
  1251.  
  1252.   //Cleanup
  1253.   free(sequence_ids);
  1254. }
  1255.  
  1256. // void randomize_music(uint8_t* rom_original, uint8_t* rom_modified, Sequence* sequences, int sequences_length, Sequence* target_sequences, int target_sequences_length,
  1257. //                      Sequence* disabled_source_sequences, int disabled_source_sequences_length, Sequence* disabled_target_sequences, int disabled_target_sequences_length,
  1258. //                      bool bgm_random, bool fanfare_random, bool ocarina_random, bool credit_random, bool fileselect_random, bool custom_sequences) {
  1259. int randomize_music(uint8_t* rom_original, uint8_t* rom_modified, Sequence* sequences, int sequences_length, int* disabled_target_sequences, int disabled_target_sequences_length, char custom_sequences) {
  1260.  
  1261.   printf("[C] 1\n");
  1262.  
  1263.   //Copy raw rom data into rom struct
  1264.   Rom rom;
  1265.   rom.original = rom_original;
  1266.   rom.modified = rom_modified;
  1267.   //Get DMA for AUDIOSEQ_DMADATA
  1268.   DMAEntry seq_original;
  1269.   seq_original.index = AUDIOSEQ_DMADATA_INDEX;
  1270.   seq_original.start = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOSEQ_DMADATA_INDEX, true);
  1271.   seq_original.end = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOSEQ_DMADATA_INDEX + 4, true);
  1272.   seq_original.size = seq_original.end - seq_original.start;
  1273.   DMAEntry seq_modified;
  1274.   seq_modified.index = AUDIOSEQ_DMADATA_INDEX;
  1275.   seq_modified.start = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOSEQ_DMADATA_INDEX, false);
  1276.   seq_modified.end = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOSEQ_DMADATA_INDEX + 4, false);
  1277.   seq_modified.size = seq_modified.end - seq_modified.start;
  1278.   //Get DMA for AUDIOBANK_DMADATA
  1279.   DMAEntry bank_original;
  1280.   bank_original.index = AUDIOBANK_DMADATA_INDEX;
  1281.   bank_original.start = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOBANK_DMADATA_INDEX, true);
  1282.   bank_original.end = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOBANK_DMADATA_INDEX + 4, true);
  1283.   bank_original.size = bank_original.end - bank_original.start;
  1284.   DMAEntry bank_modified;
  1285.   bank_modified.index = AUDIOSEQ_DMADATA_INDEX;
  1286.   bank_modified.start = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOBANK_DMADATA_INDEX, false);
  1287.   bank_modified.end = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOBANK_DMADATA_INDEX + 4, false);
  1288.   bank_modified.size = bank_modified.end - bank_modified.start;
  1289.   //Get DMA for AUDIOTABLE_DMADATA
  1290.   DMAEntry table_original;
  1291.   table_original.index = AUDIOTABLE_DMADATA_INDEX;
  1292.   table_original.start = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOTABLE_DMADATA_INDEX, true);
  1293.   table_original.end = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOTABLE_DMADATA_INDEX + 4, true);
  1294.   table_original.size = table_original.end - table_original.start;
  1295.   DMAEntry table_modified;
  1296.   table_modified.index = AUDIOSEQ_DMADATA_INDEX;
  1297.   table_modified.start = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOTABLE_DMADATA_INDEX, false);
  1298.   table_modified.end = Rom_readint32(&rom, DMA_START + DMA_SIZE * AUDIOTABLE_DMADATA_INDEX + 4, false);
  1299.   table_modified.size = table_modified.end - table_modified.start;
  1300.   //Insert DMA entries into the rom struct
  1301.   rom.dma_original = (DMAEntry*)malloc(sizeof(DMAEntry) * (file_end + 1));
  1302.   rom.dma_original[AUDIOSEQ_DMADATA_INDEX] = seq_original;
  1303.   rom.dma_original[AUDIOBANK_DMADATA_INDEX] = bank_original;
  1304.   rom.dma_original[AUDIOTABLE_DMADATA_INDEX] = table_original;
  1305.   rom.dma = (DMAEntry*)malloc(sizeof(DMAEntry) * (file_end + 1));
  1306.   rom.dma[AUDIOSEQ_DMADATA_INDEX] = seq_modified;
  1307.   rom.dma[AUDIOBANK_DMADATA_INDEX] = bank_modified;
  1308.   rom.dma[AUDIOTABLE_DMADATA_INDEX] = table_modified;
  1309.  
  1310.   //Handle CFG_AUDIOBANK_TABLE_EXTENDED_ADDR
  1311.   int CFG_AUDIOBANK_TABLE_EXTENDED_ADDR = -1;
  1312.   int cosmetic_context = Rom_readint32(&rom, COSMETICS_CONTEXT_ADDR, false) - 0x80400000 + 0x03480000;
  1313.   //Check if the cosmetics version is high enough
  1314.   int cosmetics_version = Rom_readint32(&rom, cosmetic_context, false);
  1315.   if (cosmetics_version >= CFG_AUDIOBANK_TABLE_EXTENDED_ADDR_VERSION) {
  1316.     //It is, so read in the value for the address
  1317.     int CFG_AUDIOBANK_TABLE_EXTENDED_ADDR = Rom_readint32(&rom, cosmetic_context + CFG_AUDIOBANK_TABLE_EXTENDED_ADDR_OFFSET, false);
  1318.   }
  1319.  
  1320.   printf("[C] 2\n");
  1321.  
  1322.   //Business logic for calling each function
  1323.   restore_music(rom);
  1324.  
  1325.   printf("[C] 3\n");
  1326.  
  1327.   // if (bgm_random) {
  1328.   //   process_sequences(rom, get_sequence_ids(true, false, false, credit_random, false), disabled_source_sequences, disabled_source_sequences_length,
  1329.   //                     disabled_target_sequences, disabled_target_sequences_length, custom_sequences, sequences, sequences_length, target_sequences, target_sequences_length);
  1330.   // }
  1331.   // if (fanfare_random) {
  1332.   //   process_sequences(rom, get_sequence_ids(true, false, ocarina_random, false, false), disabled_source_sequences, disabled_source_sequences_length,
  1333.   //                     disabled_target_sequences, disabled_target_sequences_length, custom_sequences, sequences, sequences_length, target_sequences, target_sequences_length);
  1334.   // }
  1335.  
  1336.   if (custom_sequences) {
  1337.     rebuild_sequences(rom, sequences, sequences_length, CFG_AUDIOBANK_TABLE_EXTENDED_ADDR);
  1338.   } else {
  1339.     rebuild_pointers_table(rom, sequences, sequences_length);
  1340.   }
  1341.  
  1342.   printf("[C] 4\n");
  1343.  
  1344.   //Version where disabled_target_sequences is a list of Sequence
  1345.   // if (disabled_target_sequences_length > 0) {
  1346.   //   int* disabled_ids = (int*)malloc(sizeof(int) * disabled_target_sequences_length);
  1347.   //   for (int i = 0; i < disabled_target_sequences_length; i++) {
  1348.   //     disabled_ids[i] = disabled_target_sequences[i].vanilla_id;
  1349.   //   }
  1350.   //   disable_music(rom, disabled_ids, disabled_target_sequences_length);
  1351.   // }
  1352.  
  1353.   //Version where disabled_target_sequences is a list of int
  1354.   if (disabled_target_sequences_length > 0) {
  1355.     disable_music(rom, disabled_target_sequences, disabled_target_sequences_length);
  1356.   }
  1357.  
  1358.   //Cleanup
  1359.   free(rom.dma_original);
  1360.   free(rom.dma);
  1361.  
  1362.   printf("[C] 5\n");
  1363.  
  1364.   return 0;
  1365. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement