19,903
edits
m (clarity in wording of Win/Mac differences and data offsets) |
(discovered this huge section commented out – I have restored it, tried to correct the broken parts, deleted the incomplete parts, and removed any mention of Macs being big-endian since that hasn't been true since two architecture migrations ago; the table markup is still pretty busted but it's functional) |
||
| Line 131: | Line 131: | ||
Environment/character/particle TXMPs seem to be using .raw storage consistently (not checked beyond level1_Final). As a notable anomaly, .sep storage is used for the following three textures (console screens) in level0_Final: _CON_SAVEGAME (main TXMP only; the animation frames use .raw storage), _CON_SAVEGAME_USED, _CON_USED. | Environment/character/particle TXMPs seem to be using .raw storage consistently (not checked beyond level1_Final). As a notable anomaly, .sep storage is used for the following three textures (console screens) in level0_Final: _CON_SAVEGAME (main TXMP only; the animation frames use .raw storage), _CON_SAVEGAME_USED, _CON_USED. | ||
==Oni's internal storage types== | |||
Some of Oni's 16 types of image storage are elaborated on below in order to illustrate exactly how they work. The RAM view assumes little-endianness, which is true for Windows and for Macs since 2006. | |||
===ARGB4444 (type 0)=== | |||
*A 16-bit field is used to store 4 color channels (4 bits each, values from 0 to 15). | *A 16-bit field is used to store 4 color channels (4 bits each, values from 0 to 15). | ||
*Bit masks are 0x000F for Blue, 0x00F0 for Green, 0x0F00 for Red, 0xF000 for Alpha. | *Bit masks are 0x000F for Blue, 0x00F0 for Green, 0x0F00 for Red, 0xF000 for Alpha. | ||
* | *Stored as big-endian in TXMP (first the AAAARRRR byte, then the GGGGBBBB byte). | ||
{|border=1 cellpadding=3 cellspacing=0 | {|border=1 cellpadding=3 cellspacing=0 | ||
!<br | !<br>Bits | ||
!Byte 1 (high)<br | !Byte 1 (high)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 0 (low)<br | !Byte 0 (low)<br><code>7 6 5 4 3 2 1 0</code> | ||
|- | |- | ||
!Masks||<code>A A A A R R R R</code>||<code>G G G G B B B B</code> | !Masks||<code>A A A A R R R R</code>||<code>G G G G B B B B</code> | ||
|- | |- | ||
!colspan=3|<br | !colspan=3|<br>Bit values for primary colors (fully opaque) | ||
!Hex view | !Hex view | ||
! | !RAM view | ||
|- | |- | ||
|Black||<code>1 1 1 1 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | |Black||<code>1 1 1 1 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | ||
| Line 196: | Line 173: | ||
!FF F0!!F0 FF | !FF F0!!F0 FF | ||
|} | |} | ||
===RGB555 (type 1)=== | |||
*A 16-bit field is used to store 3 color channels (5 bits each, values from 0 to 31). | *A 16-bit field is used to store 3 color channels (5 bits each, values from 0 to 31). | ||
*Bit masks are 0x001F for Blue, 0x03E0 for Green, 0x7C00 for Red. | *Bit masks are 0x001F for Blue, 0x03E0 for Green, 0x7C00 for Red. | ||
*The high bit (0x8000) is unused, but is always set to 1 by convention. | *The high bit (0x8000) is unused, but is always set to 1 by convention. | ||
* | *Stored in little-endian order in TXMP. | ||
{|border=1 cellpadding=3 cellspacing=0 | {|border=1 cellpadding=3 cellspacing=0 | ||
!<br | !<br>Bits | ||
!Byte 1 (high)<br | !Byte 1 (high)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 0 (low)<br | !Byte 0 (low)<br><code>7 6 5 4 3 2 1 0</code> | ||
|- | |- | ||
!Masks||<code>X R R R R R G G</code>||<code>G G G B B B B B</code> | !Masks||<code>X R R R R R G G</code>||<code>G G G B B B B B</code> | ||
|- | |- | ||
!colspan=3|<br | !colspan=3|<br>Bit values for primary colors | ||
!Hex view | !Hex view | ||
! | !RAM view | ||
|- | |- | ||
|Black||<code>1 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | |Black||<code>1 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | ||
| Line 238: | Line 214: | ||
!FF E0!!E0 FF | !FF E0!!E0 FF | ||
|} | |} | ||
===ARGB1555 (type 2)=== | |||
*A 16-bit field is used to store 3 color channels (5 bits each, values from 0 to 31) and one 1-bit channel. | *A 16-bit field is used to store 3 color channels (5 bits each, values from 0 to 31) and one 1-bit channel. | ||
*Bit masks are 0x001F for Blue, 0x03E0 for Green, 0x7C00 for Red, and 0x8000 for Alpha. | *Bit masks are 0x001F for Blue, 0x03E0 for Green, 0x7C00 for Red, and 0x8000 for Alpha. | ||
{|border=1 cellpadding=3 cellspacing=0 | {|border=1 cellpadding=3 cellspacing=0 | ||
!<br | !<br>Bits | ||
!Byte 1 (high)<br | !Byte 1 (high)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 0 (low)<br | !Byte 0 (low)<br><code>7 6 5 4 3 2 1 0</code> | ||
|- | |- | ||
!Masks||<code>A R R R R R G G</code>||<code>G G G B B B B B</code> | !Masks||<code>A R R R R R G G</code>||<code>G G G B B B B B</code> | ||
|- | |- | ||
!colspan=3|<br | !colspan=3|<br>Bit values for primary colors (opaque) | ||
!Hex view | !Hex view | ||
! | !RAM view | ||
|- | |- | ||
|Black||<code>1 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | |Black||<code>1 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | ||
| Line 279: | Line 253: | ||
!FF E0!!E0 FF | !FF E0!!E0 FF | ||
|} | |} | ||
===A4I4 (type 6)=== | |||
*An 8-bit field is used to store an intensity and an alpha (4 bits each, values from 0 to 15). | *An 8-bit field is used to store an intensity and an alpha (4 bits each, values from 0 to 15). | ||
*Bit masks are 0x0F for Intensity, 0xF0 for Alpha. | *Bit masks are 0x0F for Intensity, 0xF0 for Alpha. | ||
| Line 306: | Line 280: | ||
|} | |} | ||
===ARGB8888 (type 7)=== | |||
*A 32-bit field is used to store 4 color channels (8 bits each, values from 0 to 255). | *A 32-bit field is used to store 4 color channels (8 bits each, values from 0 to 255). | ||
*Bit masks are 0x000000FF for Blue, 0x0000FF00 for Green, 0x00FF0000 for Red, 0xFF000000 for Alpha. | *Bit masks are 0x000000FF for Blue, 0x0000FF00 for Green, 0x00FF0000 for Red, 0xFF000000 for Alpha. | ||
{|border=1 cellpadding=3 cellspacing=0 | {|border=1 cellpadding=3 cellspacing=0 | ||
!<br | !<br>Bits | ||
!Byte 3 (highest)<br | !Byte 3 (highest)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 2 (higher)<br | !Byte 2 (higher)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 1 (high)<br | !Byte 1 (high)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 0 (low)<br | !Byte 0 (low)<br><code>7 6 5 4 3 2 1 0</code> | ||
|- | |- | ||
!Masks||<code>A A A A A A A A</code>||<code>R R R R R R R R</code>||<code>G G G G G G G G</code>||<code>B B B B B B B B</code> | !Masks||<code>A A A A A A A A</code>||<code>R R R R R R R R</code>||<code>G G G G G G G G</code>||<code>B B B B B B B B</code> | ||
|- | |- | ||
!colspan=5|<br | !colspan=5|<br>Bit values for primary colors (fully opaque) | ||
!Hex view | !Hex view | ||
! | !RAM view | ||
|- | |- | ||
|Black||<code>1 1 1 1 1 1 1 1</code>||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | |Black||<code>1 1 1 1 1 1 1 1</code>||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | ||
| Line 349: | Line 320: | ||
!FF FF FF 00!!00 FF FF FF | !FF FF FF 00!!00 FF FF FF | ||
|} | |} | ||
===RGB888 (type 8)=== | |||
*A 32-bit field is used to store 3 color channels (8 bits each, values from 0 to 255). | *A 32-bit field is used to store 3 color channels (8 bits each, values from 0 to 255). | ||
*Bit masks are 0x000000FF for Blue, 0x0000FF00 for Green, 0x00FF0000 for Red. | *Bit masks are 0x000000FF for Blue, 0x0000FF00 for Green, 0x00FF0000 for Red. | ||
*The high byte (0xFF000000) is unused, but is always set to 00 by convention. | *The high byte (0xFF000000) is unused, but is always set to 00 by convention. | ||
{|border=1 cellpadding=3 cellspacing=0 | {|border=1 cellpadding=3 cellspacing=0 | ||
!<br | !<br>Bits | ||
!Byte 3 (highest)<br | !Byte 3 (highest)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 2 (higher)<br | !Byte 2 (higher)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 1 (high)<br | !Byte 1 (high)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 0 (low)<br | !Byte 0 (low)<br><code>7 6 5 4 3 2 1 0</code> | ||
|- | |- | ||
!Masks||<code>X X X X X X X X</code>||<code>R R R R R R R R</code>||<code>G G G G G G G G</code>||<code>B B B B B B B B</code> | !Masks||<code>X X X X X X X X</code>||<code>R R R R R R R R</code>||<code>G G G G G G G G</code>||<code>B B B B B B B B</code> | ||
|- | |- | ||
!colspan=5|<br | !colspan=5|<br>Bit values for primary colors | ||
!Hex view | !Hex view | ||
! | !RAM view | ||
|- | |- | ||
|Black||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | |Black||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code>||<code>0 0 0 0 0 0 0 0</code> | ||
| Line 393: | Line 362: | ||
!00 FF FF 00!!00 FF FF 00 | !00 FF FF 00!!00 FF FF 00 | ||
|} | |} | ||
===RGB_Bytes (type 10)=== | |||
*Three consecutive 8-bit fields are used to store 3 color channels (8 bits each, values from 0 to 255). | *Three consecutive 8-bit fields are used to store 3 color channels (8 bits each, values from 0 to 255). | ||
*Each channel has its own byte, and there is no "unused" byte (the bytes are packed 3 by 3). | *Each channel has its own byte, and there is no "unused" byte (the bytes are packed 3 by 3). | ||
*Endianness is irrelevant when storing as a sequence of bytes. | *Endianness is irrelevant when storing as a sequence of bytes. | ||
{|border=1 cellpadding=3 cellspacing=0 | {|border=1 cellpadding=3 cellspacing=0 | ||
!<br | !<br>Bits | ||
!Byte 0 (red)<br | !Byte 0 (red)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 1 (green)<br | !Byte 1 (green)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 2 (blue)<br | !Byte 2 (blue)<br><code>7 6 5 4 3 2 1 0</code> | ||
|- | |- | ||
!Masks||<code>R R R R R R R R</code>||<code>G G G G G G G G</code>||<code>B B B B B B B B</code> | !Masks||<code>R R R R R R R R</code>||<code>G G G G G G G G</code>||<code>B B B B B B B B</code> | ||
| Line 433: | Line 402: | ||
!FF FF 00 | !FF FF 00 | ||
|} | |} | ||
===RGBA_Bytes (type 11)=== | |||
*Four consecutive 8-bit fields are used to store 4 color channels (8 bits each, values from 0 to 255). | *Four consecutive 8-bit fields are used to store 4 color channels (8 bits each, values from 0 to 255). | ||
*Each channel has its own byte. Endianness is irrelevant when storing as a sequence of bytes. | *Each channel has its own byte. Endianness is irrelevant when storing as a sequence of bytes. | ||
{|border=1 cellpadding=3 cellspacing=0 | {|border=1 cellpadding=3 cellspacing=0 | ||
!<br | !<br>Bits | ||
!Byte 0 (red)<br | !Byte 0 (red)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 1 (green)<br | !Byte 1 (green)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 2 (blue)<br | !Byte 2 (blue)<br><code>7 6 5 4 3 2 1 0</code> | ||
!Byte 3 (alpha)<br | !Byte 3 (alpha)<br><code>7 6 5 4 3 2 1 0</code> | ||
|- | |- | ||
!Masks||<code>R R R R R R R R</code>||<code>G G G G G G G G</code>||<code>B B B B B B B B</code>||<code>A A A A A A A A</code> | !Masks||<code>R R R R R R R R</code>||<code>G G G G G G G G</code>||<code>B B B B B B B B</code>||<code>A A A A A A A A</code> | ||
|- | |- | ||
!colspan=5|<br | !colspan=5|<br>Bit values for primary colors (fully opaque) | ||
!Hex view | !Hex view | ||
|- | |- | ||
| Line 473: | Line 442: | ||
!FF FF 00 FF | !FF FF 00 FF | ||
|} | |} | ||
==Notes== | ==Notes== | ||