Pokemon Mystery Dungeon Explorers of Sky Save Structure

From ProjectPokemon Wiki
Revision as of 00:55, 3 February 2017 by UniqueGeek (talk | contribs) (Undo revision 5506 by UniqueGeek (talk))
Jump to navigation Jump to search
This article is incomplete.
Please feel free to add missing information and complete the article.

The save file for Pokémon Mystery Dungeon Explorers of Sky is 128KB and has three root blocks. The first two store the actual data and are 50KB large each. If the checksum on one of the first two blocks is invalid, the other will be loaded. If both are invalid, the save will be deleted. The third block stores some quick save data, including whether or not a quick save has been resumed.

Checksum

The checksum is 4 bytes long and is at the beginning of any of the three root blocks. To calculate the checksum, split the data from 0x4 to 0xB65A into 4 byte words, add each word together and truncate the result to 32 bits. VB.Net Code to fix the checksum for both sections, where _rawData is an array of byte containing the save file:

   Public Sub FixChecksum()
       Dim words As New List(Of UInt32)
       For count As Integer = 4 To 46682 Step 4
           words.Add(BitConverter.ToUInt32(_rawData, count))
       Next
       Dim sum As UInt64 = 0
       For Each item In words
           sum += item
       Next
       Dim buffer() As Byte = BitConverter.GetBytes(sum)
       For x As Byte = 0 To 3
           _rawData(x) = buffer(x)
           _rawData(x + &HC800) = buffer(x)
       Next
   End Sub

Byte Storage

Due to limited storage space, the game has very efficient storage of data. Unused bits are avoided by not necessarily paying attention to byte lines. Ex. 3 variables, one 3 bits, one 4 bits, and one 11 bits might be stored like 11122223 33333333 33000000. In cases where something is compressed like this and is more than just a few bits, it must be retrieved with a modified kind of bit shifting. It will be referred to as "PMD bit shifting" or the "special bit shifting" on this wiki page.

C# code to unshift the bytes:

static Stream decode(Stream src, int startbit, int bits)
{
    MemoryStream res = new MemoryStream(bits / 8);
    int srcbit = startbit;
    int resbit = 0;
    byte a = srcbit == 0 ? (byte)0 : (byte)(src.ReadByte() >> srcbit);
    byte b = 0;
    while (bits-- > 0) {
        b >>= 1;
        if ((a & 1) != 0) b |= 0x80;
        a >>= 1;
        if (++srcbit == 8) {
            a = (byte)src.ReadByte();
            srcbit = 0;
        }
        if (++resbit == 8) {
            resbit = 0;
            res.WriteByte(b);
        }
    }
    return res;
}

Number of Adventures

0x8B70-0x8B73: 32-bit signed integer in little endian format.

Team Name

&H994E to &H9958, 9 bytes long. It is similar to ANSI, but slightly different, as shown on this chart.

Pokémon Storage

Pokémon storage begins at 0x464. There are 720 Pokémon slots, each 362 bits long (45 bytes + 2 bits). If the start bit for a Pokémon (relative to 0x464) is not divisible by 8, it must be bit shifted using the special PMD bit shifting, with the start bit being the remainder of the bit offset divided by 8. In other words, 1st Pokémon, don't bit shift. 2nd, PMD bit shift with the start bit 2. 3rd, PMD bit shift with the start bit 4. 4th, PMD bit shift with the start bit 6. 5th, don't bit shift. And so on.

Pokémon Structure

(coming soon)

*.skypkm File

A skypkm file contains all the Pokémon data, padded by 6 bits at the beginning of the file (because the file size is 45 bytes and 2 bits; 6 more bits are needed). The reason the 6 bits aren't at the end is so that reading the nickname is easier.

Character Encoding

This game stores strings in a format similar to ANSI. The following is a list of HEX values paired with the corresponding character. Brackets indicate that the game does not support that character.

00=[END]
01=[$01]
02=[$02]
03=[$03]
04=[$04]
05=[$05]
06=[$06]
07=[$07]
08=[$08]
09=[$09]
0A=[$0A]
0B=[$0B]
0C=[$0C]
0D=[$0D]
0E=[$0E]
0F=[$0F]
10=[$10]
11=[$11]
12=[$12]
13=[$13]
14=[$14]
15=[$15]
16=[$16]
17=[$17]
18=[$18]
19=[$19]
1A=[$1A]
1B=[$1B]
1C=[$1C]
1D=[$1D]
1E=[$1E]
1F=[$1F]
20= 
21=!
22="
23=#
24=$
25=%
26=&
27='
28=(
29=)
2A=*
2B=+
2C=,
2D=-
2E=.
2F=/
30=0
31=1
32=2
33=3
34=4
35=5
36=6
37=7
38=8
39=9
3A=:
3B=;
3C=<
3D==
3E=>
3F=?
40=@
41=A
42=B
43=C
44=D
45=E
46=F
47=G
48=H
49=I
4A=J
4B=K
4C=L
4D=M
4E=N
4F=O
50=P
51=Q
52=R
53=S
54=T
55=U
56=V
57=W
58=X
59=Y
5A=Z
5B=[$5B]
5C=\
5D=]
5E=^
5F=_
60=`
61=a
62=b
63=c
64=d
65=e
66=f
67=g
68=h
69=i
6A=j
6B=k
6C=l
6D=m
6E=n
6F=o
70=p
71=q
72=r
73=s
74=t
75=u
76=v
77=w
78=x
79=y
7A=z
7B={
7C=|
7D=}
7E=[$7E]
7F=[$7F]
80=€
81=[$81]
82=[$82]
83=[$83]
84=[$84]
85=​…
86=†
87=[$87]
88=ˆ
89=‰
8A=Š
8B=‹
8C=Œ
8D=[e]
8E=Ž
8F=[è]
90=•
91=‘
92=’
93=“
94=”
95=•
96=[er]
97=[re]
98=~
99=™
9A=š
9B=›
9C=œ
9D=•
9E=ž
9F=Ÿ
A0= 
A1=¡
A2=¢
A3=£
A4=¤
A5=¥
A6=¦
A7=§
A8=¨
A9=©
AA=ª
AB=«
AC=¬
AD=­
AE=®
AF=¯
B0=°
B1=±
B2=²
B3=³
B4=´
B5=µ
B6=¶
B7=„
B8=‚
B9=¹
BA=º
BB=»
BC=←
BD=♂
BE=♀
BF=¿
C0=À
C1=Á
C2=Â
C3=Ã
C4=Ä
C5=Å
C6=Æ
C7=Ç
C8=È
C9=É
CA=Ê
CB=Ë
CC=Ì
CD=Í
CE=Î
CF=Ï
D0=Ð
D1=Ñ
D2=Ò
D3=Ó
D4=Ô
D5=Õ
D6=Ö
D7=×
D8=Ø
D9=Ù
DA=Ú
DB=Û
DC=Ü
DD=Ý
DE=Þ
DF=ß
E0=à
E1=á
E2=â
E3=ã
E4=ä
E5=å
E6=æ
E7=ç
E8=è
E9=é
EA=ê
EB=ë
EC=ì
ED=í
EE=î
EF=ï
F0=ð
F1=ñ
F2=ò
F3=ó
F4=ô
F5=õ
F6=ö
F7=÷
F8=ø
F9=ù
FA=ú
FB=û
FC=ü
FD=ý
FE=þ
FF=ÿ