about summary refs log tree commit diff stats
path: root/gba/source
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-07-11 18:14:18 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-07-11 18:14:18 -0400
commitec66a022a8879a5300f2ae64cd86a5d8cfbd1a36 (patch)
tree06e096126cf673be5cfd9dd1ff164c8d46520de9 /gba/source
parent57afb4058710a978bd7b07a368125d04378c62f1 (diff)
downloadgen3uploader-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/source')
-rw-r--r--gba/source/gamedata.c2
-rw-r--r--gba/source/main.c64
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