/*---------------------------------------------------------------------------* Project: NintendoWare File: lyt_Arc.h Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ #ifndef NW_LYT_ARC_H_ #define NW_LYT_ARC_H_ #if defined(_MSC_VER) && _MSC_VER >= 1500 #pragma once #endif #include namespace nw { namespace lyt { //! :private //! //! @brief アーカイブヘッダ構造体 //! typedef struct { u32 signature; //!< ファイルシグネチャ u16 byteOrder; //!< バイトオーダーマーク u16 headerSize; //!< ヘッダサイズ u32 version; //!< ファイルバージョン u32 fileSize; //!< ファイルサイズ s32 fstStart; //!< エントリテーブル部の開始位置 s32 fstSize; //!< エントリテーブル部のサイズ s32 fileStart; //!< ファイルデータ部の開始位置 } ARCHeader; //! @details :private const u32 DARCH_SIGNATURE = 0x63726164; // 'darc' //! @details :private const u16 DARCH_BYTE_ORDER_MARK = 0xFEFF; //! @details :private const u32 DARCH_VERSION = 0x01000000; //! :category ARC //! //! @brief アーカイブハンドル構造体 //! typedef struct { void* archiveStartAddr; void* FSTStart; void* fileStart; u32 entryNum; wchar_t* FSTStringStart; u32 FSTLength; u32 currDir; } ARCHandle; //! :category ARC //! //! @brief ファイル情報構造体 //! typedef struct { ARCHandle* handle; u32 startOffset; u32 length; } ARCFileInfo; //! :category ARC //! //! @brief ディレクトリ構造体 //! typedef struct { ARCHandle* handle; u32 entryNum; u32 location; u32 next; } ARCDir; //! :category ARC //! //! @brief ディレクトリエントリ構造体 //! typedef struct { ARCHandle* handle; u32 entryNum; bool isDir; wchar_t* name; } ARCDirEntry; //! @name ARC //@{ //! :category ARC //! //! @brief アーカイブをオープンします。 //! //! @param[in] arcStart メモリ上のアーカイブファイルの先頭アドレスです。 //! @param[out] handle 初期化する ARCHandle 構造体です。 //! //! @return アーカイブのオープンに成功すれば true を返します。 //! //! @details //! ARCInitHandle() は メモリ上にロードされたアーカイブファイルを //! 参照できるように ARCHandle 構造体を初期化します。 //! //! この関数を呼び出す前に、アーカイブファイルの少なくともヘッダ //! および FST 領域をメモリ上にロードしておく必要があります。 //! bool ARCInitHandle(void* arcStart, ARCHandle* handle); //! :category ARC //! //! @brief アーカイブ内のファイルをオープンします。 //! //! @param [in] handle ARCHandle 構造体です。 //! @param [in] fileName アーカイブ内のファイル名です。 //! @param [out] af 初期化する ARCFileInfo 構造体です。 //! //! @return 成功すれば true を、そうでなければ false を返します。 //! //! @details //! アーカイブ内のファイルをオープンし、指定した ARCFileInfo //! 構造体を初期化します。 //! //! fileName に相対パスを指定した場合には、 ARCHandle 構造体の //! カレントディレクトリからの相対パスとなります。 //! //! あらかじめ ARCInitHandle() でアーカイブファイルの //! ARCHandle 構造体を初期化しておく必要があります。 //! //! @sa ARCInitHandle //! @sa ARCFastOpen //! @sa ARCChangeDir //! bool ARCOpen(ARCHandle* handle, const wchar_t* fileName, ARCFileInfo* af); //! :category ARC //! //! @brief エントリ番号を指定してアーカイブ内のファイルをオープンします。 //! //! @param[in] handle ARCHandle 構造体です。 //! @param[in] entrynum ファイルのエントリ番号です。 //! @param[out] af 初期化する ARCFileInfo 構造体です。 //! //! @return 成功すれば true を、そうでなければ false を返します。 //! //! @details //! ARCFastOpen() は、アーカイブ内のファイルをオープンし、 //! 指定した ARCFileInfo 構造体を初期化します。 //! //! ARCOpen() との違いは、ファイル名を指定する代わりにエントリ番号を //! 指定することです。あらかじめ、ARCConvertPathToEntrynum() などで //! ファイルの entrynum を取得する必要があります。 //! //! あらかじめ ARCInitHandle() でアーカイブファイルの //! ARCHandle 構造体を初期化しておく必要があります。 //! //! @sa ARCOpen //! @sa ARCInitHandle //! @sa ARCConvertPathToEntrynum //! @sa ARCGetDirEntryEntrynum //! bool ARCFastOpen(ARCHandle* handle, s32 entrynum, ARCFileInfo* af); //! :category ARC //! //! @brief アーカイブ内のファイルをオープンします。 //! //! @param [in] handle ARCHandle 構造体です。 //! @param [in] dirent アーカイブ内のファイルを示すディレクトリエントリ構造体です。 //! @param [out] af 初期化する ARCFileInfo 構造体です。 //! //! @return 成功すれば true を、そうでなければ false を返します。 //! //! @details //! ディレクトリエントリ構造体で示されたアーカイブ内のファイルをオープンし、 //! 指定した ARCFileInfo 構造体を初期化します。 //! //! ディレクトリエントリ構造体が示すエントリはファイルでなければなりません。 //! //! あらかじめ ARCReadDir() でディレクトリエントリ構造体を初期化しておく //! 必要があります。 //! //! あらかじめ ARCInitHandle() でアーカイブファイルの //! ARCHandle 構造体を初期化しておく必要があります。 //! //! @sa ARCInitHandle //! @sa ARCFastOpen //! @sa ARCReadDir //! NW_INLINE bool ARCOpen(ARCHandle* handle, ARCDirEntry* dirent, ARCFileInfo* af) { NW_NULL_ASSERT(dirent); return ARCFastOpen(handle, static_cast(dirent->entryNum), af); } //! :category ARC //! //! @brief アーカイブ内のファイルのパスをエントリ番号に変換します。 //! //! @param[in] handle ARCHandle 構造体です。 //! @param[in] pathPtr アーカイブ内のファイル名です。 //! //! @return アーカイブ内にファイル名が見つからない場合は、-1 を返します。 //! 変換に成功すれば、エントリ番号(0 または正数)を返します。 //! //! @details //! ARCConvertPathToEntrynum() は、アーカイブ内のファイルのパスを //! エントリ番号に変換します。 //! //! pathPtr に相対パスを指定した場合には、 ARCHandle 構造体の //! カレントディレクトリからの相対パスとなります。 //! //! あらかじめ ARCInitHandle() で ARCHandle 構造体を初期化しておく //! 必要があります。 //! //! @sa ARCFastOpen //! @sa ARCInitHandle //! @sa ARCChangeDir //! s32 ARCConvertPathToEntrynum(ARCHandle* handle, const wchar_t* pathPtr); //! :category ARC //! //! @brief エントリの種類がディレクトリかを取得します。 //! //! @param[in] handle ARCHandle 構造体です。 //! @param[in] entrynum エントリ番号です。 //! //! @return エントリの種類がディレクトリの場合は true を返します。 //! エントリの種類がファイルの場合は false を返します。 //! //! あらかじめ ARCInitHandle() で ARCHandle 構造体を初期化しておく //! 必要があります。 //! //! @sa ARCInitHandle //! bool ARCEntrynumIsDir(const ARCHandle * handle, s32 entrynum); //! :category ARC //! //! @brief メモリ上のファイルの先頭アドレスを取得します。 //! //! @param[in] af ファイルの ARCFileInfo 構造体です。 //! //! @return ファイルの先頭アドレスを返します。 //! //! アーカイブファイル全体がメモリ上にあるとして、 ARCGetStartAddrInMem() は、 //! メモリ上のファイルの先頭アドレスを返します。 //! //! アーカイブ全体をロードしていない場合にこの関数をコールしたときの動作は //! 保証できません。 //! //! @sa ARCFastOpen //! @sa ARCOpen //! @sa ARCGetLength //! void* ARCGetStartAddrInMem(ARCFileInfo* af); //! :category ARC //! //! @brief アーカイブの先頭からのファイルの開始オフセットを取得します。 //! //! @param[in] af ファイルの ARCFileInfo 構造体です。 //! //! @return ファイルの開始オフセットを返します。 //! //! @sa ARCFastOpen //! @sa ARCOpen //! @sa ARCGetLength //! u32 ARCGetStartOffset(ARCFileInfo* af); //! :category ARC //! //! @brief ファイルのサイズを取得します。 //! //! @param[in] af ファイルの ARCFileInfo 構造体です。 //! //! @return ファイルのサイズを返します。 //! //! @sa ARCFastOpen //! @sa ARCOpen //! @sa ARCGetStartAddrInMem //! @sa ARCGetStartOffset //! u32 ARCGetLength(ARCFileInfo* af); //! :category ARC //! //! @brief ファイルをクローズします。 //! //! @param[in,out] af クローズするファイルの ARCFileInfo 構造体です。 //! //! @return 現在の実装では、常に true を返します。 //! //! @sa ARCFastOpen //! @sa ARCOpen //! bool ARCClose(ARCFileInfo* af); //! :category ARC //! //! @brief アーカイブのカレントディレクトリを変更します。 //! //! @param[in,out] handle ARCHandle 構造体です。 //! @param[in] dirName 変更するディレクトリです。 //! //! @return 成功すれば true を、そうでなければ false を返します。 //! //! @details //! ARCChangeDir() は、アーカイブのカレントディレクトリを変更します。 //! //! あらかじめ ARCInitHandle() で ARCHandle 構造体を初期化しておく //! 必要があります。 //! //! @sa ARCInitHandle //! @sa ARCOpen //! @sa ARCConvertPathToEntrynum //! bool ARCChangeDir(ARCHandle* handle, const wchar_t* dirName); //! :category ARC //! //! @brief アーカイブのカレントディレクトリを変更します。 //! //! @param[in,out] handle ARCHandle 構造体です。 //! @param[in] entrynum 変更するディレクトリのエントリ番号です。 //! //! @return 成功すれば true を、そうでなければ false を返します。 //! //! @details //! アーカイブのカレントディレクトリをエントリ番号で指定したディレクトリに //! 変更します。 //! //! エントリ番号で指定したエントリはディレクトリでなければなりません。 //! //! あらかじめ ARCInitHandle() で ARCHandle 構造体を初期化しておく //! 必要があります。 //! //! @sa ARCInitHandle //! bool ARCChangeDir(ARCHandle* handle, s32 entrynum); //! :category ARC //! //! @brief アーカイブのカレントディレクトリを変更します。 //! //! @param[in,out] handle ARCHandle 構造体です。 //! @param[in] dir 変更するディレクトリのディレクトリ構造体です。 //! //! @return 成功すれば true を、そうでなければ false を返します。 //! //! @details //! アーカイブのカレントディレクトリをディレクトリ構造体が示す //! ディレクトリに変更します。 //! //! あらかじめ ARCOpenDir() でディレクトリ構造体を初期化しておく //! 必要があります。 //! //! あらかじめ ARCInitHandle() で ARCHandle 構造体を初期化しておく //! 必要があります。 //! //! @sa ARCInitHandle //! @sa ARCOpenDir //! NW_INLINE bool ARCChangeDir(ARCHandle* handle, ARCDir* dir) { NW_NULL_ASSERT(dir); return ARCChangeDir(handle, static_cast(dir->entryNum)); } //! :category ARC //! //! @brief アーカイブのカレントディレクトリを変更します。 //! //! @param[in,out] handle ARCHandle 構造体です。 //! @param[in] dirent 変更するディレクトリのディレクトリエントリ構造体です。 //! //! @return 成功すれば true を、そうでなければ false を返します。 //! //! @details //! アーカイブのカレントディレクトリをディレクトリエントリ構造体が示す //! ディレクトリに変更します。 //! //! ディレクトリエントリ構造体が示すエントリはディレクトリでなければなりません。 //! //! あらかじめ ARCReadDir() でディレクトリエントリ構造体を初期化しておく //! 必要があります。 //! //! あらかじめ ARCInitHandle() で ARCHandle 構造体を初期化しておく //! 必要があります。 //! //! @sa ARCInitHandle //! @sa ARCReadDir //! NW_INLINE bool ARCChangeDir(ARCHandle* handle, ARCDirEntry* dirent) { NW_NULL_ASSERT(dirent); return ARCChangeDir(handle, static_cast(dirent->entryNum)); } //! :category ARC //! //! @brief アーカイブのカレントディレクトリを取得します。 //! //! @param[in] handle ARCHandle 構造体です。 //! @param[out] path パスを格納するためのバッファです。 //! @param[in] maxlen バッファのサイズです。 //! //! @return パスがバッファ内に収まれば true を返します。 //! そうでなければ false を返します。 //! //! @details //! アーカイブのカレントディレクトリのパス文字列を指定されたバッファに //! 書き込みます。 //! //! @sa ARCInitHandle //! @sa ARCChangeDir //! bool ARCGetCurrentDir(ARCHandle* handle, wchar_t* path, u32 maxlen); //! :category ARC //! //! @brief ディレクトリをオープンします。 //! //! @param[in] handle ARCHandle 構造体です。 //! @param[in] dirName オープンするディレクトリ名です。 //! @param[out] dir 初期化するディレクトリ構造体です。 //! //! @return ディレクトリをオープンできた場合は true を返します。 //! //! @details //! dirName に相対パスを指定した場合には、 ARCHandle 構造体の //! カレントディレクトリからの相対パスとなります。 //! //! @sa ARCInitHandle //! @sa ARCReadDir //! @sa ARCCloseDir //! @sa ARCChangeDir //! bool ARCOpenDir(ARCHandle* handle, const wchar_t* dirName, ARCDir* dir); //! :category ARC //! //! @brief ディレクトリをオープンします。 //! //! @param[in] handle ARCHandle 構造体です。 //! @param[in] entrynum オープンするディレクトリのエントリ番号です。 //! @param[out] dir 初期化するディレクトリ構造体です。 //! //! @return ディレクトリをオープンできた場合は true を返します。 //! //! @details //! エントリ番号が示すディレクトリをオープンし、指定した ARCDir 構造体を //! 初期化します。 //! //! あらかじめ ARCInitHandle() で ARCHandle 構造体を初期化しておく //! 必要があります。 //! //! @sa ARCInitHandle //! @sa ARCReadDir //! @sa ARCCloseDir //! bool ARCOpenDir(ARCHandle* handle, s32 entrynum, ARCDir* dir); //! :category ARC //! //! @brief ディレクトリをオープンします。 //! //! @param[in] handle ARCHandle 構造体です。 //! @param[in] dirent オープンするディレクトリを示すディレクトリエントリ構造体です。 //! @param[out] dir 初期化するディレクトリ構造体です。 //! //! @return ディレクトリをオープンできた場合は true を返します。 //! //! @details //! ディレクトリエントリ構造体が示すディレクトリをオープンし、 //! 指定した ARCDir 構造体を初期化します。 //! //! ディレクトリエントリ構造体が示すエントリはディレクトリでなければなりません。 //! //! あらかじめ ARCReadDir() でディレクトリエントリ構造体を初期化しておく //! 必要があります。 //! //! あらかじめ ARCInitHandle() で ARCHandle 構造体を初期化しておく //! 必要があります。 //! //! @sa ARCInitHandle //! @sa ARCReadDir //! @sa ARCCloseDir //! NW_INLINE bool ARCOpenDir(ARCHandle* handle, ARCDirEntry* dirent, ARCDir* dir) { NW_NULL_ASSERT(dirent); return ARCOpenDir(handle, static_cast(dirent->entryNum), dir); } //! :category ARC //! //! @brief ディレクトリエントリの情報を取得します。 //! //! @param[in,out] dir 読み込むディレクトリのディレクトリ構造体です。 //! @param[out] dirent 初期化するディレクトリエントリ構造体です。 //! //! @return ディレクトリエントリが存在すれば true を返します。 //! ディレクトリの最後に到達済みの場合は false を返します。 //! //! @details //! 次のディレクトリエントリの情報を取得します。 //! //! ディレクトリエントリは、ディレクトリかまたはファイルです。 //! エントリの種類は ARCDirEntryIsDir() で取得できます。 //! //! エントリの種類に応じて ARCOpen() または ARCOpenDir() で //! エントリをオープンできます。 //! //! @sa ARCOpenDir //! @sa ARCCloseDir //! @sa ARCSeekDir //! @sa ARCRewindDir //! @sa ARCDirEntryIsDir //! @sa ARCOpen //! @sa ARCOpenDir //! bool ARCReadDir(ARCDir* dir, ARCDirEntry* dirent); //! :category ARC //! //! @brief ディレクトリをクローズします。 //! //! @param[in,out] dir クローズするディレクトリのディレクトリ構造体です。 //! //! @return 正常に実行できれば true が返ります。 //! //! @sa ARCOpenDir //! @sa ARCReadDir //! bool ARCCloseDir(ARCDir* dir); //! :category ARC //! //! @brief ディレクトリの読み出し位置を取得します。 //! //! @param[in] dir ディレクトリ構造体です。 //! //! @return 現在の読み出し位置を返します。 //! //! @details //! ARCTellDir() は次の ARCReadDir() 時に //! ディレクトリから読み出されるディレクトリエントリの位置を返します。 //! //! この関数は、ARCSeekDir() と組み合わせて使用することが想定されています。 //! ARCTellDir() で現在の位置を「保存」し、後で ARCSeekDir() により //! 「復元」できます。 //! //! @sa ARCSeekDir //! @sa ARCReadDir //! NW_INLINE u32 ARCTellDir(ARCDir* dir) { return dir->location; } //! :category ARC //! //! @brief ディレクトリの読み出し位置を設定します。 //! //! @param[in,out] dir ディレクトリ構造体です。 //! @param[in] loc 設定する読み出し位置です。 //! //! @details //! ARCSeekDir() は次の ARCReadDir() 時に読み出されるディレクトリエントリの //! 位置を指定します。 //! //! 引数 loc には、先に ARCTellDir() で取得した位置を指定します。 //! //! この関数は、ARCTellDir() と組み合わせて使用することが想定されています。 //! ARCTellDir()で現在の場所を「保存」し、後で ARCSeekDir() により //! 「復元」できます。 //! //! 注意:loc はディレクトリ内におけるディレクトリエントリの番号ではありません。 //! //! @sa ARCTellDir //! @sa ARCReadDir //! NW_INLINE void ARCSeekDir(ARCDir* dir, u32 loc) { dir->location = loc; } //! :category ARC //! //! @brief ディレクトリの読み出し位置をディレクトリの最初へリセットします。 //! //! @param[in,out] dir ディレクトリ構造体です。 //! //! @sa ARCReadDir //! NW_INLINE void ARCRewindDir(ARCDir* dir) { dir->location = dir->entryNum + 1; } //! :category ARC //! //! @brief ディレクトリエントリの名前を取得します。 //! //! @param[in] dirent ディレクトリエントリ構造体です。 //! //! @return ディレクトリエントリの名前へのポインタ。 //! //! @details //! ディレクトリエントリの名前はパスを含みません。 //! //! @sa ARCReadDir //! NW_INLINE const wchar_t* ARCGetDirEntryName(ARCDirEntry* dirent) { return dirent->name; } //! :category ARC //! //! @brief ディレクトリエントリのエントリ番号を取得します。 //! //! @param[in] dirent ディレクトリエントリ構造体です。 //! //! @return ディレクトリエントリのエントリ番号を返します。 //! //! @sa ARCReadDir //! NW_INLINE s32 ARCGetDirEntryEntrynum(ARCDirEntry* dirent) { return static_cast(dirent->entryNum); } //! :category ARC //! //! @brief ディレクトリエントリがディレクトリであるかどうか調べます。 //! //! @param[in] dirent ディレクトリエントリ構造体です。 //! //! @return ディレクトリエントリがディレクトリであれば true を、 //! そうでなければ false を返します。 //! //! @sa ARCReadDir //! NW_INLINE bool ARCDirEntryIsDir(ARCDirEntry* dirent) { return dirent->isDir; } // @} } // namespace lyt } // namespace nw #endif // NW_LYT_ARC_H_