diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-07-11 18:14:18 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-07-11 18:14:18 -0400 |
commit | ec66a022a8879a5300f2ae64cd86a5d8cfbd1a36 (patch) | |
tree | 06e096126cf673be5cfd9dd1ff164c8d46520de9 /gba | |
parent | 57afb4058710a978bd7b07a368125d04378c62f1 (diff) | |
download | gen3uploader-ec66a022a8879a5300f2ae64cd86a5d8cfbd1a36.tar.gz gen3uploader-ec66a022a8879a5300f2ae64cd86a5d8cfbd1a36.tar.bz2 gen3uploader-ec66a022a8879a5300f2ae64cd86a5d8cfbd1a36.zip |
Things are semi-reliably working now!
A good portion of the time, the Wii will display: Pokemon LeafGreen Trainer: Starla (34182) which is the correct data on the cartridge I am testing with. Most of the GBA changes are within comments and are unimportant. I did uncomment the portion where it sends over the trainer's name, and I fixed how it reads the trainer ID from memory. The Wii changes involve properly cooperating in the message sending protocol I'm having the GBA and Wii use. More description regarding protocol: I'm not super familiar with the JOY BUS protocol because it's undocumented, but there seems to be this issue where the Wii reads the same value multiple times from the cable, and since the cable is used to negotiate the multiboot image, I need to make sure that the Wii and GBA are on the same page. Since the last message that the GBA sends is nonzero, I have the GBA image start by sending a zero and waiting for a response, and I have the Wii wait for a zero. The Wii then sends a zero in response to the GBA. From then on, the message sending protocol works like so: Wii: waits for non-zero value GBA: sends non-zero value, waits for any response Wii: reads message, sends 0 response, waits for 0 response GBA: receives response, sends 0 response, waits for any response Wii: reads 0, continues on with program The reason for this is to prevent incorrect communication caused by the Wii reading the same value from the GBA multiple times by essentially delimiting the message. This is currently pretty slow because I have debugging messages and sleeps everywhere. I will clean this code up, but this project is slightly dark magic right now and I wanted to commit something that worked in the slightest. Also added a debug function that transcodes from the proprietary gen 3 encoding to ASCII in the domain of characters that can actually be used in names (except for the 6 special German ones). Thanks to Bulbapedia (https://bulbapedia.bulbagarden.net/wiki/Character_encoding_in_Generation_III) for this. It's used for now to display the Trainer name on the console. It assumes that the cartridge is non-Japanese; this will be addressed. I'm not currently planning on transcoding names before transmitting them, because of the fact that there are characters in the character set that are not present in any other character set, and thus transcoding them spuriously (like PK -> P,K) is a loss of data. However, it is true that no such characters exist in the set of characters that can be used for names (in either the Japanese or non-Japanese encoding), so I may later decide to transcode to Unicode on the Wii before transmitting.
Diffstat (limited to 'gba')
-rw-r--r-- | gba/source/gamedata.c | 2 | ||||
-rw-r--r-- | gba/source/main.c | 64 |
2 files changed, 42 insertions, 24 deletions
diff --git a/gba/source/gamedata.c b/gba/source/gamedata.c index 19d5100..8e63232 100644 --- a/gba/source/gamedata.c +++ b/gba/source/gamedata.c | |||
@@ -493,7 +493,7 @@ bool initSaveData( | |||
493 | } | 493 | } |
494 | 494 | ||
495 | loadsave(0); | 495 | loadsave(0); |
496 | 496 | // sendS32(-1); | |
497 | // now the save is loaded, we can do what we want with the loaded blocks. | 497 | // now the save is loaded, we can do what we want with the loaded blocks. |
498 | // first, we're going to want to decrypt the parts that are crypted, if applicable. | 498 | // first, we're going to want to decrypt the parts that are crypted, if applicable. |
499 | decryptSaveStructures(gSaveBlock1,gSaveBlock2,gSaveBlock3); | 499 | decryptSaveStructures(gSaveBlock1,gSaveBlock2,gSaveBlock3); |
diff --git a/gba/source/main.c b/gba/source/main.c index 104866a..94d4c2b 100644 --- a/gba/source/main.c +++ b/gba/source/main.c | |||
@@ -96,31 +96,53 @@ int main(void) | |||
96 | m3_fill(RGB15(31,31,31)); | 96 | m3_fill(RGB15(31,31,31)); |
97 | plot_sqr( 4, 4, RGB15(31, 0, 0) ); // or CLR_RED | 97 | plot_sqr( 4, 4, RGB15(31, 0, 0) ); // or CLR_RED |
98 | 98 | ||
99 | 99 | /* | |
100 | 100 | ||
101 | //*(vu16 *)(REG_BASE + 0x84) = 0x8f; | 101 | //*(vu16 *)(REG_BASE + 0x84) = 0x8f; |
102 | //REG_IME = 1; | 102 | //REG_IME = 1; |
103 | // the vblank interrupt must be enabled for VBlankIntrWait() to work | 103 | // the vblank interrupt must be enabled for VBlankIntrWait() to work |
104 | // since the default dispatcher handles the bios flags no vblank handler | 104 | // since the default dispatcher handles the bios flags no vblank handler |
105 | // is required | 105 | // is required |
106 | //irqInit(); | 106 | irqInit(); |
107 | //irqEnable(IRQ_VBLANK); | 107 | irqEnable(IRQ_VBLANK); |
108 | 108 | ||
109 | //consoleDemoInit(); | 109 | consoleDemoInit(); |
110 | //REG_JOYTR = 0; | 110 | //REG_JOYTR = 0; |
111 | 111 | ||
112 | // ansi escape sequence to set print co-ordinates | 112 | // ansi escape sequence to set print co-ordinates |
113 | // /x1b[line;columnH | 113 | // /x1b[line;columnH |
114 | //u32 i; | 114 | //u32 i; |
115 | //iprintf("\x1b[9;2HPokemon Gen III Data Extractor\n"); | 115 | iprintf("\x1b[9;2HPokemon Gen III Data Extractor\n"); |
116 | //iprintf("\x1b[10;4HPlease look at the TV\n"); | 116 | iprintf("\x1b[10;4HPlease look at the TV\n"); |
117 | 117 | ||
118 | // disable this, needs power | 118 | // disable this, needs power |
119 | //SNDSTAT = 0; | 119 | SNDSTAT = 0; |
120 | //SNDBIAS = 0; | 120 | SNDBIAS = 0; |
121 | 121 | ||
122 | // Set up waitstates for EEPROM access etc. | 122 | // Set up waitstates for EEPROM access etc. |
123 | //REG_WAITCNT = 0x0317; | 123 | REG_WAITCNT = 0x0317; |
124 | |||
125 | s32 gamesize = getGameSize(); | ||
126 | u32 savesize = SaveSize(save_data,gamesize); | ||
127 | switch (savesize){ | ||
128 | case 0x200: | ||
129 | GetSave_EEPROM_512B(save_data); | ||
130 | break; | ||
131 | case 0x2000: | ||
132 | GetSave_EEPROM_8KB(save_data); | ||
133 | break; | ||
134 | case 0x8000: | ||
135 | GetSave_SRAM_32KB(save_data); | ||
136 | break; | ||
137 | case 0x10000: | ||
138 | GetSave_FLASH_64KB(save_data); | ||
139 | break; | ||
140 | case 0x20000: | ||
141 | GetSave_FLASH_128KB(save_data); | ||
142 | break; | ||
143 | default: | ||
144 | break; | ||
145 | }*/ | ||
124 | 146 | ||
125 | //clear out previous messages | 147 | //clear out previous messages |
126 | REG_HS_CTRL |= JOY_RW; | 148 | REG_HS_CTRL |= JOY_RW; |
@@ -172,10 +194,12 @@ int main(void) | |||
172 | plot_sqr( 5, 4, RGB15( 31, 0,31) ); | 194 | plot_sqr( 5, 4, RGB15( 31, 0,31) ); |
173 | waitForAck(); | 195 | waitForAck(); |
174 | plot_sqr( 5, 5, RGB15( 16, 16,16) ); | 196 | plot_sqr( 5, 5, RGB15( 16, 16,16) ); |
197 | |||
175 | // Get access to save data. | 198 | // Get access to save data. |
176 | pSaveBlock1 SaveBlock1; | 199 | pSaveBlock1 SaveBlock1; |
177 | pSaveBlock2 SaveBlock2; | 200 | pSaveBlock2 SaveBlock2; |
178 | pSaveBlock3 SaveBlock3; | 201 | pSaveBlock3 SaveBlock3; |
202 | //iprintf("gonna check thing\n"); | ||
179 | if (!initSaveData(&SaveBlock1, &SaveBlock2, &SaveBlock3)) | 203 | if (!initSaveData(&SaveBlock1, &SaveBlock2, &SaveBlock3)) |
180 | { | 204 | { |
181 | // Unsupported game version. | 205 | // Unsupported game version. |
@@ -187,12 +211,13 @@ int main(void) | |||
187 | 211 | ||
188 | continue; | 212 | continue; |
189 | } | 213 | } |
214 | //iprintf("success\n"); | ||
190 | plot_sqr( 5, 6, RGB15( 0, 31,16) ); | 215 | plot_sqr( 5, 6, RGB15( 0, 31,16) ); |
191 | sendS32(1); | 216 | sendS32(1); |
192 | waitForAck(); | 217 | waitForAck(); |
193 | /* | 218 | |
194 | // Send trainer name. | 219 | // Send trainer name. |
195 | u8* trainerName; | 220 | u8* trainerName = 0; |
196 | 221 | ||
197 | if (GAME_RS) | 222 | if (GAME_RS) |
198 | { | 223 | { |
@@ -204,14 +229,6 @@ int main(void) | |||
204 | { | 229 | { |
205 | trainerName = SaveBlock2->e.playerName; | 230 | trainerName = SaveBlock2->e.playerName; |
206 | } | 231 | } |
207 | iprintf("%d\n", trainerName[0]); | ||
208 | iprintf("%d\n", trainerName[1]); | ||
209 | iprintf("%d\n", trainerName[2]); | ||
210 | iprintf("%d\n", trainerName[3]); | ||
211 | iprintf("%d\n", trainerName[4]); | ||
212 | iprintf("%d\n", trainerName[5]); | ||
213 | iprintf("%d\n", trainerName[6]); | ||
214 | iprintf("%d\n", trainerName[7]); | ||
215 | 232 | ||
216 | u32 tn1 = | 233 | u32 tn1 = |
217 | (trainerName[0] << 24) | 234 | (trainerName[0] << 24) |
@@ -230,10 +247,10 @@ int main(void) | |||
230 | 247 | ||
231 | sendU32(tn2); | 248 | sendU32(tn2); |
232 | waitForAck(); | 249 | waitForAck(); |
233 | */ | 250 | |
234 | // Send trainer ID. | 251 | // Send trainer ID. |
252 | |||
235 | u8* trainerId = 0; | 253 | u8* trainerId = 0; |
236 | |||
237 | if (GAME_RS) | 254 | if (GAME_RS) |
238 | { | 255 | { |
239 | trainerId = SaveBlock2->rs.playerTrainerId; | 256 | trainerId = SaveBlock2->rs.playerTrainerId; |
@@ -246,9 +263,10 @@ int main(void) | |||
246 | } | 263 | } |
247 | 264 | ||
248 | u32 tti = | 265 | u32 tti = |
249 | (trainerId[2] << 8) | 266 | (trainerId[1] << 8) |
250 | | (trainerId[3]); | 267 | | (trainerId[0]); |
251 | 268 | ||
269 | //iprintf("sending trainer id %ld\n", tti); | ||
252 | sendU32(tti); | 270 | sendU32(tti); |
253 | waitForAck(); | 271 | waitForAck(); |
254 | 272 | ||