Skip to content

User interface

Allofich edited this page May 17, 2024 · 9 revisions

Character paperdoll

Armor class positions are stored in two 14-items WORD arrays in X, Y order.

  • Male positions are @45119
  • Female positions are @45135

Color translation

To draw the helmet for a particular race, its colors are translated to match that race's skin color.

The list of 30 palette indices to translate is stored @3B9E0. The new value arrays are:

  • Redguards @3BA0E
  • Dark elves @3BA2C
  • High elves @3BA4A

For Argonians, the xLIZn.IMG is drawn over the helmet instead. x is ether M or F, and n corresponds to the armor type (0 for plate, etc.)

Listboxes

    Background  Struct    Description
1   POPUP3      4449C     Buying weapons
2   POPUP4      4449C     Buying armor
3   POPUP       443F2     Spellmaker menus
4   POPUP5      443F2     ?
5   LOADSAVE    443F2     ?
6   POPUP2      44546     Class selection
7   POPUP7      4449C     Buying magic items
8   POPUP8      443F2     Travel city selection
9   POPUP11     444F1     Dialogue
10  NEWPOP      44447     Room selection, cures
11  NEWPOP      443F2     Loot, selling, repair, etc.

Overlays

The portraits are located at the points stored in a WORD array @46F30 in X, Y format.

The keys are drawn vertically from (8,16) with 10 px increment.

Pixelation effect

A pixelation effect can be used as a transition between two screens.

unsigned short PixelationValue = @43F84; // Default value is 0x1235

unsigned short PickPixel() {
    unsigned short result = (unsigned short)(PixelationValue * 1509) + 41;
    PixelationValue = result;
    return result;
}

void PixelationEffect(short HorizontalPixels, short VerticalPixels, short startRow, short startColumn) {
  unsigned short loopCount;
  unsigned short nextPixel;
  unsigned short pixel;
  unsigned short row;
  unsigned short column;

if ((GameOptions & 2) == 0) { // If pixelation is enabled
    unsigned short totalPixels = HorizontalPixels * VerticalPixels;
    loopCount = 64000; // One iteration for every pixel of the 320x200 display
    nextPixel = (320 * startRow) + startColumn;
    do {
      pixel = PickPixel() % totalPixels;
      column = pixel % HorizontalPixels;
      row = pixel / HorizontalPixels;
      nextPixel += (row * 320) + column;
      CurrentScreen[nextPixel] = NewScreen[nextPixel];
      if ((loopCount & 0x3ff) == 0) { // Every 1024 iterations
        SyncWithVerticalRetrace();
      }
      loopCount --;
    } while (loopCount != 0);
  }
  return;
}

The game uses an array @49A3A of pixel offsets for the start of each row, but as the values are equivalent to row * 320, that is what is used in the above pseudocode for simplicity.

This function is always called with the arguments (320, 200, 0, 0) in the original game, except for one call (unknown if it is used) of (320, 80, 119, 0). For these calls that use 320 for HorizontalPixels the calculations involving row and column are redundant and one could just use nextPixel += pixel.

By default pixelation is enabled. It can be toggled on or off in-game with the F4 key. In addition to being used for displaying message boxes it is also used for drawing images in the introduction, where it is always enabled because starting a new game resets the toggle.

Clone this wiki locally