Flipnote Files/PPM: Difference between revisions
| (19 intermediate revisions by 7 users not shown) | |||
| Line 2: | Line 2: | ||
/private/ds/app/4B475556/001 - European location | /private/ds/app/4B475556/001 - European location | ||
/private/ds/app/4B475545/001 - North American location | |||
You can save your images in a user folder as long as it's on the same level as the 001 folder. Clicking on the Choose Folder icon on the top of the View Flipnote / SD Card option gives you a list of normal folders, and you can swap to user folders by selecting the normal button again. This could possibly be to overcome a limitation in one of the files (possibly the dirmemo2.lst file). | You can save your images in a user folder as long as it's on the same level as the 001 folder. Clicking on the Choose Folder icon on the top of the View Flipnote / SD Card option gives you a list of normal folders, and you can swap to user folders by selecting the normal button again. This could possibly be to overcome a limitation in one of the files (possibly the dirmemo2.lst file). | ||
| Line 34: | Line 35: | ||
| 0x0010 | | 0x0010 | ||
| 2 | | 2 | ||
| | | Lock - 0 open, 1 locked | ||
|- | |- | ||
| 0x0012 | | 0x0012 | ||
| Line 77: | Line 78: | ||
|- | |- | ||
| 0x009A | | 0x009A | ||
| | | 4 | ||
| | | Date stored as the number of seconds since midnight 1 Jan 2000. | ||
|- | |- | ||
| 0x009E | |||
| 2 | |||
| Filler - 00 00 | |||
|- | |||
| 0x00A0 | | 0x00A0 | ||
| 1536 | | 1536 | ||
| Line 189: | Line 194: | ||
[[Image:ppm_1.png]] [[Image:ppm_2.png]] | [[Image:ppm_1.png]] [[Image:ppm_2.png]] | ||
You can use pbsds's [[User:Pbsds/PPMtool|PPMtool]] to extract the preview image yourself | |||
==Animation Data Section== | ==Animation Data Section== | ||
| Line 201: | Line 207: | ||
|- | |- | ||
| 0000 | | 0000 | ||
| | | 2 | ||
| Size of the offset table | | Size of the offset table | ||
|- | |||
| 0002 | |||
| 2 | |||
| Padding | |||
|- | |- | ||
| 0004 | | 0004 | ||
| Line 305: | Line 315: | ||
if( useByte == 0 ) // Set the full line to the current paper colour | if( useByte == 0 ) // Set the full line to the current paper colour | ||
{ | |||
memset( outB, paper, 256 ); | memset( outB, paper, 256 ); | ||
} | |||
else // Bytes in this line, read and deal with them | else // Bytes in this line, read and deal with them | ||
{ | { | ||
| Line 318: | Line 330: | ||
{ | { | ||
if( ( data & 0x01 ) == 0x01 ) | if( ( data & 0x01 ) == 0x01 ) | ||
{ | |||
outB[ x ] = invflag == 0 ? pen : paper; | outB[ x ] = invflag == 0 ? pen : paper; | ||
} | |||
else | else | ||
{ | |||
outB[ x ] = invflag == 0 ? paper : pen; | outB[ x ] = invflag == 0 ? paper : pen; | ||
} | |||
x ++; | x ++; | ||
| Line 337: | Line 352: | ||
if( x < 256 ) | if( x < 256 ) | ||
{ | |||
memset( &outB[ x ], paper, 256 - x ); | memset( &outB[ x ], paper, 256 - x ); | ||
} | |||
} | } | ||
| Line 345: | Line 362: | ||
The outB and inB are pointers to pre-allocated memory blocks, the inB is a pointer to the file, and the outB is the output data block. The useByte is the 4 bytes that is at the start of the line, if your reading a type 3 line (full raw data) just pass in 0xFFFFFFFF. The pen and paper values are what was read from the pen and paper information block. | The outB and inB are pointers to pre-allocated memory blocks, the inB is a pointer to the file, and the outB is the output data block. The useByte is the 4 bytes that is at the start of the line, if your reading a type 3 line (full raw data) just pass in 0xFFFFFFFF. The pen and paper values are what was read from the pen and paper information block. | ||
==Sound data section== | |||
The position of the sound header is 0x6A0 + AnimationDataSize | |||
{| class="wikitable" | |||
|- style="background-color: #ddd;" | |||
! Length | |||
! Function | |||
! Description | |||
|- | |||
| Framecount | |||
| Sound effect usage. | |||
| Each byte represents a frame. bit #1(from Right to Left) represents Sound effect 1, bit #2 represents Sound effect 2 and bit #3 represents Sound effect 3. the last 5 bits is padding. | |||
|- | |||
| 0 - 3 | |||
| Padding | |||
| 0x00 * (0 to 3). Makes the offset to the next value dividable by 4. | |||
|- | |||
| 4 | |||
| Size of the background music. | |||
| The size of the background music in bytes in the audio data below. 0x0 if not used/empty. | |||
|- | |||
| 4 | |||
| Size of sound effect #1 | |||
| The size of the sound effect #1 in bytes in the audio data below, max size is 0x2000. 0x0 if not used/empty. | |||
|- | |||
| 4 | |||
| Size of sound effect #2 | |||
| The size of the sound effect #3 in bytes in the audio data below, max size is 0x2000. 0x0 if not used/empty. | |||
|- | |||
| 4 | |||
| Size of sound effect #3 | |||
| The size of the sound effect #3 in bytes in the audio data below, max size is 0x2000. 0x0 if not used/empty. | |||
|- | |||
| 1 | |||
| Current Framespeed. | |||
| This is the speed of the flipnote. It's in the range of 1-8. To get the correct value, you must take 8, and subtract the decimal value of this byte. | |||
|- | |||
| 1 | |||
| Given Framespeed when BGM was recorded. | |||
| This is the speed of the flipnote when the BGM was recorded/modified. It's in the range of 1-8. This is used to resample the sound to the new speed. To get the correct value, you must take 8, and subtract the decimal value of this byte. | |||
|- | |||
| 14 | |||
| Padding | |||
| 0x00 * 14 | |||
|} | |||
Then comes the audio data. | |||
*First comes the BGM(if used) | |||
*Then comes sound effect #1(if used) | |||
*Then comes sound effect #2(if used) | |||
*Then comes sound effect #3(if used) | |||
The sound data is 4bit ADPCM with reversed nibbles @ 8kHz. | |||
You can decode the sound yourself with "sox -t ima -N [input] [output]" | |||
==Signature== | |||
The last 0x10-bytes in a PPM are all-zero. The 0x80 bytes before that is a RSA-1024 SHA-1 signature over the whole PPM, excluding the last 0x90 bytes with the signature. | |||