about summary refs log tree commit diff stats
path: root/gba/source
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 /gba/source
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.
Diffstat (limited to 'gba/source')
-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
4 files changed, 23 insertions, 24 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