about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-09-10 17:16:52 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-09-10 17:16:52 -0400
commit1d82e3affd42c2336702af4a644baa8eec249ead (patch)
treeaeea397863a7d2014bd960a9bd3ba090f841bcce
parent0882d1020d75bbddc8e8fbe30aed435e8814988a (diff)
downloadgen3uploader-1d82e3affd42c2336702af4a644baa8eec249ead.tar.gz
gen3uploader-1d82e3affd42c2336702af4a644baa8eec249ead.tar.bz2
gen3uploader-1d82e3affd42c2336702af4a644baa8eec249ead.zip
Increased stability and added support for non-English names
The GameCube side of the program now can convert from the propietary
character set to UTF-8. This is useful for representing names of Pokémon
and players in a neutral way. The propietary character set is mostly
compatible between the six languages supported by the games (as in, the
hiragana and katakana characters unique to Japanese occupy spaces not
used by the other languages for names, as do the letters with umlauts
unique to German). However, six codepoints differ between the Japanese
and non-Japanese character sets, and an additional two differ even
amongst the non-Japanese sets. Because of this, the function that
converts to UTF-8 takes a language as a parameter, and uses the correct
characters for that language.

From there, the behavior of this function differs slightly to that of
the games. In the non-Japanese games, the Japanese encoding is used if
the Pokémon in question originated in a Japanese game, and the
non-Japanese encoding (disregarding the regional differences in the two
codepoints mentioned earlier) otherwise. In the Japanese games, the
Japanese encoding is used regardless of the Pokémon's origin. The
decoding function I wrote always uses the character set corresponding to
the language of the Pokémon's origin, because that most accurately
represents the name given to it, and will not change just because the
Pokémon was traded to a different game. The character set used for the
name of the player is the one corresponding to the language of the
cartridge.

Additionally, a number of changes were made to the communication
protocol between the GameCube and the GBA that appear to have
dramatically increased stability. The most significant of these is
likely that the transfer delay was increased tenfold. This causes the
multiboot image to take slightly longer to download to the GBA, but the
difference is not large enough to outweigh the benefits of the increased
stability.
-rw-r--r--gba/source/link.c15
-rw-r--r--gba/source/main.c17
-rw-r--r--gba/source/serialize.c12
-rw-r--r--gba/source/serialize.h3
-rw-r--r--include/pokemon.h13
-rw-r--r--source/encoding.c398
-rw-r--r--source/encoding.h7
-rw-r--r--source/link.c17
-rw-r--r--source/main.c51
9 files changed, 448 insertions, 85 deletions
diff --git a/gba/source/link.c b/gba/source/link.c index 26443c8..05e4732 100644 --- a/gba/source/link.c +++ b/gba/source/link.c
@@ -12,9 +12,9 @@
12 12
13void initializeLink() 13void initializeLink()
14{ 14{
15 REG_HS_CTRL |= JOY_RW;
16 REG_JOYTR = 0; 15 REG_JOYTR = 0;
17 while ((REG_HS_CTRL & JOY_WRITE) == 0); 16 REG_HS_CTRL |= JOY_RW;
17 while ((REG_HS_CTRL & JOY_READ) == 0);
18 REG_HS_CTRL |= JOY_RW; 18 REG_HS_CTRL |= JOY_RW;
19} 19}
20 20
@@ -22,29 +22,22 @@ void waitForAck()
22{ 22{
23 while ((REG_HS_CTRL & JOY_WRITE) == 0); 23 while ((REG_HS_CTRL & JOY_WRITE) == 0);
24 REG_HS_CTRL |= JOY_RW; 24 REG_HS_CTRL |= JOY_RW;
25 REG_JOYTR = 0;
26 while ((REG_HS_CTRL & JOY_WRITE) == 0);
27 REG_HS_CTRL |= JOY_RW;
28} 25}
29 26
30u32 waitForResponse() 27u32 waitForResponse()
31{ 28{
32 u32 val; 29 u32 val;
33 30
34 REG_JOYTR = 1;
35 while ((REG_HS_CTRL & JOY_WRITE) == 0);
36 val = REG_JOYRE;
37 REG_HS_CTRL |= JOY_RW;
38 REG_JOYTR = 0;
39 while ((REG_HS_CTRL & JOY_WRITE) == 0); 31 while ((REG_HS_CTRL & JOY_WRITE) == 0);
40 REG_HS_CTRL |= JOY_RW; 32 REG_HS_CTRL |= JOY_RW;
33 val = REG_JOYRE;
41 34
42 return val; 35 return val;
43} 36}
44 37
45void sendS32(s32 val) 38void sendS32(s32 val)
46{ 39{
47 REG_JOYTR = val; 40 sendU32(val);
48} 41}
49 42
50void sendU32(u32 val) 43void sendU32(u32 val)
diff --git a/gba/source/main.c b/gba/source/main.c index aeb05af..0934e91 100644 --- a/gba/source/main.c +++ b/gba/source/main.c
@@ -113,6 +113,21 @@ int main(void)
113 sendU32(trainerIdNum); 113 sendU32(trainerIdNum);
114 waitForAck(); 114 waitForAck();
115 115
116 // Send cart language.
117 u8 cartLang = 0;
118 switch (*(u8*)(0x80000AF))
119 {
120 case 'J': cartLang = Japanese; break;
121 case 'E': cartLang = English; break;
122 case 'F': cartLang = French; break;
123 case 'I': cartLang = Italian; break;
124 case 'D': cartLang = German; break;
125 case 'S': cartLang = Spanish; break;
126 }
127
128 sendU32(cartLang);
129 waitForAck();
130
116 // Does the player want to import this game? 131 // Does the player want to import this game?
117 if (waitForResponse() == 0) 132 if (waitForResponse() == 0)
118 { 133 {
@@ -193,7 +208,7 @@ int main(void)
193 208
194 struct PokemonIntermediate pki; 209 struct PokemonIntermediate pki;
195 210
196 PokemonIntermediateInit(&pki, bpkm, trainerIdNum, secretIdNum, &gameData); 211 PokemonIntermediateInit(&pki, bpkm, trainerIdNum, secretIdNum);
197 PokemonIntermediateStream(&pki); 212 PokemonIntermediateStream(&pki);
198 } 213 }
199} 214}
diff --git a/gba/source/serialize.c b/gba/source/serialize.c index 4a80bdf..c5e8570 100644 --- a/gba/source/serialize.c +++ b/gba/source/serialize.c
@@ -11,14 +11,6 @@
11#include "exptables.h" 11#include "exptables.h"
12#include "dexorder.h" 12#include "dexorder.h"
13 13
14enum Stat {
15 StatAttack,
16 StatDefense,
17 StatSpeed,
18 StatSpAttack,
19 StatSpDefense
20};
21
22u32 CalculateStat( 14u32 CalculateStat(
23 u8 base, 15 u8 base,
24 u32 iv, 16 u32 iv,
@@ -50,8 +42,7 @@ void PokemonIntermediateInit(
50 struct PokemonIntermediate* pki, 42 struct PokemonIntermediate* pki,
51 struct BoxPokemon* bpkm, 43 struct BoxPokemon* bpkm,
52 u16 trainerId, 44 u16 trainerId,
53 u16 secretId, 45 u16 secretId)
54 const struct GameData* gameData)
55{ 46{
56 DecryptBoxPokemon(bpkm); 47 DecryptBoxPokemon(bpkm);
57 48
@@ -88,6 +79,7 @@ void PokemonIntermediateInit(
88 pki->metLocation = sub3->metLocation; 79 pki->metLocation = sub3->metLocation;
89 pki->pokeball = sub3->pokeball; 80 pki->pokeball = sub3->pokeball;
90 pki->altAbility = sub3->altAbility; 81 pki->altAbility = sub3->altAbility;
82 pki->language = bpkm->language & 3;
91 83
92 // Derive nature from the personality value. 84 // Derive nature from the personality value.
93 pki->nature = (bpkm->personality % 25); 85 pki->nature = (bpkm->personality % 25);
diff --git a/gba/source/serialize.h b/gba/source/serialize.h index 38a4d6b..7fcae0f 100644 --- a/gba/source/serialize.h +++ b/gba/source/serialize.h
@@ -17,8 +17,7 @@ void PokemonIntermediateInit(
17 struct PokemonIntermediate* pki, 17 struct PokemonIntermediate* pki,
18 struct BoxPokemon* bpkm, 18 struct BoxPokemon* bpkm,
19 u16 trainerId, 19 u16 trainerId,
20 u16 secretId, 20 u16 secretId);
21 const struct GameData* gameData);
22 21
23void PokemonIntermediateStream(struct PokemonIntermediate* pki); 22void PokemonIntermediateStream(struct PokemonIntermediate* pki);
24 23
diff --git a/include/pokemon.h b/include/pokemon.h index 80e7ee7..d8a7265 100644 --- a/include/pokemon.h +++ b/include/pokemon.h
@@ -11,6 +11,15 @@
11#define OT_NAME_LENGTH 7 11#define OT_NAME_LENGTH 7
12#define TILE_SIZE_4BPP 32 12#define TILE_SIZE_4BPP 32
13 13
14enum PokemonLanguage {
15 Japanese = 1,
16 English = 2,
17 French = 3,
18 Italian = 4,
19 German = 5,
20 Spanish = 7
21};
22
14struct PokemonIntermediate { 23struct PokemonIntermediate {
15 u32 otId; 24 u32 otId;
16 u32 experience; 25 u32 experience;
@@ -35,7 +44,9 @@ struct PokemonIntermediate {
35 u8 nickname[POKEMON_NAME_LENGTH]; 44 u8 nickname[POKEMON_NAME_LENGTH];
36 u8 otName[OT_NAME_LENGTH]; 45 u8 otName[OT_NAME_LENGTH];
37 u8 pokeball; 46 u8 pokeball;
38 u8 altAbility; // waste of space but nothing to pack it with 47 u8 language:3;
48 u8 altAbility:1;
49 u8 filler:4; // waste of space but nothing to pack it with
39 50
40 // the following values are generated from the personality value. 51 // the following values are generated from the personality value.
41 u8 nature:6; 52 u8 nature:6;
diff --git a/source/encoding.c b/source/encoding.c index 0be1e0b..0a44800 100644 --- a/source/encoding.c +++ b/source/encoding.c
@@ -9,15 +9,397 @@
9 */ 9 */
10#include "encoding.h" 10#include "encoding.h"
11 11
12const char charmap[] = { 12const char* charmap[] = {
13 ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '?', '.', '-', ' ', 13 " ", // space
14 ' ', '\"', '\"', '\'', '\'', '*', '*', ' ', ',', ' ', '/', 'A', 'B', 'C', 'D', 'E', 14 "\xe3\x81\x82", // hiragana letter a
15 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 15 "\xe3\x81\x84", // hiragana letter i
16 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 16 "\xe3\x81\x86", // hiragana letter u
17 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ' ' 17 "\xe3\x81\x88", // hiragana letter e
18 "\xe3\x81\x8a", // hiragana letter o
19 "\xe3\x81\x8b", // hiragana letter ka
20 "\xe3\x81\x8d", // hiragana letter ki
21 "\xe3\x81\x8f", // hiragana letter ku
22 "\xe3\x81\x91", // hiragana letter ke
23 "\xe3\x81\x93", // hiragana letter ko
24 "\xe3\x81\x95", // hiragana letter sa
25 "\xe3\x81\x97", // hiragana letter si
26 "\xe3\x81\x99", // hiragana letter su
27 "\xe3\x81\x9b", // hiragana letter se
28 "\xe3\x81\x9d", // hiragana letter so
29 "\xe3\x81\x9f", // hiragana letter ta
30 "\xe3\x81\xa1", // hiragana letter ti
31 "\xe3\x81\xa4", // hiragana letter tu
32 "\xe3\x81\xa6", // hiragana letter te
33 "\xe3\x81\xa8", // hiragana letter to
34 "\xe3\x81\xaa", // hiragana letter na
35 "\xe3\x81\xab", // hiragana letter ni
36 "\xe3\x81\xac", // hiragana letter nu
37 "\xe3\x81\xad", // hiragana letter ne
38 "\xe3\x81\xae", // hiragana letter no
39 "\xe3\x81\xaf", // hiragana letter ha
40 "\xe3\x81\xb2", // hiragana letter hi
41 "\xe3\x81\xb5", // hiragana letter hu
42 "\xe3\x81\xb8", // hiragana letter he
43 "\xe3\x81\xbb", // hiragana letter ho
44 "\xe3\x81\xbe", // hiragana letter ma
45 "\xe3\x81\xbf", // hiragana letter mi
46 "\xe3\x82\x80", // hiragana letter mu
47 "\xe3\x82\x81", // hiragana letter me
48 "\xe3\x82\x82", // hiragana letter mo
49 "\xe3\x82\x84", // hiragana letter ya
50 "\xe3\x82\x86", // hiragana letter yu
51 "\xe3\x82\x88", // hiragana letter yo
52 "\xe3\x82\x89", // hiragana letter ra
53 "\xe3\x82\x8a", // hiragana letter ri
54 "\xe3\x82\x8b", // hiragana letter ru
55 "\xe3\x82\x8c", // hiragana letter re
56 "\xe3\x82\x8d", // hiragana letter ro
57 "\xe3\x82\x8f", // hiragana letter wa
58 "\xe3\x82\x92", // hiragana letter wo
59 "\xe3\x82\x93", // hiragana letter n
60 "\xe3\x81\x81", // hiragana letter small a
61 "\xe3\x81\x83", // hiragana letter small i
62 "\xe3\x81\x85", // hiragana letter small u
63 "\xe3\x81\x87", // hiragana letter small e
64 "\xe3\x81\x89", // hiragana letter small o
65 "\xe3\x82\x83", // hiragana letter small ya
66 "\xe3\x82\x85", // hiragana letter small yu
67 "\xe3\x82\x87", // hiragana letter small yo
68 "\xe3\x81\x8c", // hiragana letter ga
69 "\xe3\x81\x8e", // hiragana letter gi
70 "\xe3\x81\x90", // hiragana letter gu
71 "\xe3\x81\x92", // hiragana letter ge
72 "\xe3\x81\x94", // hiragana letter go
73 "\xe3\x81\x96", // hiragana letter za
74 "\xe3\x81\x98", // hiragana letter zi
75 "\xe3\x81\x9a", // hiragana letter zu
76 "\xe3\x81\x9c", // hiragana letter ze
77 "\xe3\x81\x9e", // hiragana letter zo
78 "\xe3\x81\xa0", // hiragana letter da
79 "\xe3\x81\xa2", // hiragana letter di
80 "\xe3\x81\xa5", // hiragana letter du
81 "\xe3\x81\xa7", // hiragana letter de
82 "\xe3\x81\xa9", // hiragana letter do
83 "\xe3\x81\xb0", // hiragana letter ba
84 "\xe3\x81\xb3", // hiragana letter bi
85 "\xe3\x81\xb6", // hiragana letter bu
86 "\xe3\x81\xb9", // hiragana letter be
87 "\xe3\x81\xbc", // hiragana letter bo
88 "\xe3\x81\xb1", // hiragana letter pa
89 "\xe3\x81\xb4", // hiragana letter pi
90 "\xe3\x81\xb7", // hiragana letter pu
91 "\xe3\x81\xba", // hiragana letter pe
92 "\xe3\x81\xbd", // hiragana letter po
93 "\xe3\x81\xa3", // hiragana letter small tu
94 "\xe3\x82\xa2", // katakana letter a
95 "\xe3\x82\xa4", // katakana letter i
96 "\xe3\x82\xa6", // katakana letter u
97 "\xe3\x82\xa8", // katakana letter e
98 "\xe3\x82\xaa", // katakana letter o
99 "\xe3\x82\xab", // katakana letter ka
100 "\xe3\x82\xad", // katakana letter ki
101 "\xe3\x82\xaf", // katakana letter ku
102 "\xe3\x82\xb1", // katakana letter ke
103 "\xe3\x82\xb3", // katakana letter ko
104 "\xe3\x82\xb5", // katakana letter sa
105 "\xe3\x82\xb7", // katakana letter si
106 "\xe3\x82\xb9", // katakana letter su
107 "\xe3\x82\xbb", // katakana letter se
108 "\xe3\x82\xbd", // katakana letter so
109 "\xe3\x82\xbf", // katakana letter ta
110 "\xe3\x83\x81", // katakana letter ti
111 "\xe3\x83\x84", // katakana letter tu
112 "\xe3\x83\x86", // katakana letter te
113 "\xe3\x83\x88", // katakana letter to
114 "\xe3\x83\x8a", // katakana letter na
115 "\xe3\x83\x8b", // katakana letter ni
116 "\xe3\x83\x8c", // katakana letter nu
117 "\xe3\x83\x8d", // katakana letter ne
118 "\xe3\x83\x8e", // katakana letter no
119 "\xe3\x83\x8f", // katakana letter ha
120 "\xe3\x83\x92", // katakana letter hi
121 "\xe3\x83\x95", // katakana letter hu
122 "\xe3\x83\x98", // katakana letter he
123 "\xe3\x83\x9b", // katakana letter ho
124 "\xe3\x83\x9e", // katakana letter ma
125 "\xe3\x83\x9f", // katakana letter mi
126 "\xe3\x83\xa0", // katakana letter mu
127 "\xe3\x83\xa1", // katakana letter me
128 "\xe3\x83\xa2", // katakana letter mo
129 "\xe3\x83\xa4", // katakana letter ya
130 "\xe3\x83\xa6", // katakana letter yu
131 "\xe3\x83\xa8", // katakana letter yo
132 "\xe3\x83\xa9", // katakana letter ra
133 "\xe3\x83\xaa", // katakana letter ri
134 "\xe3\x83\xab", // katakana letter ru
135 "\xe3\x83\xac", // katakana letter re
136 "\xe3\x83\xad", // katakana letter ro
137 "\xe3\x83\xaf", // katakana letter wa
138 "\xe3\x83\xb2", // katakana letter wo
139 "\xe3\x83\xb3", // katakana letter n
140 "\xe3\x82\xa1", // katakana letter small a
141 "\xe3\x82\xa3", // katakana letter small i
142 "\xe3\x82\xa5", // katakana letter small u
143 "\xe3\x82\xa7", // katakana letter small e
144 "\xe3\x82\xa9", // katakana letter small o
145 "\xe3\x83\xa3", // katakana letter small ya
146 "\xe3\x83\xa5", // katakana letter small yu
147 "\xe3\x83\xa7", // katakana letter small yo
148 "\xe3\x82\xac", // katakana letter ga
149 "\xe3\x82\xae", // katakana letter gi
150 "\xe3\x82\xb0", // katakana letter gu
151 "\xe3\x82\xb2", // katakana letter ge
152 "\xe3\x82\xb4", // katakana letter go
153 "\xe3\x82\xb6", // katakana letter za
154 "\xe3\x82\xb8", // katakana letter zi
155 "\xe3\x82\xba", // katakana letter zu
156 "\xe3\x82\xbc", // katakana letter ze
157 "\xe3\x82\xbe", // katakana letter zo
158 "\xe3\x83\x80", // katakana letter da
159 "\xe3\x83\x82", // katakana letter di
160 "\xe3\x83\x85", // katakana letter du
161 "\xe3\x83\x87", // katakana letter de
162 "\xe3\x83\x89", // katakana letter do
163 "\xe3\x83\x90", // katakana letter ba
164 "\xe3\x83\x93", // katakana letter bi
165 "\xe3\x83\x96", // katakana letter bu
166 "\xe3\x83\x99", // katakana letter be
167 "\xe3\x83\x9c", // katakana letter bo
168 "\xe3\x83\x91", // katakana letter pa
169 "\xe3\x83\x94", // katakana letter pi
170 "\xe3\x83\x97", // katakana letter pu
171 "\xe3\x83\x9a", // katakana letter pe
172 "\xe3\x83\x9d", // katakana letter po
173 "\xe3\x83\x83", // katakana letter small tu
174 "0", // arabic numeral zero
175 "1", // arabic numeral one
176 "2", // arabic numeral two
177 "3", // arabic numeral three
178 "4", // arabic numeral four
179 "5", // arabic numeral five
180 "6", // arabic numeral six
181 "7", // arabic numeral seven
182 "8", // arabic numeral eight
183 "9", // arabic numeral nine
184 0, // exclamation mark [varies]
185 0, // question mark [varies]
186 0, // period [varies]
187 0, // hyphen [varies]
188 "\xe3\x83\xbb", // interpunct
189 "\xe2\x80\xa6", // ellipsis
190 0, // left double quotation mark [varies]
191 0, // right double quotation mark [varies]
192 0, // left single quotation mark [varies]
193 0, // right single quotation mark [varies]
194 "\xe2\x99\x82", // mars astrological sign
195 "\xe2\x99\x80", // venus astrological sign
196 0, // unused
197 ",", // comma
198 0, // unused
199 "/", // forward slash
200 "A", // uppercase latin letter a
201 "B", // uppercase latin letter b
202 "C", // uppercase latin letter c
203 "D", // uppercase latin letter d
204 "E", // uppercase latin letter e
205 "F", // uppercase latin letter f
206 "G", // uppercase latin letter g
207 "H", // uppercase latin letter h
208 "I", // uppercase latin letter i
209 "J", // uppercase latin letter j
210 "K", // uppercase latin letter k
211 "L", // uppercase latin letter l
212 "M", // uppercase latin letter m
213 "N", // uppercase latin letter n
214 "O", // uppercase latin letter o
215 "P", // uppercase latin letter p
216 "Q", // uppercase latin letter q
217 "R", // uppercase latin letter r
218 "S", // uppercase latin letter s
219 "T", // uppercase latin letter t
220 "U", // uppercase latin letter u
221 "V", // uppercase latin letter v
222 "W", // uppercase latin letter w
223 "X", // uppercase latin letter x
224 "Y", // uppercase latin letter y
225 "Z", // uppercase latin letter z
226 "a", // lowercase latin letter a
227 "b", // lowercase latin letter b
228 "c", // lowercase latin letter c
229 "d", // lowercase latin letter d
230 "e", // lowercase latin letter e
231 "f", // lowercase latin letter f
232 "g", // lowercase latin letter g
233 "h", // lowercase latin letter h
234 "i", // lowercase latin letter i
235 "j", // lowercase latin letter j
236 "k", // lowercase latin letter k
237 "l", // lowercase latin letter l
238 "m", // lowercase latin letter m
239 "n", // lowercase latin letter n
240 "o", // lowercase latin letter o
241 "p", // lowercase latin letter p
242 "q", // lowercase latin letter q
243 "r", // lowercase latin letter r
244 "s", // lowercase latin letter s
245 "t", // lowercase latin letter t
246 "u", // lowercase latin letter u
247 "v", // lowercase latin letter v
248 "w", // lowercase latin letter w
249 "x", // lowercase latin letter x
250 "y", // lowercase latin letter y
251 "z", // lowercase latin letter z
252 0, // unused
253 0, // unused
254 "\xc3\x84", // uppercase latin letter a with diaeresis
255 "\xc3\x96", // uppercase latin letter o with diaeresis
256 "\xc3\x9c", // uppercase latin letter u with diaeresis
257 "\xc3\xa4", // lowercase latin letter a with diaeresis
258 "\xc3\xb6", // lowercase latin letter o with diaeresis
259 "\xc3\xbc" // lowercase latin letter u with diaeresis
18}; 260};
19 261
20char debugGen3Decode(u8 val) 262/**
263 * Converts a string encoded with the propietary gen 3 character encoding into
264 * a UTF-8 encoded string. The function will read the input buffer until either
265 * the max length has been reached, or an 0xFF has been found. The output buffer
266 * must be at least one plus three times the max length in size.
267 */
268void decodePokemonCharset(
269 const u8* input,
270 int maxLength,
271 char* output,
272 enum PokemonLanguage language)
21{ 273{
22 return charmap[val - 0xA0]; 274 for (int i=0; i<maxLength; i++)
275 {
276 char cur = *input;
277 input++;
278
279 if (cur == 0xff)
280 {
281 break;
282 }
283
284 const char* next = 0;
285
286 if (cur == 0xab)
287 {
288 // fullwidth exclamation mark
289 if (language == Japanese)
290 {
291 next = "\xef\xbc\x81";
292 }
293 // exclamation mark
294 else {
295 next = "!";
296 }
297 } else if (cur == 0xac)
298 {
299 // fullwidth question mark
300 if (language == Japanese)
301 {
302 next = "\xef\xbc\x9f";
303 }
304 // question mark
305 else {
306 next = "?";
307 }
308 } else if (cur == 0xad)
309 {
310 // ideographic full stop
311 if (language == Japanese)
312 {
313 next = "\xe3\x80\x82";
314 }
315 // period
316 else {
317 next = ".";
318 }
319 } else if (cur == 0xae)
320 {
321 // katakana-hiragana prolonged sound mark
322 if (language == Japanese)
323 {
324 next = "\xe3\x83\xbc";
325 }
326 // hyphen
327 else {
328 next = "-";
329 }
330 } else if (cur == 0xb1)
331 {
332 // left white corner bracket
333 if (language == Japanese)
334 {
335 next = "\xe3\x80\x83";
336 }
337 // double low-9 quotation mark
338 else if (language == German)
339 {
340 next = "\xe2\x80\x9e";
341 }
342 // left double angle quotation mark
343 else if (language == French)
344 {
345 next = "\xc2\xab";
346 }
347 // left double quotation mark
348 else {
349 next = "\xe2\x80\x9c";
350 }
351 } else if (cur == 0xb2)
352 {
353 // right white corner bracket
354 if (language == Japanese)
355 {
356 next = "\xe3\x80\x8f";
357 }
358 // left double quotation mark
359 else if (language == German)
360 {
361 next = "\xe2\x80\x9c";
362 }
363 // right double angle quotation mark
364 else if (language == French)
365 {
366 next = "\xc2\xbb";
367 }
368 // right double quotation mark
369 else {
370 next = "\xe2\x80\x9d";
371 }
372 } else if (cur == 0xb3)
373 {
374 // left corner bracket
375 if (language == Japanese)
376 {
377 next = "\xe3\x80\x8c";
378 }
379 // left single quotation mark
380 else {
381 next = "\xe2\x80\x98";
382 }
383 } else if (cur == 0xb4)
384 {
385 // right corner bracket
386 if (language == Japanese)
387 {
388 next = "\xe3\x80\x8d";
389 }
390 // right single quotation mark
391 else {
392 next = "\xe2\x80\x99";
393 }
394 } else {
395 next = charmap[(int)cur];
396 }
397
398 for (; *next != 0; next++)
399 {
400 *output++ = *next;
401 }
402 }
403
404 *output = 0;
23} 405}
diff --git a/source/encoding.h b/source/encoding.h index 4dc3b1f..0cf6165 100644 --- a/source/encoding.h +++ b/source/encoding.h
@@ -8,7 +8,12 @@
8#define ENCODING_H_95547384 8#define ENCODING_H_95547384
9 9
10#include <gccore.h> 10#include <gccore.h>
11#include "pokemon.h"
11 12
12char debugGen3Decode(u8 val); 13void decodePokemonCharset(
14 const u8* input,
15 int maxLength,
16 char* output,
17 enum PokemonLanguage language);
13 18
14#endif /* end of include guard: ENCODING_H_95547384 */ 19#endif /* end of include guard: ENCODING_H_95547384 */
diff --git a/source/link.c b/source/link.c index 27837f8..c627039 100644 --- a/source/link.c +++ b/source/link.c
@@ -12,7 +12,7 @@
12 12
13//from my tests 50us seems to be the lowest 13//from my tests 50us seems to be the lowest
14//safe si transfer delay in between calls 14//safe si transfer delay in between calls
15#define SI_TRANS_DELAY 50 15#define SI_TRANS_DELAY 500
16 16
17static u8* resbuf; 17static u8* resbuf;
18static u8* cmdbuf; 18static u8* cmdbuf;
@@ -61,7 +61,7 @@ u32 recv()
61 SI_Transfer(1, cmdbuf, 1, resbuf, 5, transcb, SI_TRANS_DELAY); 61 SI_Transfer(1, cmdbuf, 1, resbuf, 5, transcb, SI_TRANS_DELAY);
62 62
63 while (transval == 0); 63 while (transval == 0);
64 printf("%08lx\n", *(vu32*)resbuf); 64 //printf("%08lx\n", *(vu32*)resbuf);
65 return *(vu32*)resbuf; 65 return *(vu32*)resbuf;
66} 66}
67 67
@@ -82,14 +82,7 @@ void send(u32 msg)
82 82
83u32 getMsg() 83u32 getMsg()
84{ 84{
85 u32 val = 0; 85 u32 val = __builtin_bswap32(recv());
86 while (val == 0)
87 {
88 val = __builtin_bswap32(recv());
89 }
90
91 send(0);
92 while (recv()!=0);
93 send(0); 86 send(0);
94 87
95 return val; 88 return val;
@@ -105,10 +98,7 @@ void getMsgArr(u32* arr, int len)
105 98
106void sendMsg(u32 msg) 99void sendMsg(u32 msg)
107{ 100{
108 while (recv()==0);
109 send(msg); 101 send(msg);
110 while (recv()!=0);
111 send(0);
112} 102}
113 103
114void waitForGBA() 104void waitForGBA()
@@ -157,5 +147,4 @@ void waitForGame()
157void waitForAck() 147void waitForAck()
158{ 148{
159 while (recv() != 0) {sleep(1);} 149 while (recv() != 0) {sleep(1);}
160 send(0);
161} 150}
diff --git a/source/main.c b/source/main.c index ceb24d5..1355533 100644 --- a/source/main.c +++ b/source/main.c
@@ -10,6 +10,7 @@
10#include <stdio.h> 10#include <stdio.h>
11#include <stdlib.h> 11#include <stdlib.h>
12#include <unistd.h> 12#include <unistd.h>
13#include <string.h>
13#include "link.h" 14#include "link.h"
14#include "encoding.h" 15#include "encoding.h"
15#include "multiboot.h" 16#include "multiboot.h"
@@ -117,6 +118,7 @@ void* extractor(void* userdata)
117 118
118 printf("\n"); 119 printf("\n");
119 VIDEO_WaitVSync(); 120 VIDEO_WaitVSync();
121 sleep(1);
120 122
121 u32 isValid = getMsg(); 123 u32 isValid = getMsg();
122 if (isValid == -1) 124 if (isValid == -1)
@@ -144,19 +146,13 @@ void* extractor(void* userdata)
144 // Get trainer ID 146 // Get trainer ID
145 u32 trainerId = getMsg(); 147 u32 trainerId = getMsg();
146 148
147 printf("Trainer: "); 149 // Get game language.
150 enum PokemonLanguage gameLanguage = getMsg();
148 151
149 for (int i = 0; i < 8; i++) 152 char d_trainerName[25];
150 { 153 decodePokemonCharset(trainerName, 8, d_trainerName, gameLanguage);
151 if (trainerName[i] == 0xFF)
152 {
153 break;
154 } else {
155 printf("%c", debugGen3Decode(trainerName[i]));
156 }
157 }
158 154
159 printf(" (%ld)\n", trainerId); 155 printf("Trainer: %s (%ld)\n", d_trainerName, trainerId);
160 156
161 // Wait for confirmation. 157 // Wait for confirmation.
162 printf("Press A to import the data from this game.\n"); 158 printf("Press A to import the data from this game.\n");
@@ -219,34 +215,15 @@ void* extractor(void* userdata)
219 215
220 struct PokemonIntermediate* pki = (struct PokemonIntermediate*)(&rawdata); 216 struct PokemonIntermediate* pki = (struct PokemonIntermediate*)(&rawdata);
221 217
222 printf("Species: %d\n", __builtin_bswap16(pki->species)); 218 char d_pokename[31];
223 219 decodePokemonCharset(pki->nickname, 10, d_pokename, pki->language);
224 u8* pokename = pki->nickname;
225 printf("Nickname: ");
226
227 for (int i = 0; i < 10; i++)
228 {
229 if (pokename[i] == 0xFF)
230 {
231 break;
232 } else {
233 printf("%c", debugGen3Decode(pokename[i]));
234 }
235 }
236 220
237 printf("\nOT: "); 221 char d_otName[22];
222 decodePokemonCharset(pki->otName, 7, d_otName, pki->language);
238 223
239 for (int i=0; i<7; i++) 224 printf("Species: %d\n", __builtin_bswap16(pki->species));
240 { 225 printf("Nickname: %s\n", d_pokename);
241 if (pki->otName[i] == 0xFF) 226 printf("OT: %s\n", d_otName);
242 {
243 break;
244 } else {
245 printf("%c", debugGen3Decode(pki->otName[i]));
246 }
247 }
248
249 printf("\n");
250 printf("Level: %d\n", pki->level); 227 printf("Level: %d\n", pki->level);
251 printf("HP: %ld\n", __builtin_bswap32(pki->hp)); 228 printf("HP: %ld\n", __builtin_bswap32(pki->hp));
252 printf("Attack: %ld\n", __builtin_bswap32(pki->attack)); 229 printf("Attack: %ld\n", __builtin_bswap32(pki->attack));