tango.zh Beta 2 ================ Basic usage ================ There are three functions that need to be added to the active global script. Tango_Start() should be called before the main loop, in the main loop before Waitdraw(), and Tango_Update2() in the main loop after Waitdraw(). It is recommended that Tango_Update1() be called before any other funcions so that buttons can be unpressed as soon as possible. Tango_Update2() should generally come after everything else that does any drawing, since one normally wants message windows drawn on top of everything else. At least one style must be set up. This can be done once per quest or on demand. Setting up a style simply involves repeated calls to Tango_SetStyleAttribute(). Displaying text on the screen requires six steps: 1: Find a free text slot (Tango_GetFreeSlot()) 2: Clear any data already in the slot (Tango_ClearSlot()) 3: Load text into the slot (Tango_LoadString() or Tango_LoadMessage()) 4: Set a style (Tango_SetSlotStyle()) 5: Set the position (Tango_SetSlotPosition()) 6: Activate the text slot (Tango_ActivateSlot()) Displaying a menu from a script takes four or five steps: 1: Initialize menu data (Tango_InitializeMenu()) 2: Add choices (Tango_AddChoice()) 3: Set the cursor's appearance (Tango_SetMenuCursor()) 4: (optional) Set the menu sound effects (Tango_SetMenuSFX()) 5: Activate the menu (Tango_ActivateMenu()) ================ Text slots ================ Tango has a number of "text slots" where text and associated data are stored. Before any text can be displayed on the screen, it must be loaded into a slot, and the slot must have a style set. Slots are numbered 0 to __TANGO_NUM_SLOTS-1. Text slots are defined in __Tango_SlotDefs[]. The slot definition defines where in the buffer text is stored and where it's rendered on the offscreen bitmap. It is permissible for slots to overlap in both the buffer and the bitmap, but be careful about this; using overlapping slots simultaneously will definitely cause problems. Slot types serve three possible purposes. 1: Ordering Text slots are drawn to the screen in the order they're defined in __Tango_SlotDefs[]. That means later slots will appear on top of earlier ones. If there's a string that should always appear on top of any others, you can define a slot type that's only used by the last slot. 2: Reservation There are a limited number of text slots available. If you display several strings at once, you could run into a situation where you want to display another but have no free slots for it. If there's something you always want to be able to show, create a slot type just for that, and you can be sure it will be available when you need it. 3: Efficiency Using different slot types lets you divide up __Tango_Buffer[] efficiently. It may be that you want to display one or two long strings at a time along with a lot of small strings. Creating separate slot types for long and short strings lets you do this without wasting a lot of space in the buffer. The intention is that all slots of a given type will use the same amount of space in the buffer and the bitmap, but this is not enforced. There's no obvious reason to make slots of the same type different, but you can if you like. There are two slots and one slot type defined by default. This should be sufficient for most quests, but you can add as many slots and types as you like. Slot type IDs should be 0 or greater. ================ Fonts ================ Tango can't use ZC's built-in fonts directly; it needs additional data about spacing to position everything correctly. Tango font definitions are arrays that provide the necessary information. Definitions for most built-in fonts are included, but they're not imported by default. The files are in the tango/font directory. Although they aren't constants (since ZScript doesn't allow constant arrays), the names are written in all caps to indicate that they should be used as though they were. You can create your own fonts, too. Using characters made from tiles, you can extend built-in fonts with additional characters or create completely original ones. The drawback of tile-based characters is that they have fewer color options; they only have a CSet, not a CSet and a color. On the other hand, tile-based characters can use multiple colors, and they can even be 8-bit. If you want to create a font, see the font format section of tango.txt for details. ================ Styles ================ Before any text can be displayed, the slot must have a style set. The style defines how the text will be displayed - the font, the backdrop, the sound effects, and so forth. Style IDs are integers 0 and up. Use Tango_SetStyleAttribute() to set each style attribute. You must at least set the font and color; every other setting has a valid (but not necessarily useful) default. The attributes and expected values are listed in the style attributes section of tango.txt. ================ Tango code ================ Tango implements a simple scripting language with functions embedded in strings. Code is identified by the character '@' (by default; set __TANGO_CODE_DELIMITER to change this). @ is followed immediately by a function name, then up to two arguments in parentheses, separated by spaces. Parentheses are needed even if a function takes no arguments. For example, the string "@playsfx(64)Hello, @savename()!" would play sound 64 and print (possibly) "Hello, Link!" You can also use @## or @(##)to insert a character directly into the text. The string "@90@69@76@68@65" would be printed as "ZELDA" This is useful for inserting line breaks (@26) and font characters beyond the ASCII range. Also, @0 can be used to terminate the text early; anything after @0 won't be printed. It's possible to create your own functions. These can be numeric, effect, or condition functions. The function's name must be a series of lower-case letters and numbers, and the first character must be a letter. There's no set limit on length, but the name must convert to a number small enough to be represented in ZScript (no greater than 214747.9999). To implement a function, you need to get the converted value of its name. The easiest way to do this is to use Tango_ConvertFunctionName(). This will not only tell you the necessary value, but also write a constant definition to allegro.log so that you can simply copy and paste it. To make Tango handle this function, you'd create a constant with the converted value, add it to __Tango_CustomFunctions[], and add the implementation to __Tango_RunCustomFunction(). The function argument is the function ID. args is an array containing the arguments. A function can take up to four arguments. Any unused arguments will be 0. const float FUNC_DOSTUFF2 = 543.3828; int __Tango_CustomFunctions[] = { FUNC_DOSTUFF2 }; float __Tango_RunCustomFunction(float function, float args) { if(function==FUNC_DOSTUFF2) { // This will just return the sum of the arguments. return args[0]+args[1]; } return 0; } Note that it's possible, although very unlikely, for two function names to convert to the same number. In that case, you'll just have to rename one of them. The method for converting a function name to a number is described in the function name conversion section of tango.txt. ================ Warnings ================ Text is drawn into offscreen bitmaps one character at a time, even when an entire string is drawn at once. Using TANGO_FLAG_INSTANTANEOUS with long strings will push you significantly closer to the drawing limit. Although Tango performs a lot of input validation, catching every problem is not feasible. Some errors can hang or crash the game, so be prepared for that when making changes.