My main point though... I think I might have found a tango bug. This is a little complex, so bear with me. What I'm attempting to do is add flavor text to my custom subscreen. Previously, my system worked like this. When the subscreen initialized, it called a PickSubscreenMessage() function. This function ran through a series of if statements, checking the character you were playing and the dmap you were on, then loaded the proper strings into tango slots. I then had another function in the subscreen's update loop play the tango slots in sequential order, using Tango_SlotIsFinished() to time them, mimicking a conversation taking place. So the function looked something like this.
int PickSubscreenMessage(){ if(Link->Item[EMILY_RING] || Link->Item[LUCAS_RING] || Link->Item[CAELAN_RING]){ if(Game->GetCurDMap() == 1 || Game->GetCurDMap() == 23){ //Caverns int String1[] = "How far do you think these caves go?"; int String2[] = "Only one way to find out."; SetTangoSubscreenMessage(String1, STYLE_LUCAS, 0, 40, 106); SetTangoSubscreenMessage(String2, STYLE_EMILY, 1, 40, 138); return 1; } if(Game->GetCurDMap() == 2){ //And so on... } } }This worked at first, until I kept adding DMap checks, with each if statement having 2-4 strings being declared inside. This apparently caused a stack overflow that would sometimes hang ZC and other times would cause tango to give me Error 0 (no such error exists) and just not print any strings.
To get around this stack overflow problem, I figured I could put each dmap's strings in their own function. That way, no one function would contain enough strings to cause a stack overflow. So now my system looks something like this.
int PickSubscreenMessage(){ if(Link->Item[EMILY_RING] || Link->Item[LUCAS_RING] || Link->Item[CAELAN_RING]){ if(Game->GetCurDMap() == 1 || Game->GetCurDMap() == 23){ //Caverns CavernsMessages(); } if(Game->GetCurDMap() == 2){ //And so on... } } } int CavernsMessages(){ if(Link->Item[EMILY_RING] || Link->Item[LUCAS_RING] || Link->Item[CAELAN_RING]){ int String1[] = "How far do you think these caves go?"; int String2[] = "Only one way to find out."; SetTangoSubscreenMessage(String1, STYLE_LUCAS, 0, 40, 106); SetTangoSubscreenMessage(String2, STYLE_EMILY, 1, 40, 138); return 1; } }I thought that would solve the problem. Instead... it hangs ZC. Tracing revealed that the SetTangoSubscreenMessage function was the offender, so I did some more tracing there. Here's what it looked like (with some traces added to figure out where it was hanging).
void SetTangoSubscreenMessage(int message, int style, int slot, int x, int y){ // x should be 40, y 106 for first and 138 for second Trace(1); Trace(slot); Tango_ClearSlot(slot); Trace(2); Trace(slot); Tango_LoadString(slot, message); Trace(3); Tango_SetSlotStyle(slot, style); Trace(4); Tango_SetSlotPosition(slot, x, y); Trace(5); }There's a good reason for tracing slot multiple times, as will become apparent later. Here's what I get when I load the quest and open the subscreen.
1.0000 0.0000 2.0000 0.0000 tango.zh:No error could even print. Wonderfully helpful. I was concerned that maybe passing strings into the function was the problem, so I added a dummy string to the function to see if that fixed it.
void SetTangoSubscreenMessage(int message, int style, int slot, int x, int y){ // x should be 40, y 106 for first and 138 for second Trace(1); Trace(slot); Tango_ClearSlot(slot); Trace(2); Trace(slot); int String[] = "Test"; Tango_LoadString(slot, String); Trace(3); Tango_SetSlotStyle(slot, style); Trace(4); Tango_SetSlotPosition(slot, x, y); Trace(5); }And now, attempting to open the subscreen the first time generates a tango error and terminates the script, and attempting to open it a second time hangs ZC. Here's what I get now, pressing start twice (the first time apparently terminating the script, the second time hanging ZC):
1.0000 0.0000 2.0000 0.0000 tango.zh: tango.zh error: Invalid slot specified. Slot was 10.0000; valid slots are integers from 0 to 9 1.0000 0.0000 2.0000 0.0000 tango.zh:So I see multiple issues which may all stem from the same source. For starters, tango is somehow becoming very confused on what slot I'm referencing. Despite it tracing that slot is 0, on the very next line, when it attempts to load a string into that slot, it panics, thinking that the slot is in fact 10. Furthermore, this is causing ZC to hang without even printing an error at times, happening immediately if I load a string via a an argument in the function and only on the second attempt at running the function when I declare a string within the function.
Needless to say, I'm a little lost here. I don't feel like I'm doing anything wrong; it seems like tango's just freaking out on me, and I don't understand the inner workings nearly enough to address the issue myself. Is this a tango bug? Or am I doing something wrong here?
Unrelated to the above, but I do have a suggestion for the next version of tango (if that ever happens). Could we get functions like Tango_GetSlotPosition? I made a function to draw character portraits to accompany their strings, with the portrait depending on the string's style, and I had to do some stupid stuff with internal variables to get it working...
int dataStart=i*__TANGO_SIZEOF_DATA; //My oh my int CurrentX = __Tango_SlotData[dataStart+__TSDIDX_SCREEN_X]; //We appear to be on an internal variable amusement park ride int CurrentY = __Tango_SlotData[dataStart+__TSDIDX_SCREEN_Y]; //Life is suffering and I just make witty remarks to stay sane int Style = __Tango_SlotData[dataStart+__TSDIDX_STYLE]; //Why did I sign up for this?I feel like having to dig through the inner workings of the library shouldn't be required for something as simple as this (and boy did that take me a while...). Though on the plus side, tango's much less of a black box to me than it was a month ago.