summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZephiles <cae222@yahoo.com>2022-05-06 16:29:44 -0500
committerZephiles <cae222@yahoo.com>2022-05-06 16:36:38 -0500
commit132cde3a527da4aee8202be2c4b30e9b9b5ccbbb (patch)
treeccdd688842089faee5670dab52d578ae99cf0ba4
parent1486704654a9500abc23f22d11495bb55db9bc0d (diff)
Add mountMemoryCard and ReadGCIMounted
Also fixed format issue in patch.h
-rw-r--r--include/gc_wii/card.h10
-rw-r--r--include/patch.h4
-rw-r--r--include/tools.h42
-rw-r--r--source/tools.cpp112
4 files changed, 126 insertions, 42 deletions
diff --git a/include/gc_wii/card.h b/include/gc_wii/card.h
index d46ab17..c75d9ea 100644
--- a/include/gc_wii/card.h
+++ b/include/gc_wii/card.h
@@ -129,7 +129,15 @@ namespace libtp::gc_wii::card
// CARDFreeBlocks( int32_t chan, int32_t* byteNotUsed, int32_t* filesNotUsed );
// int32_t CARDGetResultCode( int32_t chan );
// int32_t CARDGetEncoding( int32_t chan, u16* encode );
- // int32_t CARDGetStatus( int32_t chan, int32_t fileNo, CARDStat* stat );
+
+ /**
+ * @brief Gets the status of a file.
+ *
+ * @param chan EXI channel number
+ @param fileNo Index to the desired file on the memory card
+ @param stat Output for the status of the file
+ */
+ int32_t CARDGetStatus( int32_t chan, int32_t fileNo, CARDStat* stat );
// int32_t CARDMountAsync( int32_t chan, void* workArea, CARDCallback
// detachCallback, CARDCallback attachCallback );
diff --git a/include/patch.h b/include/patch.h
index be9af09..6f5ffb6 100644
--- a/include/patch.h
+++ b/include/patch.h
@@ -9,8 +9,8 @@
#include <cstdint>
-#include "memory.h"
#include "cxx.h"
+#include "memory.h"
namespace libtp::patch
{
@@ -24,7 +24,7 @@ namespace libtp::patch
uint32_t* instructions = reinterpret_cast<uint32_t*>( function );
#ifdef PLATFORM_WII
- uint32_t* trampoline = new (0x4, HEAP_ZELDA) uint32_t[2];
+ uint32_t* trampoline = new ( 0x4, HEAP_ZELDA ) uint32_t[2];
#else
uint32_t* trampoline = new uint32_t[2];
#endif
diff --git a/include/tools.h b/include/tools.h
index 61effd4..94f0e79 100644
--- a/include/tools.h
+++ b/include/tools.h
@@ -46,17 +46,55 @@ namespace libtp::tools
#ifndef PLATFORM_WII
/**
- * @brief Reads GCI data from offset to offset + length into buffer
+ * @brief Mounts a memory card
+ *
+ * @param chan Slot to check for the memory card
+ *
+ * @return One of the CARD_RESULT Constants (CARD_RESULT_READY, ...)
+ */
+ int32_t mountMemoryCard( int32_t chan );
+
+ /**
+ * @brief Reads GCI data from offset to offset + length into buffer. This function assumes that the memory card is already
+ * mounted, and does not unmount the memory card upon ending.
+ *
+ * @param chan Slot to check for the file
+ * @param fileName GCI Filename to load
+ * @param length Maximum length to read
+ * @param offset GCI fileOffset to read
+ * @param[out] buffer Buffer to save the data
+ * @param startAfterComments Whether to start reading after the comments section of the file. This assumes that the banner,
+ * icon, and comments are all directly next to each other in the file, and that the comments come last.
+ *
+ * @return One of the CARD_RESULT Constants (CARD_RESULT_READY, ...)
+ */
+ int32_t ReadGCIMounted( int32_t chan,
+ const char* fileName,
+ int32_t length,
+ int32_t offset,
+ void* buffer,
+ bool startAfterComments );
+
+ /**
+ * @brief Reads GCI data from offset to offset + length into buffer. This function mounts and unmounts the memory card upon
+ * starting and ending respectively.
*
* @param chan Slot to check for the file
* @param fileName GCI Filename to load
* @param length Maximum length to read
* @param offset GCI fileOffset to read
* @param[out] buffer Buffer to save the data
+ * @param startAfterComments Whether to start reading after the comments section of the file. This assumes that the banner,
+ * icon, and comments are all directly next to each other in the file, and that the comments come last.
*
* @return One of the CARD_RESULT Constants (CARD_RESULT_READY, ...)
*/
- int32_t ReadGCI( int32_t chan, const char* fileName, int32_t length, int32_t offset, void* buffer );
+ int32_t ReadGCI( int32_t chan,
+ const char* fileName,
+ int32_t length,
+ int32_t offset,
+ void* buffer,
+ bool startAfterComments );
#else // PLATFORM_WII
diff --git a/source/tools.cpp b/source/tools.cpp
index 41a710a..10eb644 100644
--- a/source/tools.cpp
+++ b/source/tools.cpp
@@ -82,23 +82,14 @@ namespace libtp::tools
#ifndef PLATFORM_WII
- int32_t ReadGCI( int32_t chan, const char* fileName, int32_t length, int32_t offset, void* buffer )
+ int32_t mountMemoryCard( int32_t chan )
{
using namespace libtp::gc_wii::card;
- CARDFileInfo fileInfo;
- uint8_t* workArea = libtp::tp::m_Do_MemCard::MemCardWorkArea0;
int32_t result;
+ uint8_t* workArea;
- // Since we can only read in and at increments of CARD_READ_SIZE do this to calculate the region we require
-
- int32_t adjustedOffset = ( offset / CARD_READ_SIZE ) * CARD_READ_SIZE;
- int32_t adjustedLength = ( 1 + ( ( offset - adjustedOffset + length - 1 ) / CARD_READ_SIZE ) ) * CARD_READ_SIZE;
-
- // Buffer might not be adjusted to the new length so create a temporary data buffer
- uint8_t* data = new uint8_t[adjustedLength];
-
- // Check if card is valid
+ // Check if the memory card is valid
for ( uint32_t i = 0; i < 1000000; i++ )
{
result = CARDProbeEx( chan, NULL, NULL );
@@ -110,40 +101,87 @@ namespace libtp::tools
if ( result == CARD_RESULT_READY )
{
- result = CARDMount( chan,
- workArea,
- []( int32_t chan, int32_t result )
- {
- // S
- tp::jfw_system::ConsoleLine* line =
- &tp::jfw_system::systemConsole->consoleLine[JFW_DEBUG_LINE];
-
- line->showLine = true;
- sprintf( line->line, "ReadGCI::CARDERR; Chan: %" PRId32 " Result: %" PRId32, chan, result );
- } );
+ // Mount the memory card
+ workArea = libtp::tp::m_Do_MemCard::MemCardWorkArea0;
+ result = CARDMount( chan, workArea, []( int32_t chan, int32_t result ) {
+ // S
+ tp::jfw_system::ConsoleLine* line = &tp::jfw_system::systemConsole->consoleLine[JFW_DEBUG_LINE];
+
+ line->showLine = true;
+ sprintf( line->line, "ReadGCI::CARDERR; Chan: %" PRId32 " Result: %" PRId32, chan, result );
+ } );
+ }
- if ( result == CARD_RESULT_READY )
+ return result;
+ }
+
+ int32_t ReadGCIMounted( int32_t chan,
+ const char* fileName,
+ int32_t length,
+ int32_t offset,
+ void* buffer,
+ bool startAfterComments )
+ {
+ using namespace libtp::gc_wii::card;
+
+ CARDFileInfo fileInfo;
+ int32_t result;
+
+ int32_t adjustedOffset;
+ int32_t adjustedLength;
+ uint8_t* data;
+
+ // Read data
+ result = CARDOpen( chan, fileName, &fileInfo );
+ if ( result == CARD_RESULT_READY )
+ {
+ // Adjust the offset if starting after the banner/icon/comments
+ if ( startAfterComments )
{
- // Read data
- result = CARDOpen( chan, const_cast<char*>( fileName ), &fileInfo );
+ CARDStat stat;
+ result = CARDGetStatus( chan, fileInfo.fileNum, &stat );
- if ( result == CARD_RESULT_READY )
+ if ( result != CARD_RESULT_READY )
{
- result = CARDRead( &fileInfo, data, adjustedLength, adjustedOffset );
CARDClose( &fileInfo );
-
- // Copy data to the user's buffer
- memcpy( buffer, data + ( offset - adjustedOffset ), length );
+ return result;
}
- // CARDOpen
- CARDUnmount( chan );
+
+ offset += stat.commentAddr + ( CARD_FILENAME_MAX * 2 );
+ }
+
+ // Since we can only read in and at increments of CARD_READ_SIZE do this to calculate the region we require
+ adjustedOffset = ( offset / CARD_READ_SIZE ) * CARD_READ_SIZE;
+ adjustedLength = ( 1 + ( ( offset - adjustedOffset + length - 1 ) / CARD_READ_SIZE ) ) * CARD_READ_SIZE;
+
+ // Buffer might not be adjusted to the new length so create a temporary data buffer
+ data = new uint8_t[adjustedLength];
+
+ result = CARDRead( &fileInfo, data, adjustedLength, adjustedOffset );
+ if ( result == CARD_RESULT_READY )
+ {
+ // Copy data to the user's buffer
+ memcpy( buffer, data + ( offset - adjustedOffset ), length );
}
- // CARDMount
+
+ delete[] data;
+ CARDClose( &fileInfo );
}
- // CARDProbeEx
+ // CARDOpen
- // Clean up
- delete[] data;
+ return result;
+ }
+
+ int32_t ReadGCI( int32_t chan, const char* fileName, int32_t length, int32_t offset, void* buffer, bool startAfterComments )
+ {
+ int32_t result;
+
+ result = mountMemoryCard( chan );
+ if ( result == CARD_RESULT_READY )
+ {
+ result = ReadGCIMounted( chan, fileName, length, offset, buffer, startAfterComments );
+ CARDUnmount( chan );
+ }
return result;
}