Difference between revisions of "Riven resources"

From A look inside The Link @ wiki
Jump to: navigation, search
m (TOC)
(this page just borrows the other pages and puts them together into a single page)
Line 1: Line 1:
 
{{Riven}}
 
{{Riven}}
This page lists resource types used by the Riven engine.
+
This document talks about Riven resources controlling the game path and world; actually, it tries to document every resource other than [[Riven SFXE resources|SFXE]], [[Riven tBMP resources|tBMP]], [[Riven tWAV resources|tWAV]] and [[Riven tMOV resources|tMOV]].
  
Resources used in Riven data files:
+
==Notes on stack switching==
* [[Riven BLST resources|BLST]]
+
The current stack can be changed from scripts using a special script command (27). For example, when the player activates a MagLev first the car movie is played, and then command 27 is called to change the current stack to the new island. This command is also used in the "Play Riven" button. However, most linking books actually change stack simply by moving to another card which has no buttons and no scripts. Apparently, there is some hardcoded mechanism inside the engine which triggers the stack change when one of these "special" cards is entered. These cards are listed here.
* [[Riven CARD resources|CARD]]
+
{| border=1 cellpadding=4 cellspacing=0 style="border:1px #000 solid;border-collapse:collapse;"
* [[Riven FLST resources|FLST]]
+
|- style="background:#CCC"
* [[Riven HSPT resources|HSPT]]
+
! Stack !! Card ID !! Target stack !! Target card
* [[Riven MLST resources|MLST]]
+
|-
* [[Riven NAME resources|NAME]]
+
|bspit||447||ospit||1
* [[Riven PLST resources|PLST]]
+
|-
* [[Riven RMAP resources|RMAP]]
+
|gspit||178||ospit||1
* [[Riven SFXE resources|SFXE]]
+
|-
* [[Riven SLST resources|SLST]]
+
|jspit||228||rspit||3
* [[Riven tBMP resources|tBMP]]
+
|-
* [[Riven tMOV resources|tMOV]]
+
|jspit||344||ospit||1
* [[Riven tWAV resources|tWAV]]
+
|-
 +
|ospit||58||pspit||43
 +
|-
 +
|ospit||62||jspit||341
 +
|-
 +
|ospit||67||gspit||175
 +
|-
 +
|ospit||72||bspit||444
 +
|-
 +
|ospit||76||tspit||387
 +
|-
 +
|pspit||46||ospit||1
 +
|-
 +
|rspit||13||jspit||215
 +
|-
 +
|tspit||392||ospit||1
 +
|}
  
Resources used in Riven saved games:
+
==BLST, FLST, MLST, PLST, SLST==
* [[Riven VARS resources|VARS]]
+
These resources are lists and begin with an unsigned short telling the number of records. Then the records follow, and their structure depends on the resource type. There is one of these resources for each card; their ID matches the corresponding CARD resource ID.
* [[Riven VERS resources|VERS]]
+
 
* [[Riven ZIPS resources|ZIPS]]
+
===[[Riven BLST resources|BLST]]===
 +
{{:Riven BLST resources}}
 +
===[[Riven FLST resources|FLST]]===
 +
{{:Riven FLST resources}}
 +
===[[Riven MLST resources|MLST]]===
 +
{{:Riven MLST resources}}
 +
===[[Riven PLST resources|PLST]]===
 +
{{:Riven PLST resources}}
 +
===[[Riven SLST resources|SLST]]===
 +
{{:Riven SLST resources}}
 +
==[[Riven HSPT resources|HSPT]]==
 +
{{:Riven HSPT resources}}
 +
==[[Riven CARD resources|CARD]]==
 +
{{:Riven CARD resources}}
 +
==[[Riven NAME resources|NAME]]==
 +
{{:Riven NAME resources}}
 +
==[[Riven RMAP resources|RMAP]]==
 +
{{:Riven RMAP resources}}
 +
==[[Riven VARS resources|VARS]]==
 +
{{:Riven VARS resources}}
 +
==[[Riven VERS resources|VERS]]==
 +
{{:Riven VERS resources}}
 +
==[[Riven ZIPS resources|ZIPS]]==
 +
{{:Riven ZIPS resources}}

Revision as of 04:35, 6 February 2008

Riven
Mohawk Overview
BLST CARD FLST HSPT
MLST NAME PLST RMAP
SFXE SLST tBMP tMOV
tWAV VARS VERS ZIPS
Scripts Variables
External commands

This document talks about Riven resources controlling the game path and world; actually, it tries to document every resource other than SFXE, tBMP, tWAV and tMOV.

Notes on stack switching

The current stack can be changed from scripts using a special script command (27). For example, when the player activates a MagLev first the car movie is played, and then command 27 is called to change the current stack to the new island. This command is also used in the "Play Riven" button. However, most linking books actually change stack simply by moving to another card which has no buttons and no scripts. Apparently, there is some hardcoded mechanism inside the engine which triggers the stack change when one of these "special" cards is entered. These cards are listed here.

Stack Card ID Target stack Target card
bspit 447 ospit 1
gspit 178 ospit 1
jspit 228 rspit 3
jspit 344 ospit 1
ospit 58 pspit 43
ospit 62 jspit 341
ospit 67 gspit 175
ospit 72 bspit 444
ospit 76 tspit 387
pspit 46 ospit 1
rspit 13 jspit 215
tspit 392 ospit 1

BLST, FLST, MLST, PLST, SLST

These resources are lists and begin with an unsigned short telling the number of records. Then the records follow, and their structure depends on the resource type. There is one of these resources for each card; their ID matches the corresponding CARD resource ID.

BLST

They control which hotspots should be enabled and which disabled within the card.

Each BLST resource is a list of records; it starts with an unsigned short record count, followed by that many records. The record size is 6 bytes and follows this structure:

unsigned short index Record index, starting from 1
unsigned short enabled Hotspot state, 0 or 1
unsigned short hotspot_id Matches the blst_id field of the corresponding hotspot record

BLST records must be "activated" from scripts, with command 43. Note that hotspots may exist without an associated BLST record. In that case, unless they are marked as Zip Mode hotspots and Zip Mode is off, they should just be enabled when entering the card.

FLST

They seem to specify which SFXE resource each card must use.

Each FLST resource is a list of records; it starts with an unsigned short record count, followed by that many records. The record size is 6 bytes:

unsigned short index Record index, starting from 1
unsigned short sfxe_id Resource ID of the corresponding SFXE
unsigned short u0

u0 is always zero. Changing it seems to have no effect.

FLST resources are very often empty (meaning no SFXE for that card) or with just one record.

MLST

Movie lists: they specify the movies to be used in the card and their placement.

Each MLST resource is a list of records; it starts with an unsigned short record count, followed by that many records. This is the record structure:

unsigned short index index of the record (starting at 1)
unsigned short movie_id Resource ID of the corresponding tMOV movie
unsigned short code Used by script commands to reference the movie record
unsigned short left Movie position within the game window (pixels)
unsigned short top
unsigned short u0[3]
unsigned short loop 0 or 1, 1 means the movie must loop forever
unsigned short volume Volume of the movie sound track (details still unknown)
unsigned short u1

As for unknown fields: u0 seems always 0000 0000 ffff and u1 seems always 1. Changing them produces no observable effects.

PLST

PLSTs are bitmap lists: they tell which bitmap to draw and where to draw it within the card.

Each PLST resource is a list of records; it starts with an unsigned short record count, followed by that many records. The record structure is:

unsigned short index Record index, starting from 1
unsigned short bitmap_id Resource ID of the corresponding tBMP bitmap
unsigned short left Rectangle to draw the bitmap into, in pixels
unsigned short top
unsigned short right
unsigned short bottom

Like in BLSTs, the records must be "activated" from a script, using command 39. The first record is automatically enabled when entering the card, though: some cards have no PLST activation commands at all.

SLST

They contain ambient sound info for the card. Ambient sounds are arbitrary mixes of a number of sounds (for example wind + steam flowing in a pipe). Sounds are read from tWAV resources stored in the associated *_sounds.mhk archive (not in the same archive storing the SLST resource). For example, a SLST resource in a_Data will point to tWAV sounds stored in a_Sounds, not a_Data.

Each SLST resource is a list of records; it starts with an unsigned short record count, followed by that many records. The record structure is:

unsigned short index Record index, starting from 1
unsigned short sound_count How many sounds to mix
unsigned short sound_ids[sound_count] tWAV resource IDs of the sounds to use
unsigned short fade_flags
unsigned short loop If set to 1, the mix loops forever
unsigned short global_volume Volume of the resulting sound mix
unsigned short u0
unsigned short u1
unsigned short volumes[sound_count] Volume for each sound component
unsigned short balances[sound_count] Balance for each sound component (<0 left, 0 center, >0 right)
unsigned short u2[sound_count]

fade_flags is a bit field controlling how to fade the sound channels when the record is activated. Bit 0 controls the fading out of any previous playing sound, bit 1 controls the fading in of the sound specified by the new record. For example, 3 would cause both sounds to fade, while 0 would suddenly stop the previous sound and immediately start the new one.

Volume ranges are not known exactly, values as high as 355 have been observed. Riven apparently keeps "scale factors" for sound volumes in its Riven.ini file (VolumeDivisorWin and VolumeDivisorMac).

u0 is usually 0 or 1, and changing it seems to do nothing. u1 is 0; giving it a non-zero value prevents sounds from playing. u2[] seems always 255 or 256 (for every sound component) and changing it seems to do nothing.

The first record is automatically enabled when entering the card, so it doesn't need to be activated from scripts.

Riven sound logic

This is an explanation of the Riven sound logic as it is currently understood.

Riven seems to maintain a set of playing sounds. Each sound has attributes, such as volume, panning, and fade flags. When an SLST record is activated, the set of playing sounds is updated with the set of sounds specified by the SLST record.

  • Any sound present in the currently playing set and the SLST record set keep on playing, but their volume and pan attributes are updated.
  • Any sound not present in the currently playing set but present in the SLST record gets added to the set of currently playing sounds. Appropriate fade-in is applied if specified by the sound flags.
  • Any sound present in the currently playing set but not present in the SLST record gets removed from the set of currently playing sounds. Appropriate fade-out is applied if specified by the sound flags.

In-data-archive sounds ("instant sounds", or "foreground sounds") are kept in a separate set, since they never loop. They should not block script execution.

HSPT

These contain hotspots, sort of invisible buttons within cards that respond to mouse clicks (and other events) by performing actions described by attached scripts.

Each HSPT resource is a list of records and starts with an unsigned short equal to the number of records. Due to the attached scripts, HSPT records can have different size and there is no way to know it without fully decoding the record. Each record has the following structure:

unsigned short blst_id Links the hotspot to a BLST resource record
short name_rec If ≥ 0, record index in NAME resource 2 to provide a name for the hotspot
short left Hotspot rectangle within the game window, in pixels
short top
short right
short bottom
unsigned short u0
unsigned short mouse_cursor Cursor icon to set when the mouse rolls over this hotspot
unsigned short index Record index starting from 1
short u1
unsigned short u2
variable size script
Error creating thumbnail: Unable to save thumbnail to destination
Riven cursor icons and their IDs

Hotspot rectangles can fall outside the game window (in any direction) and often two or more hotspots overlap. There are even cases with left > right (card 371, t_Data). When more hotspots overlap, the hotspot "on top" is the one with the largest index value.

Cursor icon values are listed on the right.

u0 seems always zero and changing it seems to leave Riven indifferent. u1 is very very often -1 but not always. u2 is 0 for ordinary hotspots, 1 for Zip Mode ones: the engine disables all Zip Mode hotspots when Zip Mode is off.

For info on the attached script see the scripts section.

CARD

CARD resources describe general properties of cards and associate a command script to each card. There is one CARD resource for each card, and its ID matches the card ID.

short name_rec If ≥ 0, record index in NAME resource 1 to provide a name for the card
unsigned short zip_mode_place
variable size script

zip_mode_place is usually 0; it's 1 when the card name is one of the special names used in ZIPS records. I think that if zip_mode_place = 1 then Riven stores the card name and ID in a new ZIPS record when the card is accessed, so that the place will be accessible using Zip Mode later.

For info on the attached script see the scripts section.

NAME

They contain a list of strings with an associated value, and their purpose is to store names for variables, cards, hotspots and other entities. They have the following structure:

unsigned short field_count
unsigned short string_offsets[field_count]
unsigned short values[field_count]
char* strings

strings is a list of zero-terminated strings. You can access string n by looking at string_offsets[n], which is the offset starting from strings (not from the beginning of resource data). The meaning of values[] is not yet known, but it seem to go from 0 to field_count-1 (not in sequential order). This field apparently has no function (the record index is important, instead).

In saved games there's only one NAME resource; it stores the name of each variable in the VARS (the record index in the NAME matches the one in the VARS).

In data files there are more NAMEs:

  • ID 1 stores card names.
  • ID 2 stores hotspot names.
  • ID 3 stores external command names.
  • ID 4 stores variable names. In this case, the record index is equal to the number used in script commands to access the variable.
  • ID 5 stores stack names and it's used by command 27 to change island.

RMAP

There's just one RMAP resource per Mohawk file. Its function is to assign a unique code to each card. The resource is just a block of records, each having the following structure:

unsigned long card_code

The corresponding card is the one with resource ID equal to the record index, so the record count in the RMAP is equal to the greatest ID of CARD resources. The card code is used when going to another stack with command 27: it specifies the destination card in the new stack.

If you are familiar with the Riven debug shell, the CyanCardID value is exactly the card code specified in the RMAP resource.

VARS

The VARS resource is found in Riven saved game files (there is just one). It stores the state of every game variable. The data is just an array of 12-byte records, each representing a variable, with this structure:

unsigned long u0
unsigned long type 0 = unknown, 1 = integer
unsigned long value Saved variable value

u0 starts from 2, and seems to grow when going on with the game.

Fortunately, saved games contain a NAME resource that labels most variables in the VARS resource. The VARS record index simply matches the NAME one.

The number of records is not constant. If you save different games in different places then new records will appear, usually with u1 = 0 and strange values. However, "known" variables (dome combination, telescope levers state etc) are always at the same record.

VERS

This is found only in saved game files, and should just contain version information.

In the CD version, it contains the following 4 bytes, which probably means "version 1.0":

00 01 00 00


However, in the DVD version, it contains the following 4 bytes, which probably means "version 1.1":

00 01 01 00

ZIPS

Found only in saved games, this resource contains a list of visited locations to support the "Zip Mode". It starts with an unsigned short telling how many records will follow. Then, each record contains the following data:

unsigned short name_len
char name[name_len]
unsigned short card_id

Each record is linked to a card: card_id tells its ID, and name is equal to the card name. Zip Mode hotspots share the same name, so when they are clicked the target card ID can be known by looking up in the ZIPS. If the user already visited that card, the record will be there and the hotspot will be able to go to that card.