diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-08-18 13:49:00 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-08-18 13:49:00 -0400 |
commit | 08dfb0aa80668b80c4a31bd064f5f2d729e5b7f6 (patch) | |
tree | b46baa9353c0919efaed4349d2207958fa0bfaf5 /gba/source/main.c | |
parent | a19507262602fa31f9f14a9e4f4e03e375bca111 (diff) | |
download | gen3uploader-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.c | 86 |
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 | ||
11 | int main(void) | 12 | int 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 | } |