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: 19746 $
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 
28 // テクスチャインデックス取得関数
GetTextureIndex(const void * pTexPackage,const char * texPath)29 s16 GetTextureIndex(const void* pTexPackage, const char* texPath)
30 {
31     if(!pTexPackage || !texPath)
32     {
33         NN_TASSERT_((pTexPackage != 0) && (texPath != 0));
34         return -1;
35     }
36     // CRC32のハッシュコードを作成。
37     int fileNameLen = (int)::std::strlen(texPath);
38     unsigned int crc32key = calculate_crc32(texPath, fileNameLen);
39 
40     const CtrTexturePackageHeader &header =
41         *reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
42     const CtrTextureHash *texHash = reinterpret_cast<const CtrTextureHash *>
43                       ((const char*)pTexPackage + (header.texHashOffset));
44 
45     // パッケージ内のテクスチャ情報と比較して一致するものを探す。
46     TPK_SEARCH_DATA data = { texPath, fileNameLen, pTexPackage };
47     int t = search_crc32_data(
48         texHash, header.numTexture, sizeof(CtrTextureHash), crc32key, &data);
49 
50     if(t < 0) return -1;
51     return texHash[t].index;
52 }
53 
54 // テクスチャ取得関数
GetTexture(s32 * mipLevel,u32 * mipmapSize,const void * pTexPackage,const s16 texIndex)55 void* GetTexture(s32* mipLevel, u32* mipmapSize, const void* pTexPackage, const s16 texIndex)
56 {
57     if(!pTexPackage)
58     {
59         NN_TASSERT_(pTexPackage != 0);
60         return 0;
61     }
62 
63     // 指定された番号がテクスチャの枚数に収まっているか確認。
64     const CtrTexturePackageHeader *header =
65         reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
66     NN_TASSERT_((0 <= texIndex) && (texIndex < header->numTexture));
67     if((texIndex < 0) || (header->numTexture <= texIndex))
68     {
69         return 0;
70     }
71 
72     const CtrTextureInfo *texInfo = reinterpret_cast<const CtrTextureInfo *>
73         (((const char*)pTexPackage) + (sizeof(CtrTexturePackageHeader)) + (sizeof(CtrTextureInfo) * texIndex));
74 
75     if(!texInfo)
76     {
77         return 0;
78     }
79 
80     // get texture size.
81     const unsigned int *Size = reinterpret_cast<const unsigned int *>
82         (((const char*)pTexPackage) + (4 * texInfo->bitmapSizeOffset));
83 
84     *mipLevel = static_cast<int>(texInfo->mipLevel);
85     for(int i=0; i < *mipLevel; i++)
86     {
87         mipmapSize[i] = Size[i];
88     }
89 
90     return (void*)(((const char*)pTexPackage) + (header->texDataOffset + texInfo->texDataOffset));
91 }
92 
93 // テクスチャ情報取得関数
GetTextureInfo(CtrTextureInfo * pTexInfo,const void * pTexPackage,const s16 texIndex)94 bool GetTextureInfo(CtrTextureInfo* pTexInfo, const void* pTexPackage, const s16 texIndex)
95 {
96     if(!pTexPackage || !pTexInfo)
97     {
98         NN_TASSERT_((pTexPackage != 0) && (pTexInfo != 0));
99         return false;
100     }
101 
102 
103     // 指定された番号がテクスチャの枚数に収まっているか確認。
104     const CtrTexturePackageHeader *header =
105         reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
106     NN_TASSERT_((0 <= texIndex) && (texIndex < header->numTexture));
107     if((texIndex < 0) || (header->numTexture <= texIndex))
108     {
109         return false;
110     }
111 
112     const CtrTextureInfo *texInfo = reinterpret_cast<const CtrTextureInfo *>
113         (((const char*)pTexPackage) + (sizeof(CtrTexturePackageHeader)) + (sizeof(CtrTextureInfo) * texIndex));
114 
115     pTexInfo->filePathOffset   = texInfo->filePathOffset;
116     pTexInfo->texDataSize      = texInfo->texDataSize;
117     pTexInfo->texDataOffset    = texInfo->texDataOffset;
118     pTexInfo->texFormat        = texInfo->texFormat;
119     pTexInfo->width            = texInfo->width;
120     pTexInfo->height           = texInfo->height;
121     pTexInfo->mipLevel         = texInfo->mipLevel;
122     pTexInfo->type             = texInfo->type;
123     pTexInfo->cubeDir          = texInfo->cubeDir;
124     pTexInfo->bitmapSizeOffset = texInfo->bitmapSizeOffset;
125     pTexInfo->srcFileTime      = texInfo->srcFileTime;
126 
127     return true;
128 }
129 
130 
131 // テクスチャパッケージヘッダーチェック関数(ヘルパー関数)
CheckTexturePackageHeader(const void * pTexPackage)132 bool CheckTexturePackageHeader(const void* pTexPackage)
133 {
134     if(!pTexPackage)
135     {
136         NN_TASSERT_(pTexPackage != 0);
137         return false;
138     }
139 
140     // 指定された番号がテクスチャの枚数に収まっているか確認。
141     const CtrTexturePackageHeader *header =
142         reinterpret_cast<const CtrTexturePackageHeader *>(pTexPackage);
143     NN_TASSERT_(header);
144 
145     // ヘッダのマジックコードを確認。
146     if(::std::strncmp(header->magic, "CTPK", 4) != 0)
147     {
148         NN_LOG("ERROR: The texture package's magic code isn't 'CTPK'.\n");
149         return false;
150     }
151 
152     if(header->version != CTR_TEXTURE_PACKAGE_VERSION)
153     {
154         NN_LOG("ERROR: The texture package's version code differs.\n");
155         return false;
156     }
157 
158     return true;
159 }
160 
161 
162 }}}
163