about summary refs log tree commit diff stats
path: root/gba/source/main.c
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-08-18 13:49:00 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-08-18 13:49:00 -0400
commit08dfb0aa80668b80c4a31bd064f5f2d729e5b7f6 (patch)
treeb46baa9353c0919efaed4349d2207958fa0bfaf5 /gba/source/main.c
parenta19507262602fa31f9f14a9e4f4e03e375bca111 (diff)
downloadgen3uploader-08dfb0aa80668b80c4a31bd064f5f2d729e5b7f6.tar.gz
gen3uploader-08dfb0aa80668b80c4a31bd064f5f2d729e5b7f6.tar.bz2
gen3uploader-08dfb0aa80668b80c4a31bd064f5f2d729e5b7f6.zip
Started working on serializing pokemon data
The GBA program now sends serialized data about the first pokemon in the
player's party over to the Wii. This data doesn't yet include all of the
information that we will eventually want. It does, however, not transfer
any private data, specifically IVs, EVs, and the personality value. It
does this by deriving the public information (stats, nature, gender,
shiny) before sending the pokemon over. Because of this, lookup tables
for things such as base stats were needed, and given that these are
large tables, it was easier to use the tables already existent in the
game's ROM. Thus, the addresses of the three lookup tables that are now
used are necessary for each ROM that this tool supports.

I derived the addresses for version 1 of English Pokemon LeafGreen by dumping
my own copy and searching through it with a text editor. Thus, at the current
time, that cartridge is the only one that is supported. I will supplement this
soon with addresses for the other four gen 3 carts that I have, but that will
still not provide a very large amount of coverage. I have not yet decided how
to address this issue.

There is one current bug with the serialized data: the Wii doesn't seem
to see the original trainer ID. Will fix.
Diffstat (limited to 'gba/source/main.c')
-rw-r--r--gba/source/main.c86
1 files changed, 60 insertions, 26 deletions
diff --git a/gba/source/main.c b/gba/source/main.c index 14d2f1d..aeb05af 100644 --- a/gba/source/main.c +++ b/gba/source/main.c
@@ -7,6 +7,7 @@
7#include <gba.h> 7#include <gba.h>
8#include "gamedata.h" 8#include "gamedata.h"
9#include "link.h" 9#include "link.h"
10#include "serialize.h"
10 11
11int main(void) 12int main(void)
12{ 13{
@@ -42,11 +43,9 @@ int main(void)
42 waitForAck(); 43 waitForAck();
43 44
44 // Get access to save data. 45 // Get access to save data.
45 pSaveBlock1 SaveBlock1; 46 struct GameData gameData;
46 pSaveBlock2 SaveBlock2;
47 pSaveBlock3 SaveBlock3;
48 47
49 if (!initSaveData(&SaveBlock1, &SaveBlock2, &SaveBlock3)) 48 if (!initSaveData(&gameData))
50 { 49 {
51 // Unsupported game version. 50 // Unsupported game version.
52 sendS32(-1); 51 sendS32(-1);
@@ -63,13 +62,13 @@ int main(void)
63 62
64 if (GAME_RS) 63 if (GAME_RS)
65 { 64 {
66 trainerName = SaveBlock2->rs.playerName; 65 trainerName = gameData.SaveBlock2->rs.playerName;
67 } else if (GAME_FRLG) 66 } else if (GAME_FRLG)
68 { 67 {
69 trainerName = SaveBlock2->frlg.playerName; 68 trainerName = gameData.SaveBlock2->frlg.playerName;
70 } else if (GAME_EM) 69 } else if (GAME_EM)
71 { 70 {
72 trainerName = SaveBlock2->e.playerName; 71 trainerName = gameData.SaveBlock2->e.playerName;
73 } 72 }
74 73
75 u32 tn1 = 74 u32 tn1 =
@@ -94,20 +93,24 @@ int main(void)
94 u8* trainerId = 0; 93 u8* trainerId = 0;
95 if (GAME_RS) 94 if (GAME_RS)
96 { 95 {
97 trainerId = SaveBlock2->rs.playerTrainerId; 96 trainerId = gameData.SaveBlock2->rs.playerTrainerId;
98 } else if (GAME_FRLG) 97 } else if (GAME_FRLG)
99 { 98 {
100 trainerId = SaveBlock2->frlg.playerTrainerId; 99 trainerId = gameData.SaveBlock2->frlg.playerTrainerId;
101 } else if (GAME_EM) 100 } else if (GAME_EM)
102 { 101 {
103 trainerId = SaveBlock2->e.playerTrainerId; 102 trainerId = gameData.SaveBlock2->e.playerTrainerId;
104 } 103 }
105 104
106 u32 tti = 105 u16 trainerIdNum =
107 (trainerId[1] << 8) 106 (trainerId[1] << 8)
108 | (trainerId[0]); 107 | (trainerId[0]);
109 108
110 sendU32(tti); 109 u16 secretIdNum =
110 (trainerId[3] << 8)
111 | (trainerId[2]);
112
113 sendU32(trainerIdNum);
111 waitForAck(); 114 waitForAck();
112 115
113 // Does the player want to import this game? 116 // Does the player want to import this game?
@@ -120,22 +123,22 @@ int main(void)
120 u8* pokedexSeen = 0; 123 u8* pokedexSeen = 0;
121 if (GAME_RS) 124 if (GAME_RS)
122 { 125 {
123 pokedexSeen = SaveBlock2->rs.pokedex.seen; 126 pokedexSeen = gameData.SaveBlock2->rs.pokedex.seen;
124 } else if (GAME_FRLG) 127 } else if (GAME_FRLG)
125 { 128 {
126 pokedexSeen = SaveBlock2->frlg.pokedex.seen; 129 pokedexSeen = gameData.SaveBlock2->frlg.pokedex.seen;
127 } else if (GAME_EM) 130 } else if (GAME_EM)
128 { 131 {
129 pokedexSeen = SaveBlock2->e.pokedex.seen; 132 pokedexSeen = gameData.SaveBlock2->e.pokedex.seen;
130 } 133 }
131 134
132 for (int i=0; i<13; i++) 135 for (int i=0; i<13; i++)
133 { 136 {
134 u32 psi = 137 u32 psi =
135 (pokedexSeen[i*4]) 138 (pokedexSeen[i*4] << 24)
136 | (pokedexSeen[i*4+1] << 8) 139 | (pokedexSeen[i*4+1] << 16)
137 | (pokedexSeen[i*4+2] << 16) 140 | (pokedexSeen[i*4+2] << 8)
138 | (pokedexSeen[i*4+3] << 24); 141 | (pokedexSeen[i*4+3]);
139 142
140 directSendU32(psi); 143 directSendU32(psi);
141 } 144 }
@@ -143,23 +146,54 @@ int main(void)
143 u8* pokedexCaught = 0; 146 u8* pokedexCaught = 0;
144 if (GAME_RS) 147 if (GAME_RS)
145 { 148 {
146 pokedexCaught = SaveBlock2->rs.pokedex.owned; 149 pokedexCaught = gameData.SaveBlock2->rs.pokedex.owned;
147 } else if (GAME_FRLG) 150 } else if (GAME_FRLG)
148 { 151 {
149 pokedexCaught = SaveBlock2->frlg.pokedex.owned; 152 pokedexCaught = gameData.SaveBlock2->frlg.pokedex.owned;
150 } else if (GAME_EM) 153 } else if (GAME_EM)
151 { 154 {
152 pokedexCaught = SaveBlock2->e.pokedex.owned; 155 pokedexCaught = gameData.SaveBlock2->e.pokedex.owned;
153 } 156 }
154 157
155 for (int i=0; i<13; i++) 158 for (int i=0; i<13; i++)
156 { 159 {
157 u32 psi = 160 u32 psi =
158 (pokedexCaught[i*4]) 161 (pokedexCaught[i*4] << 24)
159 | (pokedexCaught[i*4+1] << 8) 162 | (pokedexCaught[i*4+1] << 16)
160 | (pokedexCaught[i*4+2] << 16) 163 | (pokedexCaught[i*4+2] << 8)
161 | (pokedexCaught[i*4+3] << 24); 164 | (pokedexCaught[i*4+3]);
162 165
163 directSendU32(psi); 166 directSendU32(psi);
164 } 167 }
168
169 // Start sending over party pokémon.
170 struct Pokemon* playerParty = 0;
171 if (GAME_RS)
172 {
173 playerParty = gameData.SaveBlock1->rs.playerParty;
174 } else if (GAME_FRLG)
175 {
176 playerParty = gameData.SaveBlock1->frlg.playerParty;
177 } else if (GAME_EM)
178 {
179 playerParty = gameData.SaveBlock1->e.playerParty;
180 }
181
182 waitForResponse();
183
184 u32 partyCount = 1;
185
186 sendU32(partyCount);
187 waitForAck();
188
189 for (int pki=0; pki<partyCount; pki++)
190 {
191 struct Pokemon* pkm = (playerParty + pki);
192 struct BoxPokemon* bpkm = &(pkm->box);
193
194 struct PokemonIntermediate pki;
195
196 PokemonIntermediateInit(&pki, bpkm, trainerIdNum, secretIdNum, &gameData);
197 PokemonIntermediateStream(&pki);
198 }
165} 199}