1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: tpl_ReadTexturePackage.cpp
4
5 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Rev: 27744 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nn/util.h>
17 #include <nn/tpl.h>
18
19 #include <cstring>
20 #include <cstdio>
21
22 #include "tpl_crc32.h"
23 #include "tpl_Internal.h"
24
25 namespace nn { namespace tpl { namespace CTR {
26
27 // テクスチャパッケージファイルに含まれるテクスチャ数を取得します。
GetTextureNum(const void * pTexPackage)28 u16 GetTextureNum(const void* pTexPackage)
29 {
30 if (!pTexPackage)
31 {
32 NN_TASSERT_(pTexPackage != 0);
33 return 0;
34 }
35 const CtrTexturePackageHeader* header =
36 reinterpret_cast<const CtrTexturePackageHeader*>(pTexPackage);
37 return header->numTexture;
38 }
39
40 // テクスチャインデックス取得関数
GetTextureIndex(const void * pTexPackage,const char * texPath)41 s16 GetTextureIndex(const void* pTexPackage, const char* texPath)
42 {
43 if(!pTexPackage || !texPath)
44 {
45 NN_TASSERT_((pTexPackage != 0) && (texPath != 0));
46 return -1;
47 }
48 // CRC32のハッシュコードを作成。
49 int fileNameLen = (int)::std::strlen(texPath);
50 unsigned int crc32key = calculate_crc32(texPath, fileNameLen);
51
52 const CtrTexturePackageHeader &header =
53 *reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
54 const CtrTextureHash *texHash = reinterpret_cast<const CtrTextureHash *>
55 ((const char*)pTexPackage + (header.texHashOffset));
56
57 // パッケージ内のテクスチャ情報と比較して一致するものを探す。
58 TPK_SEARCH_DATA data = { texPath, fileNameLen, pTexPackage };
59 int t = search_crc32_data(
60 texHash, header.numTexture, sizeof(CtrTextureHash), crc32key, &data);
61
62 if(t < 0) return -1;
63 return texHash[t].index;
64 }
65
66 // テクスチャ取得関数
GetTexture(s32 * mipLevel,u32 * mipmapSize,const void * pTexPackage,const s16 texIndex)67 void* GetTexture(s32* mipLevel, u32* mipmapSize, const void* pTexPackage, const s16 texIndex)
68 {
69 if(!pTexPackage)
70 {
71 NN_TASSERT_(pTexPackage != 0);
72 return 0;
73 }
74
75 // 指定された番号がテクスチャの枚数に収まっているか確認。
76 const CtrTexturePackageHeader *header =
77 reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
78 NN_TASSERT_((0 <= texIndex) && (texIndex < header->numTexture));
79 if((texIndex < 0) || (header->numTexture <= texIndex))
80 {
81 return 0;
82 }
83
84 const CtrTextureInfo *texInfo = reinterpret_cast<const CtrTextureInfo *>
85 (((const char*)pTexPackage) + (sizeof(CtrTexturePackageHeader)) + (sizeof(CtrTextureInfo) * texIndex));
86
87 if(!texInfo)
88 {
89 return 0;
90 }
91
92 // get texture size.
93 const unsigned int *Size = reinterpret_cast<const unsigned int *>
94 (((const char*)pTexPackage) + (4 * texInfo->bitmapSizeOffset));
95
96 *mipLevel = static_cast<int>(texInfo->mipLevel);
97 for(int i=0; i < *mipLevel; i++)
98 {
99 mipmapSize[i] = Size[i];
100 }
101
102 return (void*)(((const char*)pTexPackage) + (header->texDataOffset + texInfo->texDataOffset));
103 }
104
105 // テクスチャ情報取得関数
GetTextureInfo(CtrTextureInfo * pTexInfo,const void * pTexPackage,const s16 texIndex)106 bool GetTextureInfo(CtrTextureInfo* pTexInfo, const void* pTexPackage, const s16 texIndex)
107 {
108 if(!pTexPackage || !pTexInfo)
109 {
110 NN_TASSERT_((pTexPackage != 0) && (pTexInfo != 0));
111 return false;
112 }
113
114
115 // 指定された番号がテクスチャの枚数に収まっているか確認。
116 const CtrTexturePackageHeader *header =
117 reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
118 NN_TASSERT_((0 <= texIndex) && (texIndex < header->numTexture));
119 if((texIndex < 0) || (header->numTexture <= texIndex))
120 {
121 return false;
122 }
123
124 const CtrTextureInfo *texInfo = reinterpret_cast<const CtrTextureInfo *>
125 (((const char*)pTexPackage) + (sizeof(CtrTexturePackageHeader)) + (sizeof(CtrTextureInfo) * texIndex));
126
127 pTexInfo->filePathOffset = texInfo->filePathOffset;
128 pTexInfo->texDataSize = texInfo->texDataSize;
129 pTexInfo->texDataOffset = texInfo->texDataOffset;
130 pTexInfo->texFormat = texInfo->texFormat;
131 pTexInfo->width = texInfo->width;
132 pTexInfo->height = texInfo->height;
133 pTexInfo->mipLevel = texInfo->mipLevel;
134 pTexInfo->type = texInfo->type;
135 pTexInfo->cubeDir = texInfo->cubeDir;
136 pTexInfo->bitmapSizeOffset = texInfo->bitmapSizeOffset;
137 pTexInfo->srcFileTime = texInfo->srcFileTime;
138
139 return true;
140 }
141
142
143 // テクスチャパッケージヘッダーチェック関数(ヘルパー関数)
CheckTexturePackageHeader(const void * pTexPackage)144 bool CheckTexturePackageHeader(const void* pTexPackage)
145 {
146 if(!pTexPackage)
147 {
148 NN_TASSERT_(pTexPackage != 0);
149 return false;
150 }
151
152 // 指定された番号がテクスチャの枚数に収まっているか確認。
153 const CtrTexturePackageHeader *header =
154 reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
155 NN_TASSERT_(header);
156
157 // ヘッダのマジックコードを確認。
158 if(::std::strncmp(header->magic, "CTPK", 4) != 0)
159 {
160 NN_LOG("ERROR: The texture package's magic code isn't 'CTPK'.\n");
161 return false;
162 }
163
164 if(header->version != CTR_TEXTURE_PACKAGE_VERSION)
165 {
166 NN_LOG("ERROR: The texture package's version code differs.\n");
167 return false;
168 }
169
170 return true;
171 }
172
173
174 }}}
175