# VPW Studio – Appendix C: Common Data Format Details

Return to Manual

## Introduction

This appendix contains detailed information about the non-program specific formats used in VPW Studio and described in the main portion of the manual.

## Table of Contents

### General Formats

These formats are shared by multiple games in the series.

1. AkiAnimation
2. AkiArchive
3. AkiModel
4. AkiText
5. AkiTexture (a.k.a. "TEX" file)

### Nintendo 64-specific

These formats specifically target Nintendo 64 hardware. All formats in this section are big endian, unless otherwise stated.

6. Ci4Palette
7. Ci8Palette
8. Ci4Texture
9. Ci8Texture
10. I4Texture

### PlayStation 1-specific

These formats specifically target PlayStation 1 hardware. All formats in this section are little endian, unless otherwise stated.

11. TIM
12. CLUT

TMD, being a highly complex format, is outside the scope of this document.

### Game-specific Formats

WCW/nWo Revenge

1. DoubleTex

WWF No Mercy

1. MenuItems_NoGroup
2. MenuItems_Shop
3. MenuItems_Costume

## AkiAnimation

AkiAnimation defines animation frames, and is used in all six of AKI's Nintendo 64 wrestling games. It is a relatively complex format to explain.

### Header Data

The animation header data is often called "Toki 2" in the hacking community. Tokidoim originally called it "Animation stats mods 2".

- Offset 0x00: Ending animation type and facing direction (2 bytes)
- Offset 0x02: Number of frames in the animation (2 bytes)

The VPW Studio source code mentions "divide by 2 and add 1 to get actual number of frames".

### Animation Frame Components

Each frame of animation consists of multiple components. These components are represented using one of three possible data types:

- Pivot/Rotation
- Overall Movement XYZ
- Movement XYZ

#### Pivot/Rotation

The Pivot/Rotation values are four bytes long, but read in a non-standard manner. Pivot/Rotation data consists of three components:

- Pivot X (12 bits)
- Rotation (8 bits)
- Pivot Z (12 bits)

To understand the data format, start by thinking of the values as four bytes, as they exist in the animation data:

    00 00 00 00
    |__||_||__|
     |   |   |
     |   |   +--- Pivot Z
     |   +------- Rotation
     +----------- Pivot X

Next, re-arrange the values to account for the number of bits used by each component, to make it easier on your eyes:

    000 00 000
    |_| || |_|
     |  ||  |
     |  ||  +--- Pivot Z
     |  ++------ Rotation
     +---------- Pivot X

This data layout is mentioned in the VPW Studio source code as "3/2/3", which represents the number of nibbles (groups of 4 bits) each value has.

#### Overall Movement XYZ

The Overall Movement XYZ values are four bytes long. They possibly define a shared displacement for all body parts. Like the Pivot/Rotation data, they are stored in "3/2/3" format, and consist of three components:

- Overall X (12 bits)
- Overall Y (8 bits)
- Overall Z (12 bits)

As they would appear in the animation data:

    00 00 00 00
    |__||_||__|
     |   |   |
     |   |   +--- Overall Z
     |   +------- Overall Y
     +----------- Overall X

And split out based on the number of bits used:

    000 00 000
    |_| || |_|
     |  ||  |
     |  ||  +--- Overall Z
     |  ++------ Overall Y
     +---------- Overall X

#### Movement XYZ

The Movement XYZ values are three bytes long, and mercifully, map out that way:

- Offset 0: X
- Offset 1: Y
- Offset 2: Z

### Animation Frame Data

The actual animation frame data follows the header, in this order:

Name | Value Type
--- | ---
Pelvis | Pivot/Rotation
Overall Movement | Overall Movement XYZ
Lower Abs | Pivot/Rotation
Lower Abs Movement | Movement XYZ
Upper Body | Pivot/Rotation
Upper Body Movement | Movement XYZ
Neck | Pivot/Rotation
Head | Pivot/Rotation
Lower Left Leg | Pivot/Rotation
Upper Left Leg | Pivot/Rotation
Left Leg Movement | Movement XYZ
Left Foot | Pivot/Rotation
Left Hand | Pivot/Rotation
Left Fingers | Pivot/Rotation
Lower Left Arm | Pivot/Rotation
Upper Left Arm | Pivot/Rotation
Left Arm Movement | Movement XYZ
Lower Right Leg | Pivot/Rotation
Upper Right Leg | Pivot/Rotation
Right Leg Movement | Movement XYZ
Right Foot | Pivot/Rotation
Lower Right Arm | Pivot/Rotation
Right Hand | Pivot/Rotation
Right Fingers | Pivot/Rotation
Upper Right Arm | Pivot/Rotation
Right Arm Movement | Movement XYZ

## AkiArchive

AkiArchive packs multiple files into a single file. It is up to the game to determine how the contents are handled, meaning it's not easy to figure out what each entry is meant to be.

### Data Format

- Offset 0x00: Number of files (4 bytes)
- Offset 0x04: List of offsets into this file for file data (4 bytes * number of files)
- File data follows the offset list.

## AkiModel

AkiModel stores mesh data. The format is largely the same between the six AKI N64 wrestling games, though some implementation details may differ.

### Header Data

- Offset 0x00: Scale (1 byte)
- Offset 0x01: Number of Vertices (1 byte)
- Offset 0x02: Number of Faces (1 byte)
- Offset 0x03: Vertex Influence (1 byte)
- Offset 0x04: Offset X (1 byte)
- Offset 0x05: Offset Y (1 byte)
- Offset 0x06: Offset Z (1 byte)
- Offset 0x07: Texture Size (1 byte)

#### Number of Vertices

The topmost bit of this value has meaning, so the actual maximum amount of vertices you can have in a single AkiModel is 127.

#### Number of Faces

The topmost bit of this value also has meaning, so the actual maximum amount of faces you can have in a single AkiModel is 127.

### Vertex Data

Vertex Data immediately follows the header.

- Offset 0x00: X position (1 byte)
- Offset 0x01: Y position (1 byte)
- Offset 0x02: Z position (1 byte)
- Offset 0x03: Texture U value (1 byte)
- Offset 0x04: Texture V value (1 byte)
- Offset 0x05: Vertex Color Red value OR Normal Vector X value (1 byte)
- Offset 0x06: Vertex Color Green value OR Normal Vector Y value (1 byte)
- Offset 0x07: Vertex Color Blue value OR Normal Vector Z value (1 byte)

Whether or not the last three values represent Vertex Colors or Normal Vectors is dependent on the top bit in either Number of Vertices or Number of Faces... probably.

### Face Data

After the Vertex Data comes a list of vertices that make up the polygon faces. Each face consists of three bytes, representing vertex indices.

## AkiText

AkiText is an archive of strings with a table at the beginning, pointing to the location of the strings in the file. It is only used in the last three AKI N64 wrestling games (WWF WrestleMania 2000, Virtual Pro-Wrestling 2, and WWF No Mercy.)

The location table starts at the very first byte (offset 0x00). Values are two bytes, big-endian, and represent the offset in the file where the relevant string is located.

String encoding depends on the game. WWF WrestleMania 2000 and WWF No Mercy use (mostly) ASCII. Virtual Pro-Wrestling 2 uses mostly Shift-JIS.

Strings in AkiText files typically end with a null/0x00 byte, but if a string is at the end of the file, it may not have a terminating byte.

## AkiTexture

AkiTexture is a wrapper around CI4/CI8 texture and palette data. It is typically used for user interface graphics in the menus.

### Header Format

- Offset 0x00: Magic number (4 bytes): "TEX",`0x00` (0x54, 0x45, 0x58, 0x00)
- Offset 0x04: Width (2 bytes)
- Offset 0x06: Height (2 bytes)
- Offset 0x08: Image Format (1 byte)
- Offset 0x09: Color Width (1 byte)
- Offset 0x0A: Number of colors in palette (2 bytes)
- Offsets 0x0C to 0x0F appear to be unused, or inserted for padding purposes. Typically set to `0x00`.

#### Image Format

Image Format has only two known values:

- `0x04` – CI4
- `0x08` – CI8

#### Color Width

Number of bytes per color. (Description might not be accurate, but it seems to work for existing files. Perhaps 32bpp color modes were planned to be supported, but this is not confirmed, since only two known Image Format values are known.)

### Palette Data

Palette Data starts at offset 0x10. Colors are the same format mentioned in the Ci4Palette section.

### Image Data

Image Data directly follows the Palette Data. In CI4 mode, one byte is equal to two pixels. In CI8 mode, one byte is one pixel. This is the same as the relevant CI4/CI8Texture format(s).

## Ci4Palette

Nintendo 64-specific format for defining a 16-color palette. These files only contain palette data, no headers or anything else.

### Color Format

Each palette entry consists of two bytes, stored in big endian format.

    byte #1   byte #2
    FEDCBA98 76543210
    |___||____||___||
      |     |    |  +-- Alpha (0 or 1)
      |     |    +----- Blue (0-31)
      |     +---------- Green (0-31)
      +---------------- Red (0-31

The developers sometimes stored multiple sets of 16-color palettes in a single Ci4Palette file, so some extracted palettes may have more than 16 colors.

## Ci8Palette

Similar to Ci4Palette, but with 256 color entries instead of 16. Color format is the same as Ci4Palette.

## Ci4Texture

Nintendo 64-specific format for defining a 16-color texture. Paired with a Ci4Palette to show desired colors.

### Header Format

- Offset 0x00: Width (1 byte)
- Offset 0x01: Height (1 byte)
- Offset 0x02: Number of Palette Entries (2 bytes)
- Offset 0x04: Horizontal Mirroring Flag (1 byte)
- Offset 0x05: Vertical Mirroring Flag (1 byte)
- Offset 0x06: Width Bit Length (1 byte)
- Offset 0x07: Height Bit Length (1 byte)

### Image Data

Image Data uses one byte for two pixels. Values represent the palette entry, and range from `0x0` to `0xF`.

    76543210
    |__||__|
      |  |
      |  +---- Second palette entry
      +------- First palette entry

## Ci8Texture

Nintendo 64-specific format for defining a 256-color texture. Paired with a Ci8Palette to show desired colors.

This format is largely similar to Ci4Texture, but image data uses one byte per pixel, since there are 256 possible colors instead of 16.

## I4Texture

Nintendo 64-specific format for defining a 16-step "intensity" texture.

Unlike the CI texture formats, I*Texture does not use a header. It is up to the game to use the correct width and height values when loading the texture.

Other intensity formats exist (I8, IA4, IA8), but it's unsure if any of them are used in AKI's N64 games.

## TIM

PlayStation 1-specific texture format. Often paired with a CLUT, either externally or internally.

A single file may contain multiple TIM files, and this is often the case in AKI's wrestling games on PlayStation 1.

### Header Format

- Offset 0x00: TIM identifier (value `0x10`)
- Offset 0x01: TIM version number (value `0x00`)
- Offsets 0x02,0x03: always `0x00`
- Offset 0x04: Image Flags (4 bytes)

If the image has an internal CLUT, it starts at offset 0x08. Data then continues as follows:

- Pixel Data Length (4 bytes) – Number of bytes to describe the pixel data, including the 4 bytes for this variable.
- Pixel X Coordinate (2 bytes) – X coordinate for pixel data in the framebuffer.
- Pixel Y Coordinate (2 bytes) – Y coordinate for pixel data in the framebuffer.
- Pixel Width (2 bytes) – Width of the pixel data (in 16 bit/2 byte units).
- Pixel Height (2 bytes) – Height of the pixel data.

The actual pixels follow the header data. See the "Image Formats" section below for more information.

### Image Flags

Only the four least significant bits are used:

    3210
    ||_|
    | |
    | +-- Image Format
    +---- Has internal CLUT

#### Image Formats

The "Image Format" section accepts the following values ("one uint16 value" is two bytes):

- `0` – 4bpp CLUT/paletted (one uint16 value = 4 pixels)
- `1` – 8bpp CLUT/paletted (one uint16 value = 2 pixels)
- `2` – 15bpp direct color (one uint16 value = 1 pixel)
- `3` – 24bpp direct color (one uint16 value = 2/3rds of a pixel; three uint16 values = 2 pixels)
- `4` – "Mixed" (not supported by VPW Studio)

Values 5-7 are presumed unused, or are at least assumed to be unused by AKI's PS1 games.

## CLUT

CLUT is short for "Color Look-Up Table", but it's really just a fancy term for a palette.

Note: This only describes CLUT data as found in TIM files. Standalone CLUT files exist, but have a slightly different format.

### Header Format

- Offset 0x00: Data Length (4 bytes) – Total length of the CLUT data, including the 4 bytes for this variable, as well as the other values below.
- Offset 0x04: VRAM X Coordinate (2 bytes) – X coordinate for CLUT data in the framebuffer.
- Offset 0x06: VRAM Y Coordinate (2 bytes) – Y coordinate for CLUT data in the framebuffer.
- Offset 0x08: Data Width (2 bytes) – Width of the CLUT data in the framebuffer.
- Offset 0x0A: Data Height (2 bytes) – Height of the CLUT data in the framebuffer.

### Color Format

Actual color data follows the header, with each color entry in the following format:

    FEDCBA9876543210
    ||___||___||___|
    |  |    |    |
    |  |    |    +--- Red
    |  |    +-------- Green
    |  +------------- Blue
    +---------------- (Semi-)Transparent

Alpha/transparency calculation is slightly more complicated than just checking the relevant bit. If the Red, Green, and Blue values are 0 and (Semi-)transparency is also 0, it's fully transparent. However, if any of the RGB values are non-zero, the color is only semi-transparent.

## DoubleTex (WCW/nWo Revenge)

DoubleTex contains two AkiTexture images in one file. Both images are 64x64 pixels. They are only used for the credits sequence.