Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GUI Format (Panel Layout)

A .gui file describes one screen of the game’s interface: a panel rectangle and a flat list of controls with their tags, positions, borders, text and colours. The in-game HUD, the equipment screen, the main menu and the message boxes each have one.

GUI is built on GFF (Generic File Format), the engine’s labelled key/value tree. If you have not read the GFF page, start there.

This page documents what the shared panel loader reads, why the rest of the file reaches the engine only by name, and what a corpus census of every shipped .gui shows about which paths are structural. Evidence is drawn from Ghidra decompilation of swkotor.exe (K1 GOG build), cross-checked against every .gui in a full install.

At a Glance

PropertyValue
Extension(s).gui
Magic SignatureGUI / V3.2
TypeInterface panel layout
Rust ReferenceNo typed view. Read as a generic GFF tree via rakata_formats::Gff

Population. The files live in data/gui.bif, indexed by chitin.key, plus a handful in patch.erf. Most of the patch copies shadow resrefs that also exist in gui.bif (abilities, character, equip, inventory, mainmenu), and two appear nowhere else (mipc212x10, tooltip12x10). The type occurs in no module RIM, no lips archive and no texture pack.

Every count on this page is measured over that population, and the census at the end gives it as a denominator, so the numbers there are the finding rather than decoration.

A .gui restyles a panel the binary already knows about

It cannot describe a new one. This is the fact the rest of the page depends on, and the format’s name works against it. There is no generic GUI loader that reads a control list and builds an interface from it.

What the shared panel loader does is narrow. It reads the panel’s extent, colour, border and alpha, stores the CONTROLS list unparsed, and instantiates nothing from it. Every actual screen in the game is a hand-written C++ class with its controls declared as typed members at compile time. Each of those classes asks for the controls it wants one at a time, by literal tag string, and the lookup scans the stored list for an element whose TAG matches, then hands that element to the member’s own loader.

So the file supplies values to a structure the executable already fixed:

  • Add a control with a new tag and nothing will ask for it. Nothing in the executable is waiting for that name, and nothing walks the list looking for work. Your control is read into memory, never matched, and never drawn.
  • Rename a control and the panel loses it. The screen still asks for the old name, finds nothing, and carries on without it.
  • You cannot change what kind of control something is. The kind was decided when the game was built. The file does not get a vote.
  • What you can change is real and substantial. Move and resize controls, restyle borders and fills, swap fonts, colours, text and alignment, repoint images. That is exactly what interface mods do, and it works because none of it touches the structure.

Important

No two .gui files have the same read set, so counting how often a label appears tells you nothing about whether it is used Which labels get read depends entirely on which screen opened the file, and each screen asks only for the controls it knows by name. A label sitting in a file that its screen never asks for is untouched in that file, while the same label is load-bearing in another file opened by another screen.

So the census at the end of this page describes what artists wrote, not what the engine reads. The one table you can read as “the engine uses these” is the panel-level one below, because the shared loader takes those from every .gui whatever screen it belongs to.

Field Schema

FamilyCoversRepresentative paths
Panel frameThe rectangle, fill and border the shared loader reads from every fileEXTENT, COLOR, BORDER, ALPHA
Control listThe flat list every screen looks into by tagCONTROLS, CONTROLS[]/TAG, CONTROLS[]/ID
Per-control stylingBorders, highlight and selection states, text and fontBORDER, HILIGHT, SELECTED, TEXT
Image stylingHow an image is drawn, flipped and rotatedIMAGE, ROTATE, FLIPSTYLE, DRAWSTYLE
Composite slotsNamed sub-controls a listbox or scrollbar ownsPROTOITEM, SCROLLBAR, THUMB, PROGRESS

Every label path any shipped file carries is tabulated at the end of this page. There is no schema to generate it from, so that table is a corpus census rather than a declaration.

Engine Audits & Decompilation

Read from CSWGuiPanel::StartLoadFromLayout at 0x0040a680, with the control lookup and the listbox dispatch traced separately.

(Provenance: traced, except ALIGNMENT’s bitfield split, which is marked inferred below. Corpus figures are measured over the population named above.)

Pipeline eventEngine behaviour
Panel loadReads extent, colour, border or background, and alpha, then stores the CONTROLS list without walking it.
Control lookupCSWGuiControl::Load (0x00418840) scans the stored list for an element whose TAG matches a requested string and hands it to the caller’s own loader. The requested string is a literal in the panel class.
Per-panel classesEvery screen class in the client reaches the control initialiser, each with its own hardcoded set of tags and its own pre-typed members. This is why there is no shared read set.
Listbox item templateCSWGuiListBox::LoadProtoItem (0x0041d3e0) is the sole CONTROLTYPE dispatch, with the default case creating nothing.
ScrollbarCSWGuiListBox::Load (0x0041d5b0) loads the scrollbar into an already-typed member, so no dispatch occurs on that path.
ExtentCSWGuiExtent::Load (0x00409dc0) stores four plain integers.
Image fieldsCSWGuiImage::Load (0x00416196) is where DRAWSTYLE, FLIPSTYLE, ROTATESTYLE and the ROTATE precedence live.

What the shared panel loader reads

These are read for every file, before any panel class gets involved.

LabelGFF typeBehaviour
EXTENTStructThe panel rectangle
EXTENT/LEFT, TOP, WIDTH, HEIGHTINTDefault 0 each, kept exactly as written. Plain pixel counts rather than fractions, and nothing scales them on the way in.
COLORVector3
BORDERStructFalls back to BACKGROUND when absent. No shipped file carries a BACKGROUND; see below.
ALPHAFLOAT1.0 wherever it appears, which is every file but one. Not a default; see below.
CONTROLSListKept as-is for the tag lookups that come later. Nothing is built from it here.

A small set of paths is carried by every file in the population: BORDER with its CORNER, EDGE, FILL, DIMENSION and FILLSTYLE; CONTROLS; CONTROLTYPE; EXTENT with its four members; Obj_Locked; and TAG.

Two rows above are observations rather than rules, where every other row gives a value a reader can rely on.

ALPHA has no established default. It holds 1.0 in every file that carries it, and debug in data/gui.bif is the one file that omits it. So a single shipped file exercises the case the table cannot answer, and 1.0 is what the files show rather than what an absent field resolves to.

BACKGROUND is a real label, and it is a flat resref rather than a struct. Where the panel’s BORDER sub-struct is absent, the loader reads BACKGROUND as a CResRef defaulting to the empty string and passes it straight in as the border’s fill image. Where BORDER is present it is never read at all, so this is strictly the fallback rather than a field consulted alongside a full border definition.

No shipped file takes that path. BACKGROUND appears nowhere in the census further down, which covers every .gui in the install. The branch is real and the data never reaches it, which is a different thing from a label that does not exist.

CONTROLTYPE decides nothing except in a listbox item template

After all that, the field has one job and it is a narrow one. The only place the value chooses anything is PROTOITEM, the template a listbox stamps out for each of its rows. Here the file really does pick the kind of control, because a listbox has any number of rows and the game cannot have named them all in advance.

ValueProduces
4Label
5Label with highlight
6Button
7Toggle button
8Slider

Anything else silently produces nothing. 0 through 3, and 9 upward, make no control and no complaint. The template is left as it was, so a listbox with an unrecognised PROTOITEM type comes out empty rather than broken, and nothing tells you which of the two you are looking at.

Everywhere else the value does nothing. A SCROLLBAR goes into a slot whose kind was already decided, so there is nothing for the value to choose. The files agree: 9 shows up at CONTROLS[]/SCROLLBAR/CONTROLTYPE and nowhere else.

Across the corpus the attested values are 2 at the panel root, 4 through 8, 10 and 11 in the control list, 4 through 7 on PROTOITEM, and 9 on SCROLLBAR. 0, 1 and 3 occur nowhere.

Field results

ALIGNMENT

It packs two axes into one number rather than listing combinations. Every value in the files, 9, 10, 12, 17, 18, 20 and 34, splits into exactly one horizontal bit out of {1, 2, 4} plus exactly one vertical bit out of {8, 16, 32}, and the engine has separate horizontal-only and vertical-only setters beside the combined one.

The loader passes the whole number along untouched, so (provenance: inferred) the split comes from the shape of the values and those setters. Defaults vary by control: 0x12 on images, 9 on text.

TEXT/STRREF and TEXT/TEXT

They are alternatives, and no shipped control uses both. Both labels are populated across the install, which makes it look as though a writer must know which wins. Per control rather than per file: some TEXT structs carry a live STRREF, some a non-empty TEXT string, most neither, and none carries both. The precedence question is not merely undocumented, it is unexercised.

Populate one. A localized string goes in STRREF, a literal in TEXT. Setting both puts the file outside anything the game’s own data does.

ROTATE and ROTATESTYLE

ROTATE wins outright where it is present, and ROTATESTYLE is then never read at all. Where ROTATESTYLE is read, 0, 1, 2 and 3 mean 0, 90, 180 and 270 degrees, and anything else leaves the rotation wherever ROTATE defaulted. Every shipped file holds 0, so this comes from the code rather than the data.

ROTATE is in degrees, and the pairing is what proves it. The float is stored into the image’s angle with no unit conversion anywhere on the path, and ROTATESTYLE writes the same field using the literals 0.0, 90.0, 180.0 and 270.0. Those are unambiguously degrees and nothing scales between the two paths, so the shared destination settles the unit by construction rather than by the usual assumption about angles in a file format.

FLIPSTYLE and DRAWSTYLE

FLIPSTYLE is treated as bits whatever you write in it. The loader masks it into a four-bit slot of the image’s flag word, which is true of the code rather than of the values that ship. Shipped files hold 0.

DRAWSTYLE is read and passed along whole, with nothing masking or splitting it, and is 0 in every file.

Obj_ParentID, and the three labels beside it

Obj_ParentID really does wire controls together. The shared control loader reads it as an INT defaulting to -1, and where it is anything else it looks up another control in the same panel by numeric ID and attaches the two as parent and child. The -1 is an ordinary equality sentinel, compared as signed. Most files carry it.

Important

No reader can exist for Obj_Locked, Obj_Parent or Obj_Layer Search the whole executable and you find Obj_ParentID and not one of the other three. The engine’s GFF readers take a field name as a literal string, so a label appearing nowhere in the executable can never be asked for on any path. That is the strong form set out under the standard of evidence.

Obj_Locked is in every single file, and a field that universal looks important. It is what the toolset writes every time and what the engine has no name for.

What the files look like

The census at the end sounds sprawling and is not. The shape repeats, and most of its length is the same handful of sub-structs recurring under different slots.

Controls nest by named slot, never by list. A panel holds one flat CONTROLS list and no control holds a nested one. Two of the named slots are themselves control-shaped, carrying their own CONTROLTYPE, EXTENT, BORDER and TAG: PROTOITEM and SCROLLBAR. The rest, TEXT, HILIGHT, MOVETO, PROGRESS, THUMB, and PROTOITEM’s own SELECTED and HILIGHTSELECTED, carry no CONTROLTYPE and so are never a control in their own right.

Every CONTROLS element in every file has GFF struct_id 0, so the struct id carries no type information here. Contrast GIT, where it discriminates object kinds.

Value sets small enough to be enumerations rather than ranges:

PathAttested values
FILLSTYLE0, 1, 2
BORDER/DIMENSION0, 1, 2, 4, 6, 16, 32
PULSING0, 1, 2
Obj_Locked0 or 1
TEXT/FONTdialogfont10x10, dialogfont16x16, fnt_console, fnt_d16x16

Panel-level COLOR takes (-1, -1, -1) in some files, which has the shape of a sentinel and is recorded here as a value.

One file carries an empty CONTROLS list, which is why every CONTROLS[]/... path in the census sits one below the population total or lower.

Open questions

  • Which of TEXT/STRREF and TEXT/TEXT wins when both are set. No shipped control populates both, so the precedence is unexercised by the corpus as well as untraced. On the reverse-engineering queue.
  • Whether DRAWSTYLE is an enumeration or a bitfield. It is read and passed along whole with nothing masking or splitting it, and holds 0 in every file, so neither the code nor the data distinguishes the two readings.
  • Whether EXTENT values are rescaled downstream. CSWGuiExtent::Load stores four plain integers and the stored value is a literal pixel count. What a later render stage does with them for the active resolution was not traced.
  • ALIGNMENT’s bitfield split is inferred, from the shape of the attested values and the existence of separate per-axis setters, rather than traced through the loader.

Implemented Linter Rules (Rakata-Lint)

None yet. No rule currently reads this format.


Every label path

The complete set, so a reader does not have to infer it from the examples above. Measured across every .gui in data/gui.bif and in patch.erf, which is the population named at the top of this page.

The Files column is how many of those carry the path. One that appears in all of them is structural; one that appears in a single file is that screen’s own peculiarity. Telling those apart is most of what you need before writing a reader, and it is exactly what a list of examples cannot give you.

PathTypeFiles
ALPHAFLOAT90
BORDERStruct91
BORDER/COLORVector385
BORDER/CORNERCResRef91
BORDER/DIMENSIONINT91
BORDER/EDGECResRef91
BORDER/FILLCResRef91
BORDER/FILLSTYLEINT91
BORDER/INNEROFFSETINT86
BORDER/PULSINGBYTE86
COLORVector390
CONTROLSList91
CONTROLS[]/BORDERStruct90
CONTROLS[]/BORDER/COLORVector385
CONTROLS[]/BORDER/CORNERCResRef90
CONTROLS[]/BORDER/DIMENSIONINT90
CONTROLS[]/BORDER/EDGECResRef90
CONTROLS[]/BORDER/FILLCResRef90
CONTROLS[]/BORDER/FILLSTYLEINT90
CONTROLS[]/BORDER/INNEROFFSETINT86
CONTROLS[]/BORDER/PULSINGBYTE86
CONTROLS[]/COLORVector349
CONTROLS[]/CONTROLTYPEINT90
CONTROLS[]/CURVALUEINT17
CONTROLS[]/EXTENTStruct90
CONTROLS[]/EXTENT/HEIGHTINT90
CONTROLS[]/EXTENT/LEFTINT90
CONTROLS[]/EXTENT/TOPINT90
CONTROLS[]/EXTENT/WIDTHINT90
CONTROLS[]/HILIGHTStruct72
CONTROLS[]/HILIGHT/COLORVector371
CONTROLS[]/HILIGHT/CORNERCResRef72
CONTROLS[]/HILIGHT/DIMENSIONINT72
CONTROLS[]/HILIGHT/EDGECResRef72
CONTROLS[]/HILIGHT/FILLCResRef72
CONTROLS[]/HILIGHT/FILLSTYLEINT72
CONTROLS[]/HILIGHT/INNEROFFSETINT72
CONTROLS[]/HILIGHT/PULSINGBYTE72
CONTROLS[]/HILIGHTSELECTEDStruct16
CONTROLS[]/HILIGHTSELECTED/COLORVector316
CONTROLS[]/HILIGHTSELECTED/CORNERCResRef16
CONTROLS[]/HILIGHTSELECTED/DIMENSIONINT16
CONTROLS[]/HILIGHTSELECTED/EDGECResRef16
CONTROLS[]/HILIGHTSELECTED/FILLCResRef16
CONTROLS[]/HILIGHTSELECTED/FILLSTYLEINT16
CONTROLS[]/HILIGHTSELECTED/INNEROFFSETINT16
CONTROLS[]/HILIGHTSELECTED/PULSINGBYTE16
CONTROLS[]/IDINT90
CONTROLS[]/ISSELECTEDBYTE16
CONTROLS[]/LEFTSCROLLBARBYTE49
CONTROLS[]/LOOPINGBYTE49
CONTROLS[]/MAXVALUEINT17
CONTROLS[]/MOVETOStruct70
CONTROLS[]/MOVETO/DOWNINT70
CONTROLS[]/MOVETO/LEFTINT70
CONTROLS[]/MOVETO/RIGHTINT70
CONTROLS[]/MOVETO/UPINT70
CONTROLS[]/Obj_LayerINT1
CONTROLS[]/Obj_LockedBYTE90
CONTROLS[]/Obj_ParentCExoString90
CONTROLS[]/Obj_ParentIDINT83
CONTROLS[]/PADDINGINT49
CONTROLS[]/PARENTIDINT1
CONTROLS[]/PROGRESSStruct12
CONTROLS[]/PROGRESS/COLORVector312
CONTROLS[]/PROGRESS/CORNERCResRef12
CONTROLS[]/PROGRESS/DIMENSIONINT12
CONTROLS[]/PROGRESS/EDGECResRef12
CONTROLS[]/PROGRESS/FILLCResRef12
CONTROLS[]/PROGRESS/FILLSTYLEINT12
CONTROLS[]/PROGRESS/INNEROFFSETINT12
CONTROLS[]/PROGRESS/PULSINGBYTE12
CONTROLS[]/PROTOITEMStruct49
CONTROLS[]/PROTOITEM/BORDERStruct49
CONTROLS[]/PROTOITEM/BORDER/COLORVector347
CONTROLS[]/PROTOITEM/BORDER/CORNERCResRef49
CONTROLS[]/PROTOITEM/BORDER/DIMENSIONINT49
CONTROLS[]/PROTOITEM/BORDER/EDGECResRef49
CONTROLS[]/PROTOITEM/BORDER/FILLCResRef49
CONTROLS[]/PROTOITEM/BORDER/FILLSTYLEINT49
CONTROLS[]/PROTOITEM/BORDER/INNEROFFSETINT47
CONTROLS[]/PROTOITEM/BORDER/PULSINGBYTE47
CONTROLS[]/PROTOITEM/CONTROLTYPEINT49
CONTROLS[]/PROTOITEM/EXTENTStruct49
CONTROLS[]/PROTOITEM/EXTENT/HEIGHTINT49
CONTROLS[]/PROTOITEM/EXTENT/LEFTINT49
CONTROLS[]/PROTOITEM/EXTENT/TOPINT49
CONTROLS[]/PROTOITEM/EXTENT/WIDTHINT49
CONTROLS[]/PROTOITEM/HILIGHTStruct33
CONTROLS[]/PROTOITEM/HILIGHT/COLORVector332
CONTROLS[]/PROTOITEM/HILIGHT/CORNERCResRef33
CONTROLS[]/PROTOITEM/HILIGHT/DIMENSIONINT33
CONTROLS[]/PROTOITEM/HILIGHT/EDGECResRef33
CONTROLS[]/PROTOITEM/HILIGHT/FILLCResRef33
CONTROLS[]/PROTOITEM/HILIGHT/FILLSTYLEINT33
CONTROLS[]/PROTOITEM/HILIGHT/INNEROFFSETINT32
CONTROLS[]/PROTOITEM/HILIGHT/PULSINGBYTE32
CONTROLS[]/PROTOITEM/HILIGHTSELECTEDStruct6
CONTROLS[]/PROTOITEM/HILIGHTSELECTED/COLORVector36
CONTROLS[]/PROTOITEM/HILIGHTSELECTED/CORNERCResRef6
CONTROLS[]/PROTOITEM/HILIGHTSELECTED/DIMENSIONINT6
CONTROLS[]/PROTOITEM/HILIGHTSELECTED/EDGECResRef6
CONTROLS[]/PROTOITEM/HILIGHTSELECTED/FILLCResRef6
CONTROLS[]/PROTOITEM/HILIGHTSELECTED/FILLSTYLEINT6
CONTROLS[]/PROTOITEM/HILIGHTSELECTED/INNEROFFSETINT6
CONTROLS[]/PROTOITEM/HILIGHTSELECTED/PULSINGBYTE6
CONTROLS[]/PROTOITEM/ISSELECTEDBYTE6
CONTROLS[]/PROTOITEM/Obj_ParentCExoString49
CONTROLS[]/PROTOITEM/Obj_ParentIDINT47
CONTROLS[]/PROTOITEM/SELECTEDStruct6
CONTROLS[]/PROTOITEM/SELECTED/COLORVector36
CONTROLS[]/PROTOITEM/SELECTED/CORNERCResRef6
CONTROLS[]/PROTOITEM/SELECTED/DIMENSIONINT6
CONTROLS[]/PROTOITEM/SELECTED/EDGECResRef6
CONTROLS[]/PROTOITEM/SELECTED/FILLCResRef6
CONTROLS[]/PROTOITEM/SELECTED/FILLSTYLEINT6
CONTROLS[]/PROTOITEM/SELECTED/INNEROFFSETINT6
CONTROLS[]/PROTOITEM/SELECTED/PULSINGBYTE6
CONTROLS[]/PROTOITEM/TAGCExoString49
CONTROLS[]/PROTOITEM/TEXTStruct49
CONTROLS[]/PROTOITEM/TEXT/ALIGNMENTINT49
CONTROLS[]/PROTOITEM/TEXT/COLORVector349
CONTROLS[]/PROTOITEM/TEXT/FONTCResRef49
CONTROLS[]/PROTOITEM/TEXT/PULSINGBYTE47
CONTROLS[]/PROTOITEM/TEXT/STRREFDWORD49
CONTROLS[]/PROTOITEM/TEXT/TEXTCExoString49
CONTROLS[]/SCROLLBARStruct49
CONTROLS[]/SCROLLBAR/BORDERStruct49
CONTROLS[]/SCROLLBAR/BORDER/COLORVector347
CONTROLS[]/SCROLLBAR/BORDER/CORNERCResRef49
CONTROLS[]/SCROLLBAR/BORDER/DIMENSIONINT49
CONTROLS[]/SCROLLBAR/BORDER/EDGECResRef49
CONTROLS[]/SCROLLBAR/BORDER/FILLCResRef49
CONTROLS[]/SCROLLBAR/BORDER/FILLSTYLEINT49
CONTROLS[]/SCROLLBAR/BORDER/INNEROFFSETINT47
CONTROLS[]/SCROLLBAR/BORDER/PULSINGBYTE47
CONTROLS[]/SCROLLBAR/CONTROLTYPEINT49
CONTROLS[]/SCROLLBAR/CURVALUEINT49
CONTROLS[]/SCROLLBAR/DIRStruct49
CONTROLS[]/SCROLLBAR/DIR/ALIGNMENTINT49
CONTROLS[]/SCROLLBAR/DIR/DRAWSTYLEINT49
CONTROLS[]/SCROLLBAR/DIR/FLIPSTYLEINT49
CONTROLS[]/SCROLLBAR/DIR/IMAGECResRef49
CONTROLS[]/SCROLLBAR/DIR/ROTATEFLOAT48
CONTROLS[]/SCROLLBAR/DIR/ROTATESTYLEINT1
CONTROLS[]/SCROLLBAR/DRAWMODEBYTE48
CONTROLS[]/SCROLLBAR/EXTENTStruct49
CONTROLS[]/SCROLLBAR/EXTENT/HEIGHTINT49
CONTROLS[]/SCROLLBAR/EXTENT/LEFTINT49
CONTROLS[]/SCROLLBAR/EXTENT/TOPINT49
CONTROLS[]/SCROLLBAR/EXTENT/WIDTHINT49
CONTROLS[]/SCROLLBAR/MAXVALUEINT49
CONTROLS[]/SCROLLBAR/Obj_ParentCExoString49
CONTROLS[]/SCROLLBAR/Obj_ParentIDINT47
CONTROLS[]/SCROLLBAR/TAGCExoString49
CONTROLS[]/SCROLLBAR/THUMBStruct49
CONTROLS[]/SCROLLBAR/THUMB/ALIGNMENTINT49
CONTROLS[]/SCROLLBAR/THUMB/DRAWSTYLEINT49
CONTROLS[]/SCROLLBAR/THUMB/FLIPSTYLEINT49
CONTROLS[]/SCROLLBAR/THUMB/IMAGECResRef49
CONTROLS[]/SCROLLBAR/THUMB/ROTATEFLOAT48
CONTROLS[]/SCROLLBAR/THUMB/ROTATESTYLEINT1
CONTROLS[]/SCROLLBAR/VISIBLEVALUEINT49
CONTROLS[]/SELECTEDStruct16
CONTROLS[]/SELECTED/COLORVector316
CONTROLS[]/SELECTED/CORNERCResRef16
CONTROLS[]/SELECTED/DIMENSIONINT16
CONTROLS[]/SELECTED/EDGECResRef16
CONTROLS[]/SELECTED/FILLCResRef16
CONTROLS[]/SELECTED/FILLSTYLEINT16
CONTROLS[]/SELECTED/INNEROFFSETINT16
CONTROLS[]/SELECTED/PULSINGBYTE16
CONTROLS[]/STARTFROMLEFTBYTE12
CONTROLS[]/TAGCExoString90
CONTROLS[]/TEXTStruct89
CONTROLS[]/TEXT/ALIGNMENTINT89
CONTROLS[]/TEXT/COLORVector388
CONTROLS[]/TEXT/FONTCResRef89
CONTROLS[]/TEXT/PULSINGBYTE86
CONTROLS[]/TEXT/STRREFDWORD89
CONTROLS[]/TEXT/TEXTCExoString64
CONTROLS[]/THUMBStruct5
CONTROLS[]/THUMB/ALIGNMENTINT5
CONTROLS[]/THUMB/DRAWSTYLEINT5
CONTROLS[]/THUMB/FLIPSTYLEINT5
CONTROLS[]/THUMB/IMAGECResRef5
CONTROLS[]/THUMB/ROTATEFLOAT5
CONTROLTYPEINT91
EXTENTStruct91
EXTENT/HEIGHTINT91
EXTENT/LEFTINT91
EXTENT/TOPINT91
EXTENT/WIDTHINT91
Obj_LayerINT1
Obj_LockedBYTE91
Obj_ParentIDINT83
TAGCExoString91