diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/main.c | 231 |
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 | ||
| 29 | u8 *resbuf,*cmdbuf; | 30 | u8 *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 | } |
