|
11 | 11 | #include <string.h> |
12 | 12 | #include <types.h> |
13 | 13 |
|
| 14 | +// Not 100% on what this does or if it's correctly defined for all cases. Seems to be used for allocation alignment |
| 15 | +#define ALIGN_THING(x, n) (n + x - 1 & -x) |
| 16 | + |
14 | 17 | // WIP |
15 | 18 | struct st_ISG_TPL_TEXPALETTE |
16 | 19 | { |
@@ -570,12 +573,206 @@ S32 iSGSetupGameDir(st_ISGSESSION* isgdata, const char* dname, S32 force_iconfix |
570 | 573 | return 1; |
571 | 574 | } |
572 | 575 |
|
| 576 | +static char* iSG_bfr_icondata(char* param1, CARDStat* stat, char* param3, int param4); |
| 577 | +static S32 iSG_mc_fopen(st_ISG_MEMCARD_DATA*, const char*, S32, en_ISG_IOMODE, en_ASYNC_OPERR*); |
| 578 | +static void iSG_mc_fclose(st_ISG_MEMCARD_DATA*); |
| 579 | +static void iSG_mc_fclose(st_ISG_MEMCARD_DATA*, CARDStat*); |
| 580 | +static S32 iSG_mc_fdel(st_ISG_MEMCARD_DATA*, const char*); |
| 581 | +static S32 iSG_mc_fwrite(st_ISG_MEMCARD_DATA*, char*, int); |
| 582 | +static S32 iSG_upd_icostat(CARDStat*, CARDStat*); |
| 583 | +static void iSG_timestamp(CARDStat*); |
| 584 | +S32 iSGSaveFile(st_ISGSESSION* isgdata, const char* fname, char* data, S32 n, S32 async, char* arg5) |
| 585 | +{ |
| 586 | + void* alloc; |
| 587 | + S32 allocsize; |
| 588 | + char* icondata; |
| 589 | + S32 iconsize; |
| 590 | + |
| 591 | + S32 writeret = 0; |
| 592 | + en_ASYNC_OPERR operr = ISG_OPERR_NONE; |
| 593 | + CARDStat statA = { 0 }; |
| 594 | + CARDStat statB = { 0 }; |
| 595 | + |
| 596 | + ResetButton::DisableReset(); |
| 597 | + if (isgdata->slot < 0) |
| 598 | + { |
| 599 | + isgdata->unk_26c = ISG_OPSTAT_FAILURE; |
| 600 | + isgdata->unk_268 = ISG_OPERR_NOCARD; |
| 601 | + return 0; |
| 602 | + } |
| 603 | + |
| 604 | + st_ISG_MEMCARD_DATA* mcdata = &isgdata->mcdata[isgdata->slot]; |
| 605 | + if (mcdata->unk_12c != 0) |
| 606 | + { |
| 607 | + isgdata->unk_26c = ISG_OPSTAT_FAILURE; |
| 608 | + isgdata->unk_268 = ISG_OPERR_DAMAGE; |
| 609 | + return 0; |
| 610 | + } |
| 611 | + |
| 612 | + iTRCDisk::CheckDVDAndResetState(); |
| 613 | + iconsize = iSG_cubeicon_size(isgdata->slot, mcdata->sectorSize); |
| 614 | + S32 sectorsize200 = ALIGN_THING(mcdata->sectorSize, 0x200); |
| 615 | + iconsize += ALIGN_THING(sectorsize200, n); |
| 616 | + |
| 617 | + allocsize = iconsize + 0x1f; |
| 618 | + alloc = xMemPushTemp(allocsize); |
| 619 | + memset(alloc, 0, allocsize); |
| 620 | + icondata = (char*)((U32)alloc + 0x1f & 0xFFFFFFE0); |
| 621 | + |
| 622 | + memcpy(iSG_bfr_icondata(icondata, &statA, arg5, mcdata->sectorSize), data, n); |
| 623 | + iTRCDisk::CheckDVDAndResetState(); |
| 624 | + |
| 625 | + if (iSG_mc_fopen(mcdata, fname, iconsize, ISG_IOMODE_WRITE, &operr) != 0) |
| 626 | + { |
| 627 | + if (iSG_mc_fwrite(mcdata, icondata, iconsize) != 0) |
| 628 | + { |
| 629 | + writeret = 1; |
| 630 | + } |
| 631 | + else |
| 632 | + { |
| 633 | + writeret = 0; |
| 634 | + operr = ISG_OPERR_SVWRITE; |
| 635 | + } |
| 636 | + |
| 637 | + if (writeret != 0) |
| 638 | + { |
| 639 | + iSG_upd_icostat(&statA, &mcdata->unk_20); |
| 640 | + iSG_timestamp(&mcdata->unk_20); |
| 641 | + s32 result; |
| 642 | + do |
| 643 | + { |
| 644 | + result = CARDSetStatus(mcdata->unk_4, mcdata->unk_c.fileNo, &mcdata->unk_20); |
| 645 | + } while (result == CARD_RESULT_BUSY); |
| 646 | + |
| 647 | + if (result != CARD_RESULT_READY) |
| 648 | + { |
| 649 | + writeret = 0; |
| 650 | + } |
| 651 | + } |
| 652 | + |
| 653 | + if (writeret != 0) |
| 654 | + { |
| 655 | + s32 result; |
| 656 | + do |
| 657 | + { |
| 658 | + result = CARDSetAttributes(mcdata->unk_4, mcdata->unk_c.fileNo, CARD_ATTR_PUBLIC); |
| 659 | + } while (result == CARD_RESULT_BUSY); |
| 660 | + } |
| 661 | + |
| 662 | + iSG_mc_fclose(mcdata, &statB); |
| 663 | + } |
| 664 | + xMemPopTemp(alloc); |
| 665 | + |
| 666 | + if (writeret == 0 && mcdata->unk_12c == 0) |
| 667 | + { |
| 668 | + iSG_mc_fdel(mcdata, fname); |
| 669 | + } |
| 670 | + |
| 671 | + ResetButton::EnableReset(); |
| 672 | + iTRCDisk::CheckDVDAndResetState(); |
| 673 | + |
| 674 | + isgdata->unk_268 = ISG_OPERR_NONE; |
| 675 | + if (writeret != 0) |
| 676 | + { |
| 677 | + isgdata->unk_26c = ISG_OPSTAT_SUCCESS; |
| 678 | + } |
| 679 | + else |
| 680 | + { |
| 681 | + isgdata->unk_26c = ISG_OPSTAT_FAILURE; |
| 682 | + if (operr != ISG_OPERR_NONE) |
| 683 | + { |
| 684 | + isgdata->unk_268 = operr; |
| 685 | + } |
| 686 | + else |
| 687 | + { |
| 688 | + isgdata->unk_268 = ISG_OPERR_UNKNOWN; |
| 689 | + } |
| 690 | + } |
| 691 | + return writeret; |
| 692 | +} |
| 693 | + |
573 | 694 | S32 iSGLoadFile(st_ISGSESSION* isgdata, const char* fname, char* databuf, S32 async) |
574 | 695 | { |
575 | 696 | S32 numBytes = iSGFileSize(isgdata, fname); |
576 | 697 | return iSGReadLeader(isgdata, fname, databuf, numBytes, async); |
577 | 698 | } |
578 | 699 |
|
| 700 | +static S32 iSG_mc_fread(st_ISG_MEMCARD_DATA* mcdata, char*, S32, S32); |
| 701 | +S32 iSGReadLeader(st_ISGSESSION* isgdata, const char* fname, char* databuf, S32 numbytes, S32 async) |
| 702 | +{ |
| 703 | + en_ASYNC_OPERR operr = ISG_OPERR_NONE; |
| 704 | + S32 readret = 0; |
| 705 | + void* alloc = NULL; |
| 706 | + if (isgdata->slot < 0) |
| 707 | + { |
| 708 | + isgdata->unk_26c = ISG_OPSTAT_FAILURE; |
| 709 | + isgdata->unk_268 = ISG_OPERR_NOCARD; |
| 710 | + return 0; |
| 711 | + } |
| 712 | + st_ISG_MEMCARD_DATA* data = &isgdata->mcdata[isgdata->slot]; |
| 713 | + |
| 714 | + if (data->unk_12c != 0) |
| 715 | + { |
| 716 | + isgdata->unk_26c = ISG_OPSTAT_FAILURE; |
| 717 | + isgdata->unk_268 = ISG_OPERR_DAMAGE; |
| 718 | + return 0; |
| 719 | + } |
| 720 | + |
| 721 | + iTRCDisk::CheckDVDAndResetState(); |
| 722 | + S32 iconsize = iSG_cubeicon_size(data->unk_4, data->sectorSize); |
| 723 | + U32 sign = (S32)databuf >> 0x1f; |
| 724 | + // /x + (n-1) & -x is the same as Round x up to next n |
| 725 | + S32 nearest200 = -data->sectorSize & 0x1ff + data->sectorSize; |
| 726 | + // FIXME: I think the code is supposed to check if there is enough room at the end of the existing databuf allocation to use |
| 727 | + // and only allocate if not. |
| 728 | + void* readbuf; |
| 729 | + if (((sign * 0x20 | (int)databuf * 0x8000000 + sign >> 0x1b) != sign) || |
| 730 | + (sign = numbytes, readbuf = databuf, numbytes != (numbytes / nearest200) * nearest200)) |
| 731 | + { |
| 732 | + sign = numbytes + 0x1ffU & 0xfffffe00; |
| 733 | + S32 __n = sign + 0x1f; |
| 734 | + alloc = (void*)xMemPushTemp(__n); |
| 735 | + readbuf = alloc; |
| 736 | + memset(alloc, 0, __n); |
| 737 | + readbuf = (char*)((int)alloc + 0x1fU & 0xffffffe0); |
| 738 | + } |
| 739 | + iTRCDisk::CheckDVDAndResetState(); |
| 740 | + |
| 741 | + if (iSG_mc_fopen(data, fname, -1, ISG_IOMODE_READ, &operr) != 0) |
| 742 | + { |
| 743 | + readret = (bool)iSG_mc_fread(data, (char*)readbuf, numbytes, iconsize); |
| 744 | + iSG_mc_fclose(data); |
| 745 | + } |
| 746 | + |
| 747 | + if (readret == 0 && alloc != NULL) |
| 748 | + { |
| 749 | + memcpy(databuf, readbuf, numbytes); |
| 750 | + } |
| 751 | + if (alloc != NULL) |
| 752 | + { |
| 753 | + xMemPopTemp(alloc); |
| 754 | + } |
| 755 | + |
| 756 | + isgdata->unk_268 = ISG_OPERR_NONE; |
| 757 | + if (readret != 0) |
| 758 | + { |
| 759 | + isgdata->unk_26c = ISG_OPSTAT_SUCCESS; |
| 760 | + } |
| 761 | + else |
| 762 | + { |
| 763 | + isgdata->unk_26c = ISG_OPSTAT_FAILURE; |
| 764 | + if (data->unk_12c != 0) |
| 765 | + { |
| 766 | + isgdata->unk_268 = ISG_OPERR_DAMAGE; |
| 767 | + } |
| 768 | + else |
| 769 | + { |
| 770 | + isgdata->unk_268 = ISG_OPERR_OTHER; |
| 771 | + } |
| 772 | + } |
| 773 | + return readret; |
| 774 | +} |
| 775 | + |
579 | 776 | en_ASYNC_OPSTAT iSGPollStatus(st_ISGSESSION* isgdata, en_ASYNC_OPCODE* curop, S32 block) |
580 | 777 | { |
581 | 778 | return isgdata->unk_26c; |
@@ -878,8 +1075,7 @@ static S32 iSG_isSpaceForFile(st_ISG_MEMCARD_DATA* mcdata, S32 param2, const cha |
878 | 1075 | } |
879 | 1076 | len = iSG_cubeicon_size(mcdata->unk_4, mcdata->sectorSize); |
880 | 1077 | len = len + param2; |
881 | | - // FIXME: fakematch: x + (n-1) & -x is the same as Round x up to next n |
882 | | - len = -mcdata->sectorSize & len + mcdata->sectorSize - 1; |
| 1078 | + len = ALIGN_THING(mcdata->sectorSize, len); |
883 | 1079 |
|
884 | 1080 | do |
885 | 1081 | { |
@@ -948,8 +1144,6 @@ static S32 iSG_mc_settgt(st_ISG_MEMCARD_DATA* mcdata, S32 slot) |
948 | 1144 | return mcdata->unk_0 != 0 ? 1 : 0; |
949 | 1145 | } |
950 | 1146 |
|
951 | | -static S32 iSG_mc_fopen(st_ISG_MEMCARD_DATA*, const char*, int, en_ISG_IOMODE, en_ASYNC_OPERR*); |
952 | | -static void iSG_mc_fclose(st_ISG_MEMCARD_DATA*); |
953 | 1147 | static S32 iSG_get_finfo(st_ISG_MEMCARD_DATA* mcdata, const char* dpath) |
954 | 1148 | { |
955 | 1149 | S32 rc = 0; |
@@ -1007,7 +1201,6 @@ static S32 iSG_curKosher(CARDStat* stat, CARDFileInfo* info) |
1007 | 1201 |
|
1008 | 1202 | return rc; |
1009 | 1203 | } |
1010 | | -static S32 iSG_mc_fdel(st_ISG_MEMCARD_DATA*, const char*); |
1011 | 1204 | static S32 iSG_fileKosher(st_ISG_MEMCARD_DATA* mcdata, const char* param2, int param3, int* param4) |
1012 | 1205 | { |
1013 | 1206 | S32 rc = 0; |
@@ -1130,9 +1323,11 @@ static S32 iSG_cubeicon_size(S32 slot, S32 param2) |
1130 | 1323 | return -1; |
1131 | 1324 | } |
1132 | 1325 |
|
1133 | | - // FIXME: fakematch: x + (n-1) & -x is the same as Round x up to next n |
1134 | | - S32 t = (param2 + 0x1ffU) & -param2; |
1135 | | - return -t & (t + (sizeof(IconData) - 1)); |
| 1326 | + S32 t = ALIGN_THING(param2, 0x200); |
| 1327 | + |
| 1328 | + // FIXME: Macro not quite right |
| 1329 | + // return ALIGN_THING(t, sizeof(IconData)); |
| 1330 | + return -t & sizeof(IconData) + t - 1; |
1136 | 1331 | } |
1137 | 1332 |
|
1138 | 1333 | static S32 iSG_chk_icondata() |
@@ -1202,7 +1397,7 @@ static char* iSG_bfr_icondata(char* param1, CARDStat* stat, char* param3, int pa |
1202 | 1397 |
|
1203 | 1398 | memcpy(param1, &data, sizeof(data)); |
1204 | 1399 |
|
1205 | | - S32 t = param4 + 0x1ff & -param4; |
| 1400 | + S32 t = ALIGN_THING(param4, 0x1ff); |
1206 | 1401 | return param1 + (t + (sizeof(IconData) - 1) & -t); |
1207 | 1402 | } |
1208 | 1403 |
|
|
0 commit comments