45 printf(
"warning zero length block allocated");
55 sbl->
buf = (uint8_t*)malloc(len);
56 sbl->
relocs = (uint16_t*)malloc(32);
60 sbl->
flag = bank >> 3;
76 unsigned char* rom_ptr;
85 a = *(
unsigned short*)rom_ptr;
96 b = *(
unsigned short*)(rom_ptr + 2);
99 if (addr >= b && addr - b < a) {
102 return rom_ptr + addr - b;
127 spc_command[j].
next = j + 1, j++;
128 spc_command[j].
next = -1;
131 spc_command[j].
prev = j - 1, j--;
132 spc_command[j].
prev = -1;
167 if (spc_command[l].flag & 4) {
168 j = spc_command[l].
tim;
169 m = spc_command[l].
tim2;
176 if (spc_command[l].flag & 1)
177 n = spc_command[l].
b1;
179 l = spc_command[l].
next;
198 spc_command2 = spc_command + i;
199 if (spc_command2->
cmd == 0xef) {
200 k = *(
short*)&(spc_command2->
p1);
202 printf(
"Invalid music address\n");
206 if (spc_command2->
flag & 1) {
210 j += spc_command[k].
tim2 * spc_command2->
b1;
211 j += (spc_command2->
p3 - 1) * spc_command[k].tim2 *
ss_lasttime;
214 spc_command2->
b1 * (m + spc_command[k].
tim2 * spc_command2->
p3);
221 j += (spc_command2->
p3 - 1) *
ss_lasttime * spc_command[k].tim2,
222 m = spc_command[k].tim2;
224 m += spc_command[k].
tim2 * spc_command2->
p3;
227 if (spc_command2->
cmd < 0xe0)
229 if (spc_command2->
flag & 1) {
230 j += m * spc_command[i].
b1;
234 spc_command2->
tim = j;
235 spc_command2->
tim2 = m;
236 spc_command2->
flag |= 4;
241 i = spc_command2->
prev;
245 return spc_command[num].
tim + prevtime * spc_command[num].
tim2;
276 unsigned char* a =
nullptr;
287 printf(
"Address not found when loading track");
294 for (c = 0; c < e; c++) {
295 if (sr[c].bank == d) {
296 if (sr[c].start > addr) {
300 }
else if (sr[c].end > addr) {
301 for (f = sr[c].first; f != -1; f = spc_command[f].
next) {
302 if (spc_command[f].flag & 4)
303 m = spc_command[f].
tim, o = spc_command[f].
tim2;
304 if (spc_command[f].addr == addr) {
305 spc_command[f].
tim = m;
306 spc_command[f].
tim2 = o;
310 if (spc_command[f].flag & 1)
311 k = spc_command[f].
b1;
312 if (spc_command[f].cmd < 0xca) {
320 printf(
"Misaligned music pointer");
333 for (g = addr; g < f;) {
334 spc_command2 = spc_command + i;
335 if (spc_command2->
next == -1) {
339 spc_command2 = spc_command + i;
342 spc_command[l].
next = l + 1, l++;
343 spc_command[l].
next = -1;
346 spc_command[l].
prev = l - 1, l--;
347 spc_command[l].
prev = i;
348 spc_command2->
next = l;
350 spc_command2->
addr = g;
354 if (m >= t && b != 0xf9)
360 k = spc_command2->
b1 = b;
363 j = 3, spc_command2->
b2 = b, b = a[g++];
372 spc_command2->
cmd = b;
373 spc_command2->
flag = j;
377 spc_command2->
p1 = a[g++];
379 spc_command2->
p2 = a[g++];
381 spc_command2->
p3 = a[g++];
384 spc_command[spc_command2->
next].
prev = -1;
387 spc_command2 = spc_command + i;
388 *(
short*)(&(spc_command2->
p1)) = l;
390 spc_command[spc_command2->
next].
prev = i;
392 if (spc_command[l].flag & 4)
394 (spc_command[l].
tim + spc_command[l].
tim2 * k) * spc_command2->
p3;
396 i = spc_command2->
next;
403 i = spc_command2->
next;
406 spc_command[h].
tim = m;
407 spc_command[h].
tim2 = o;
408 spc_command[h].
flag |= 4;
410 if (f == g && m < t) {
411 l = spc_command[i].
prev;
415 if (spc_command[l].flag & 4)
416 spc_command[h].
tim = spc_command[l].
tim + m + spc_command[l].
tim2 * k,
417 spc_command[h].
flag |= 4;
435 spc_command[spc_command[i].
prev].
next = -1;
438 spc_command[i].
prev = -1;
759 if (spc_command[i].flag & 8)
760 return spc_command[i].
addr;
763 j = spc_command[i].
prev;
769 for (j = 0; j <
srnum; j++) {
770 if (sr[j].first == i) {
777 spc_command2 = spc_command + m;
778 if (spc_command2->
flag & 1)
779 k++, n = spc_command2->
b1;
780 if (spc_command2->
flag & 2)
782 if (spc_command2->
cmd >= 0xe0)
784 m = spc_command2->
next;
789 l = (songtime + 126) / 127;
793 if (n && !songtime % n) {
808 spc_command2 = spc_command + i;
810 spc_command2->
flag |= 8;
811 if (spc_command2->
flag & 1)
812 *(b++) = spc_command2->
b1;
813 if (spc_command2->
flag & 2)
814 *(b++) = spc_command2->
b2;
815 *(b++) = spc_command2->
cmd;
816 if (spc_command2->
cmd >= 0xe0) {
818 if (spc_command2->
cmd == 0xef) {
822 AddSpcReloc(sbl, b - sbl->
buf);
823 b[2] = spc_command2->
p3;
827 *(b++) = spc_command2->
p1;
829 *(b++) = spc_command2->
p2;
831 *(b++) = spc_command2->
p3;
834 i = spc_command2->
next;
839 l = (songtime + 126) / 127;
847 for (; songtime >= n; songtime -= n)
851 *(b++) = (uint8_t)songtime;
856 return spc_command[num].
addr;
860 printf(
"Address %04X not found", num);
888 if (((addr + len + 4) & 0x7fff) > 0x7ffb) {
889 if (addr + 5 > limit)
891 *(
int*)(rom_data + addr) = 0x00010140;
892 rom_data[addr + 4] = 0xff;
896 if (addr + len + 4 > limit) {
898 printf(
"Not enough space for sound data");
903 *(
short*)(rom_data + addr) = len;
904 *(
short*)(rom_data + addr + 2) = spc;
906 memcpy(rom_data + addr + 4, buf, len);
908 return addr + len + 4;
1392 printf(
"Invalid address: %04X", i);
1397 if ((j = spc_command[i].prev) != -1)
1403 for (l = 0; l < k; l++)
1410 printf(
"Not found: %04X", i);
1447 spc_command->
prev = -1;
1448 spc_command->
next = -1;
1449 spc_command->
cmd = 128;
1450 spc_command->
flag = 0;
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
void EditTrack(Rom &rom, short i)
Opens an editor window for a specific track. (Legacy UI-related function)
unsigned char * GetSpcAddr(Rom &rom, unsigned short addr, short bank)
Gets a direct pointer to music data within the ROM. This function is critical for parsing....
short AllocSpcCommand()
Allocates a new SpcCommand from a pre-allocated pool. This uses a classic free-list implementation fo...
SongSpcBlock * AllocSpcBlock(int len, int bank)
Allocates a new SongSpcBlock for holding generated SPC data. These blocks are the building blocks for...
void SaveSongs(Rom &rom)
High-level function to save all modified song data back to the ROM. (Currently commented out,...
short LoadSpcCommand(Rom &rom, unsigned short addr, short bank, int t)
Loads a block of music data from a given ROM address. This is the main parser. It reads the raw byte ...
short GetBlockTime(Rom &rom, short num, short prevtime)
Calculates the total time (duration) of a block of SpcCommands. This is essential for synchronization...
int WriteSpcData(Rom &rom, void *buf, int len, int addr, int spc, int limit)
Writes a prepared data block into the ROM file. This is a utility for SaveSongs, formatting the data ...
short SaveSpcCommand(Rom &rom, short num, short songtime, short endtr)
Saves a block of edited SpcCommands back into a binary format. This is the serializer,...
void NewSR(Rom &rom, int bank)
Creates a new, empty song range (SongRange) and opens it for editing. (Legacy UI-related function)
SpcCommand * current_spc_command_
void LoadSongs(Rom &rom)
High-level function to load all song data from the ROM. (Currently commented out, but this would be t...
void AddSpcReloc(music::SongSpcBlock *sbl, short addr)
A metadata structure to keep track of parsed sections of the song data. Used to avoid re-parsing the ...
Represents a block of binary data destined for the APU (SPC700) RAM. This is the intermediate format ...
The core data structure representing a single command in a music track. A song track is a doubly-link...