tango.zh
Version 1.3.3


================================

How do I display a string?


1: Find a free text slot (Tango_GetFreeSlot())
2: Clear all data 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 on the screen (Tango_SetSlotPosition())
6: Activate the text slot (Tango_ActivateSlot())

Tango_LoadString() loads a ZScript string (an int array); Tango_LoadMessage()
loads a ZC message (Quest -> Strings). All built-in function names follow
this naming convention.

You'll probably want to combine these into a single function for simplicity.
tangoQuickStart.zh provides examples in the ShowString() and ShowMessage()
functions.

================================

What is a text slot?


Text slots are where strings are stored for processing and display. They store
the text, the style, and the position on the screen, as well as some internal
data. Before any text can be shown on the screen, it must be loaded into
one of the available slots.

Slot IDs are integers counting up from 0. Most often, you'll want to find
a free slot automatically, but you can also use hardcoded slot numbers.
Each slot has its own definition, which determines how long a string can be and
how much space is available for drawing it.

================================

What is a style?


A style determines the appearance and behavior of displayed text. For instance,
the font, the backdrop, and whether the text can be sped up by holding A
are all controlled by the style.

Style IDs are integers counting up from 0. Every text slot using the same style
will have the same appearance and behavior.

================================

How many text slots do I need?


You need at least as many slots as will ever be active at once. If you want
fifty strings onscreen at once, you need fifty slots. If you only want one
string active at a time, just one slot will suffice.

For more advanced uses, you may want more slots than are strictly necessary.
For instance, you might want to reserve certain slots for specific purposes,
even if they'll never all be in use at once.

================================

How do I add more text slots?


Set __TANGO_NUM_SLOTS to the number of slots you want and change the size of
__Tango_Buffer[] so that it's large enough to hold the text for all of them.

The slot definitions go in __Tango_SlotDefs[]. The first seven numbers define
slot 0, the next seven define slot 1, and so on. In order, these numbers are
the slot type, the starting index and size in __Tango_Buffer[], the X and Y
coordinates on the bitmap, and the width and height on the bitmap. For example:

int __Tango_SlotDefs[] = {
    // Slot 0
    TANGO_SLOT_NORMAL, // The slot type
    0, 512,   // Occupies __Tango_Buffer[0] to __Tango_Buffer[511]
    0, 0,     // Draws to a region at 0, 0 on the bitmap
    192, 128, // Drawing region is 192x128 pixels
    
    // Slot 1
    TANGO_SLOT_SMALL,
    512, 64, // Occupies __Tango_Buffer[512] to __Tango_Buffer[575]
    0, 128,  // Draws to a region at 0, 128 (just below slot 0)
    128, 32  // Drawing region is 128x32
    
    // Slot 2
    TANGO_SLOT_SMALL,
    576, 64, // Occupies __Tango_Buffer[576] to __Tango_Buffer[639]
    0, 160,  // Draws to a region at 0, 160 (just below slot 1)
    128, 32  // Drawing region is 128x32
};

The slot type is arbitrary. It can be any non-negative number. The default
slot type, TANGO_SLOT_NORMAL, can safely be renamed or deleted.

Generally, you shouldn't let slots overlap in the buffer or the bitmap.
If they won't be in use at the same time, however, it won't cause problems.
If you use a very large number of slots, it may even be necessary for them
to share some space on the bitmap.

================================

What is the purpose of slot types?


A slot's type makes no difference to how it's handled internally. Slot types
exist only for users to create distictions. There are three reasons you might
use different slot types:

1: Reservation
In order to display a string, you must first have a free slot. If no slots
are free, you can't show any text without clearing one out. If there's
something you need to be able to display, you can create a dedicated slot type
for it, so there will always be a slot free when you need it.

2: Drawing order
Text slots are drawn to the screen in order from first to last. If you want
certain strings to be drawn above or below others, you can enforce this by
using different slot types. If slots 0-3 have type SLOT_BG and slots 4-5
have type SLOT_FG, SLOT_FG slots will always be drawn on top of SLOT_BG slots.

3: Efficient use of space
If you plan to have one or two long strings appear alongside a lot of
short ones, you can use different slot types to avoid wasting space
in __Tango_Buffer[].

Ordinarily, it is expected that all slots of the same type have the same amount
of space allocated in the buffer and on the bitmap, but this is not enforced.

================================

How do I create a style?


With a series of calls to Tango_SetStyleAttribute(). Each call will set
a single attribute of the style. At a minimum, you must set a font and
color for the text. See tangoQuickStart.zh for an example.

If you want to unload a style after it's been set up, use Tango_ClearStyle().
This is only necessary if you want to reuse an ID for a different style,
which is rarely done.

================================

When should I set up a style?


Any time before it's actually used is fine. The most common method is
to set up all of your styles at the beginning of the active global script.
They'll stay loaded until you unload them or change them, so it's also okay
to do it in the Init script. Another approach is to set a style up immediately
before displaying a string that uses it; this may be preferable when using
a large number of different styles.

A combination of those two methods is also possible. If you want multiple
styles that are mostly the same, you might set the common attributes
in advance and set the distinct ones on demand.

Changing a style while it's in use is permitted, but changes to the text color
and font will not affect any text that has already been printed.

================================

Why isn't the screen freeze style flag working?


There are two functions in the main file, __Tango_FreezeScreen() and
__Tango_UnfreezeScreen(), that are blank by default. In order for the
screen freeze style flag to work, you must implement these functions.

The reason that they're blank is that there isn't a reasonable default
implementation; they're too dependent on the quest. Grabbing arbitrary FFCs
or changing combo definitions in an unknown quest might cause serious problems.

The recommended method is to set two unused FFCs to combos of type
"Screen Freeze (Except FFCs)" and "Screen Freeze (FFCs Only)". Be aware,
however, that if an FFC script triggers this, that script will freeze, too.
If you're using ghost.zh, SuspendGhostZHScripts() and ResumeGhostZHScripts()
should be used as well.

================================

Why isn't my script working correctly?


Whenever something doesn't work, you should look at allegro.log to see
if any errors have been reported. You'll get more helpful messages using
full logging, which is enabled by importing loggingFull.zh instead of
loggingMinimal.zh. These are found near the bottom of the main file.

Some common errors:

Using more styles than alloted
- Fixed by increasing __TANGO_NUM_STYLES and the size of __Tango_Styles[]

Using more menu options than alloted
- Fixed by increasing __TANGO_MAX_MENU_ITEMS and the size of __Tango_Data[]

Incorrect constants for custom functions
- Use Tango_ConvertFunctionName() to make sure you've got them right

You can also try calling the function Tango_ValidateConfiguration(). This will
analyze your settings and report any errors it finds in allegro.log.

================================

