about summary refs log tree commit diff stats
path: root/source
diff options
context:
space:
mode:
authorFIX94 <fix94.1@gmail.com>2016-04-08 23:10:13 +0200
committerFIX94 <fix94.1@gmail.com>2016-04-08 23:10:13 +0200
commit2fdb5e638e023408697be8950e776e8f8ffd2590 (patch)
treeed9d04ded678e3e8af685221a8409d508455d918 /source
parent95b6910184d576e64ace469b9845b96b5a1d9f2d (diff)
downloadgen3uploader-2fdb5e638e023408697be8950e776e8f8ffd2590.tar.gz
gen3uploader-2fdb5e638e023408697be8950e776e8f8ffd2590.tar.bz2
gen3uploader-2fdb5e638e023408697be8950e776e8f8ffd2590.zip
added experimental save support (only tested with EEPROM)
Diffstat (limited to 'source')
-rw-r--r--source/main.c231
1 files changed, 180 insertions, 51 deletions
diff --git a/source/main.c b/source/main.c index afe3423..ee23263 100644 --- a/source/main.c +++ b/source/main.c
@@ -23,7 +23,8 @@ void printmain()
23{ 23{
24 printf("\x1b[2J"); 24 printf("\x1b[2J");
25 printf("\x1b[37m"); 25 printf("\x1b[37m");
26 printf("GBA Link Cable Dumper v1.0 by FIX94\n"); 26 printf("GBA Link Cable Dumper v1.1 by FIX94\n");
27 printf("Save Support based on SendSave by Chishm\n");
27} 28}
28 29
29u8 *resbuf,*cmdbuf; 30u8 *resbuf,*cmdbuf;
@@ -299,9 +300,17 @@ int main(int argc, char *argv[])
299 { 300 {
300 if(recvsafe() == 0) //ready 301 if(recvsafe() == 0) //ready
301 { 302 {
302 sleep(1); //gba rom prepare 303 printf("Waiting for GBA\n");
303 u32 gbasize = __builtin_bswap32(recvsafe()); 304 VIDEO_WaitVSync();
304 if(gbasize == 0) 305 int gbasize = 0;
306 while(gbasize == 0)
307 gbasize = __builtin_bswap32(recvsafe());
308 sendsafe(0); //got gbasize
309 usleep(5000); //wait for it to set next val
310 u32 savesize = __builtin_bswap32(recvsafe());
311 sendsafe(0); //got savesize
312 usleep(5000); //wait for it to set next val
313 if(gbasize == -1)
305 { 314 {
306 printf("ERROR: No (Valid) GBA Card inserted!\n"); 315 printf("ERROR: No (Valid) GBA Card inserted!\n");
307 VIDEO_WaitVSync(); 316 VIDEO_WaitVSync();
@@ -309,29 +318,36 @@ int main(int argc, char *argv[])
309 sleep(2); 318 sleep(2);
310 continue; 319 continue;
311 } 320 }
321 //get rom header
312 for(i = 0; i < 0xC0; i+=4) 322 for(i = 0; i < 0xC0; i+=4)
313 *(vu32*)(testdump+i) = recvfast(); 323 *(vu32*)(testdump+i) = recvfast();
324 //print out all the info from the game
314 printf("Game Name: %.12s\n",(char*)(testdump+0xA0)); 325 printf("Game Name: %.12s\n",(char*)(testdump+0xA0));
315 printf("Game ID: %.4s\n",(char*)(testdump+0xAC)); 326 printf("Game ID: %.4s\n",(char*)(testdump+0xAC));
316 printf("Company ID: %.2s\n",(char*)(testdump+0xB0)); 327 printf("Company ID: %.2s\n",(char*)(testdump+0xB0));
317 printf("ROM Size: %02.02f MB\n \n",((float)(gbasize/1024))/1024.f); 328 printf("ROM Size: %02.02f MB\n",((float)(gbasize/1024))/1024.f);
329 if(savesize > 0)
330 printf("Save Size: %02.02f KB\n \n",((float)(savesize))/1024.f);
331 else
332 printf("No Save File\n \n");
333 //generate file paths
318 char gamename[64]; 334 char gamename[64];
319 sprintf(gamename,"/dumps/%.12s [%.4s%.2s].gba", 335 sprintf(gamename,"/dumps/%.12s [%.4s%.2s].gba",
320 (char*)(testdump+0xA0),(char*)(testdump+0xAC),(char*)(testdump+0xB0)); 336 (char*)(testdump+0xA0),(char*)(testdump+0xAC),(char*)(testdump+0xB0));
321 FILE *f = fopen(gamename,"rb"); 337 char savename[64];
322 if(f) 338 sprintf(savename,"/dumps/%.12s [%.4s%.2s].sav",
339 (char*)(testdump+0xA0),(char*)(testdump+0xAC),(char*)(testdump+0xB0));
340 //let the user choose the option
341 printf("Press A to dump this game, it will take about %i minutes.\n",gbasize/1024/1024*3/2);
342 printf("Press B if you want to cancel dumping this game.\n");
343 if(savesize > 0)
323 { 344 {
324 fclose(f); 345 printf("Press Y to backup this save file.\n");
325 sendsafe(0); 346 printf("Press X to restore this save file.\n\n");
326 printf("ERROR: Game already dumped! Please insert another game.\n");
327 VIDEO_WaitVSync();
328 VIDEO_WaitVSync();
329 sleep(2);
330 continue;
331 } 347 }
332 printf("Press A to dump this game, it will take about %i minutes.\n",gbasize/1024/1024*3/2); 348 else
333 printf("Press B if you want to cancel dumping this game.\n\n"); 349 printf("\n");
334 int dumping = 0; 350 int command = 0;
335 while(1) 351 while(1)
336 { 352 {
337 PAD_ScanPads(); 353 PAD_ScanPads();
@@ -341,56 +357,169 @@ int main(int argc, char *argv[])
341 endproc(); 357 endproc();
342 else if(btns&PAD_BUTTON_A) 358 else if(btns&PAD_BUTTON_A)
343 { 359 {
344 dumping = 1; 360 command = 1;
345 break; 361 break;
346 } 362 }
347 else if(btns&PAD_BUTTON_B) 363 else if(btns&PAD_BUTTON_B)
348 break; 364 break;
365 else if(savesize > 0)
366 {
367 if(btns&PAD_BUTTON_Y)
368 {
369 command = 2;
370 break;
371 }
372 else if(btns&PAD_BUTTON_X)
373 {
374 command = 3;
375 break;
376 }
377 }
349 } 378 }
350 sendsafe(dumping); 379 if(command == 1)
351 if(dumping == 0)
352 continue;
353 //create base file with size
354 printf("Creating file...\n");
355 int fd = open(gamename, O_WRONLY|O_CREAT);
356 if(fd >= 0)
357 { 380 {
358 ftruncate(fd, gbasize); 381 FILE *f = fopen(gamename,"rb");
359 close(fd); 382 if(f)
383 {
384 fclose(f);
385 command = 0;
386 printf("ERROR: Game already dumped!\n");
387 VIDEO_WaitVSync();
388 sleep(2);
389 }
360 } 390 }
361 f = fopen(gamename,"wb"); 391 else if(command == 2)
362 if(!f)
363 { 392 {
364 printf("ERROR: Could not create file! Exit...\n"); 393 FILE *f = fopen(savename,"rb");
365 VIDEO_WaitVSync(); 394 if(f)
366 VIDEO_WaitVSync(); 395 {
367 sleep(5); 396 fclose(f);
368 exit(0); 397 command = 0;
398 printf("ERROR: Save already backed up!\n");
399 VIDEO_WaitVSync();
400 sleep(2);
401 }
369 } 402 }
370 printf("Dumping...\n"); 403 else if(command == 3)
371 u32 bytes_read = 0;
372 while(gbasize > 0)
373 { 404 {
374 int toread = (gbasize > 0x400000 ? 0x400000 : gbasize); 405 size_t readsize = 0;
375 int j; 406 FILE *f = fopen(savename,"rb");
376 for(j = 0; j < toread; j+=4) 407 if(f)
377 { 408 {
378 *(vu32*)(testdump+j) = recvfast(); 409 fseek(f,0,SEEK_END);
379 bytes_read+=4; 410 readsize = ftell(f);
380 if((bytes_read&0xFFFF) == 0) 411 if(readsize != savesize)
381 { 412 {
382 printf("\r%02.02f MB done",(float)(bytes_read/1024)/1024.f); 413 command = 0;
414 printf("ERROR: Save has the wrong size, aborting restore!\n");
383 VIDEO_WaitVSync(); 415 VIDEO_WaitVSync();
416 sleep(2);
417 }
418 else
419 {
420 rewind(f);
421 fread(testdump,readsize,1,f);
422 }
423 fclose(f);
424 }
425 else
426 {
427 command = 0;
428 printf("ERROR: No Save to restore!\n");
429 VIDEO_WaitVSync();
430 sleep(2);
431 }
432 }
433 sendsafe(command);
434 usleep(5000); //wait for it to set next val
435 if(command == 0)
436 continue;
437 else if(command == 1)
438 {
439 //create base file with size
440 printf("Creating file...\n");
441 int fd = open(gamename, O_WRONLY|O_CREAT);
442 if(fd >= 0)
443 {
444 ftruncate(fd, gbasize);
445 close(fd);
446 }
447 FILE *f = fopen(gamename,"wb");
448 if(!f)
449 {
450 printf("ERROR: Could not create file! Exit...\n");
451 VIDEO_WaitVSync();
452 VIDEO_WaitVSync();
453 sleep(5);
454 exit(0);
455 }
456 printf("Dumping...\n");
457 u32 bytes_read = 0;
458 while(gbasize > 0)
459 {
460 int toread = (gbasize > 0x400000 ? 0x400000 : gbasize);
461 int j;
462 for(j = 0; j < toread; j+=4)
463 {
464 *(vu32*)(testdump+j) = recvfast();
465 bytes_read+=4;
466 if((bytes_read&0xFFFF) == 0)
467 {
468 printf("\r%02.02f MB done",(float)(bytes_read/1024)/1024.f);
469 VIDEO_WaitVSync();
470 }
384 } 471 }
385 //printf("%02x%02x%02x%02x",resbuf[0],resbuf[1],resbuf[2],resbuf[3]); 472 fwrite(testdump,toread,1,f);
473 gbasize -= toread;
474 }
475 printf("\nClosing file\n");
476 fclose(f);
477 printf("Game dumped!\n");
478 sleep(5);
479 }
480 else if(command == 2)
481 {
482 FILE *f = fopen(savename,"wb");
483 if(!f)
484 {
485 printf("ERROR: Could not create file! Exit...\n");
486 VIDEO_WaitVSync();
487 VIDEO_WaitVSync();
488 sleep(5);
489 exit(0);
386 } 490 }
387 fwrite(testdump,toread,1,f); 491 printf("Waiting for GBA\n");
388 gbasize -= toread; 492 VIDEO_WaitVSync();
493 u32 readval = 0;
494 while(readval != savesize)
495 readval = __builtin_bswap32(recvsafe());
496 sendsafe(0); //got savesize
497 usleep(5000); //wait for it to set next val
498 printf("Receiving...\n");
499 for(i = 0; i < savesize; i+=4)
500 *(vu32*)(testdump+i) = recvsafe();
501 printf("Writing save...\n");
502 fwrite(testdump,savesize,1,f);
503 fclose(f);
504 printf("Save backed up!\n");
505 sleep(5);
506 }
507 else if(command == 3)
508 {
509 printf("Sending save\n");
510 VIDEO_WaitVSync();
511 u32 readval = 0;
512 while(readval != savesize)
513 readval = __builtin_bswap32(recvsafe());
514 for(i = 0; i < savesize; i+=4)
515 sendsafe(__builtin_bswap32(*(vu32*)(testdump+i)));
516 printf("Waiting for GBA\n");
517 while(recvsafe() != 0)
518 VIDEO_WaitVSync();
519 printf("Save restored!\n");
520 sendsafe(0);
521 sleep(5);
389 } 522 }
390 printf("\nClosing file\n");
391 fclose(f);
392 printf("Game dumped!\n");
393 sleep(5);
394 } 523 }
395 } 524 }
396 } 525 }