RIX
| SoftStar RIX | |||||
![]() |
|||||
| Developer: | Pei-Cheng Tong | ||||
| Header: | Custom | ||||
| Content: | Notational | ||||
| Instruments: | Internal | ||||
Target Output
| |||||
| Released: | 1993-02-10 | ||||
| First Game: | Richman 2 (DOS) (zh:大富翁2) | ||||
| Extensions |
|
||||
A SoftStar RIX OPL Music Format musical audio structure was developed for Softstar Entertainment Co.,Ltd. (zh:大宇資訊) by an outsourced programmer, Tong Pei Cheng (zh:童培诚).
RIX stands for Rol Ins miXed file, referring to ROL and INS formats.
It is intended to achieve reproducing OPL2 music without loading AdLib Sound Driver and separate instrument/bank files, saving free space on disk in comparison to ROL + INS/BNK.
Contents
Players
Editors
There are no editors written for RIX. You're supposed to do all the editing with AdLib Visual Composer and INS patchfile editors.
Converters
RIX to ?
? to RIX
Games
This format of music was shipped with games from SoftStar since 1993, with Richman 2 (zh:大富翁2).
During the development of hit game Chinese Paladin: Sword and Fairy (zh:仙剑奇侠传), it was considered tedious to make (with AdLib Visual Composer) and deprecated.
Tho, the musician in charge with project lead decided that Ad Lib Music Synthesizer Card (zh:魔奇音效卡) and fully compatible Sound Blasters (zh:声霸卡) had the most installed base, with years of experience in making the AdLib music, its toolchain (bank maker, AdLib Visual Composer, rol2rix) and workflow, that the project would still focus on AdLib music, whilst providing a MIDI conversion from ROL source files (that's 4 semitone higher pitched) for Roland SC / General MIDI support.
When the MIDI technology came to fruition, the company quickly jumped ship, dropping support for AdLib music altogether, with the last game supporting RIX format being 16 Brands Taiwai Mahjong 2 (zh:正宗台灣十六張麻將2).
| Released | Title | Sample |
|---|---|---|
| 1993-02-10 | Richman 2 (DOS) (大富翁2) | |
| 1994-02-08 | Xuan-Yuan Sword 2 (DOS) (轩辕剑贰) | |
| 1994-02-?? | 16 Brands Taiwai Mahjong (DOS) (正宗台灣十六張麻將) | |
| 1994-08-?? | YAO MO DAO (DOS) (妖魔道) | |
| 1994-10-?? | Empire of Angels 2 (DOS) (天使帝国2) | |
| 1994-??-?? | Act of Fighters (DOS) (格斗拳王) | |
| 1995-01-06 | Xuan-Yuan Sword: Dance of the Maple Leaves (DOS) (轩辕剑外传:枫之舞) | |
| 1995-01-20 | Magic Century 2 (DOS) (魔法世纪2) | |
| 1995-07-15 | Chinese Paladin: Sword and Fairy (DOS) (仙剑奇侠传) | |
| 1995-??-?? | Stardom (DOS) (明星志愿) | |
| 1996-??-?? | Richman 3 (DOS) (大富翁3) | |
| 1996-??-?? | Moshen Zhanji 2 (DOS) (魔神战记2) | |
| 1996-??-?? | Chunqiuzhengbachuan2 (DOS) (春秋争霸战2) | |
| 1997-??-?? | 16 Brands Taiwai Mahjong 2 (DOS) (正宗台灣十六張麻將2) |
Technical
Unlike .IMF or .DRO, it's not just a pure 388h register-ops bit-stream dump.
The format defines a header of 55AAh, offsets to compressed .INS instrument patches, and offsets to ROL/MID-like music pattern chunk, containing commands (e.g. $9x $Ax $Bx $Cx) specifying an OPL2 register operation and timing information from a fixed tick rate. With magic number 8000h at the end of file.
There are some improvements over ROL format:
- Extended Pitch Bent range.(From 100 steps (i.e. cents) in ADVC to 127 steps semitone to semitone, tho invisible to composer.)
- Channel Detuning.
Later, the .RIX files were stored into a pack file .MKF, equivalent to zipping .RIX files into one .zip file without compression. It's done to free some clusters of disk space, but the actual .RIX format remains the same.
Structure
A RIX file is in following structure:
| Data type | Name | Description |
|---|---|---|
| BYTE[20] | fileHearder | Filehearder |
| BYTE[patternOffset - insOffset] | insChunk | .ins Instrument Chunk |
| BYTE[patternOffset -> EOF] | patternChunk | The music pattern commands |
| UINT16LE | EOF | End of file magic number. (0x8000) |
File Header
| Data type | Name | Description | Default value |
|---|---|---|---|
| UINT16LE | fileSignature | FileSignature(might be dummy) | 0x55AA |
| UINT8 | soundMode | 0 = melodic, 1 = percussive | 0 |
| BYTE[5] | dummy | Unknown propose, could be padding | 0 |
| UINT16LE | insOffset | Offset to beginning of INS inst(s) | 0x0014 |
| BYTE[2] | dummy | Unknown propose, could be padding | 0 |
| UINT16LE | patternOffset | Offset to music pattern | 0x???? |
| BYTE[6] | dummy | Unknown propose, could be padding | 0 |
Instrument Chunk
In insChunk, there's only $02-$41 of a valid ins file for total $40 byte bytes per sub-ins-chunk.
A insChunk could contain a number of instruments. A instrument could have a insNumber, calulated with
currentInsOffset = insNumber x $40 + insOffset
Then, in patternChunk, a command of 0x09xyy could be used to select target insNumber instrument patch data.
Pattern Chunk
Pattern Chunk consists of units of UINT16LE words, each word can be either a delayWord, specifying a UINT16LE delay time, or a commandWord.
The word 0x8000 specifies point of End Of File (eoF-word? XD ).
If a word is not either valid eofWord, or commandWord, it will be processed as a delayWord.
A commandWord is split.
With it's lower UINT8 byte(pink boxed) being a value to be parsed.
It's higher UINT8 has been further split down to lower and higher 4 nibbles.
It's higher 4 nibble(green boxed) being a command, lower 4 nibble(purple boxed) being channel to be applied the command.
If soundMode = 0, channel 0 to 8 are valid and melodic, if soundMode = 1, channel 0 to A are valid, 0 to 5 are melodic, 6 to A are percussive(BD,SD,TT,CY,HH).
(You can now refer RIX as RIXMML.... :/ )
Valid Command List
- 0x8000: EOF
- 0x9xyy: insSelect, select target instrument found in insChunk, x: channel apply to, yy: insNum of the target instrument.(UNIT8...of course, not 00 11 22 33....)
- 0xAxyy: pitchBent, select finetuning of a channel of a key, x: channel apply to, yy: pitchBentValue of the current playing key. 0x00 = 1 semitone down, 0xFF = 1 semitone up. (hence 127 steps to 100 cents.)(equivalent of Pitch Accuracy value in ADVC.)
- 0xBxyy: volumeSelect, select target channel volume, x: channel apply to, yy: volumeValue to be applied. 0x00 = OPL OP.TL 0x3F("almost" mute), 0x7F = OPL OP.TL 0x00(loudest)
- 0xCxyy: noteSelect, select target channel playing note, x: channel apply to, yy: noteNum to be applied. 0x3C = C-4, 1 semitone per stepping (C#4 would be 0x3D vice versa). 0x00 = channel mute.
(You'll need to plan timing of commands with delayWord s, every command has it's delay. If you plan it well, you can make two channel to bark "almost" at the same time.)
Links
- github.com/palxex/palresearch/tree/master/rix - Research resources for the Chinese classic RPG "Xiān jiàn Qí Xiá Zhuàn" (also known as PAL/CPAL).
- bilibili.com/video/BV1Sug9zGE1t/?t=24 - Lead musician of PAL Lin Kun-Xin flexing FG01.ROL in AdLib Visual Composer, the source file of MUSIC_36.RIX.






