1 /*---------------------------------------------------------------------------*
2
3 Copyright 2010-2011 Nintendo. All rights reserved.
4
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10
11 *---------------------------------------------------------------------------*/
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <assert.h>
16 #include <types.h>
17 #include <stdlib.h>
18
19 #include "windows/gx2.h"
20
21 #include "cafe/gfd.h"
22 #include "gfdFile.h"
23
GFDWriteFileHeader(FILE * fp,GFDGPUVersion gpuVer,GFDAlignMode alignMode)24 bool GFD_API GFDWriteFileHeader(FILE *fp, GFDGPUVersion gpuVer, GFDAlignMode alignMode)
25 {
26 GFDHeader header;
27 memset(&header, 0, sizeof(header));
28 header.magic = GFD_SWAP_8_IN_32(GFD_HEADER_MAGIC);
29 header.size = GFD_HEADER_SIZE;
30 header.majorVersion = GFD_HEADER_MAJOR;
31 header.minorVersion = GFD_HEADER_MINOR;
32 header.gpuVersion = gpuVer;
33 header.alignMode = alignMode;
34
35 return GFDWriteFilePPCData(fp, (GFD_HEADER_SIZE + 3) / 4, GFD_ELEMENT_SIZE_32, (u32 *) &header);
36 }
37
GFDWriteFileBlockHeader(FILE * fp,GFDBlockType type,u32 size)38 bool GFD_API GFDWriteFileBlockHeader(FILE *fp, GFDBlockType type, u32 size)
39 {
40 GFDBlockHeader blockHeader;
41 memset(&blockHeader, 0, sizeof(blockHeader));
42 blockHeader.magic = GFD_SWAP_8_IN_32(GFD_BLOCK_HEADER_MAGIC);
43 blockHeader.size = GFD_BLOCK_HEADER_SIZE;
44 blockHeader.type = type;
45 blockHeader.majorVersion = GFD_BLOCK_HEADER_MAJOR;
46 blockHeader.minorVersion = GFD_BLOCK_HEADER_MINOR;
47
48 blockHeader.dataSize = size; // following data block size in bytes, doesn't include this header
49
50 return GFDWriteFilePPCData(fp, (GFD_BLOCK_HEADER_SIZE + 3) / 4, GFD_ELEMENT_SIZE_32, (u32 *) &blockHeader);
51 }
52
GFDWriteFileGPUData(FILE * fp,u32 numElements,GFDElementSize elemSize,GFDEndianSwapMode swapMode,void * pData)53 bool GFD_API GFDWriteFileGPUData(FILE *fp, u32 numElements, GFDElementSize elemSize, GFDEndianSwapMode swapMode, void *pData)
54 {
55 size_t retWords = 0;
56
57 // Set Swap Enable
58 if(swapMode == GFD_ENDIAN_SWAP_MODE_8_IN_32)
59 {
60 u32 scale = GFD_ELEMENT_SIZE_32/elemSize;
61 u32 elems = (numElements + scale - 1)/scale;
62
63 // Swap Endian
64 GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32);
65
66 // Write data
67 retWords = fwrite((u32*)pData, GFD_ELEMENT_SIZE_32, elems, fp);
68
69 // Revert Endian
70 GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32);
71 }
72 else if((swapMode == (GFD_ENDIAN_SWAP_MODE_8_IN_32 | GFD_ENDIAN_SWAP_MODE_BIG)) && _GFD_LITTLE_ENDIAN_CPU)
73 {
74 u32 scale = GFD_ELEMENT_SIZE_32/elemSize;
75 u32 elems = (numElements + scale - 1)/scale;
76
77 // Swap Endian
78 GFDEndianSwap(pData, numElements, elemSize);
79
80 // Swap Endian
81 GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32);
82
83 // Write data
84 retWords = fwrite((u32*)pData, GFD_ELEMENT_SIZE_32, elems, fp);
85
86 // Revert Endian
87 GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32);
88
89 // Revert Endian
90 GFDEndianSwap(pData, numElements, elemSize);
91 }
92 else if((swapMode == GFD_ENDIAN_SWAP_MODE_BIG) && _GFD_LITTLE_ENDIAN_CPU)
93 {
94 // Swap Endian
95 GFDEndianSwap(pData, numElements, elemSize);
96
97 // Write data
98 retWords = fwrite(pData, elemSize, numElements, fp);
99
100 // Revert Endian
101 GFDEndianSwap(pData, numElements, elemSize);
102 }
103 else
104 {
105 // Write data
106 retWords = fwrite(pData, elemSize, numElements, fp);
107 }
108
109 if(retWords != numElements)
110 return false;
111
112 return true;
113 }
114
GFDOpenFile(FILE ** fp,const char * fileName,const char * mode)115 errno_t GFD_API GFDOpenFile(FILE **fp, const char* fileName, const char *mode)
116 {
117 // ABoggs - Adding more logging to determine why this is failing in autotest. (Bug8147)
118 errno_t err = fopen_s(fp, fileName, mode);
119 if( err != 0 )
120 perror( "An error occurred in GFDOpenFile" );
121 return( err );
122 }
123
GFDCloseFile(FILE * fp)124 int GFD_API GFDCloseFile(FILE *fp)
125 {
126 return fclose(fp);
127 }
128
GFDReadFileGPUData(void * pData,u32 numElements,GFDElementSize elemSize,GFDEndianSwapMode swapMode,FILE * fp)129 bool GFD_API GFDReadFileGPUData(void *pData, u32 numElements, GFDElementSize elemSize, GFDEndianSwapMode swapMode, FILE *fp)
130 {
131 // read data
132 size_t retWords = fread( pData, elemSize, numElements , fp);
133
134 if(retWords != numElements)
135 return false;
136
137 // Set Swap Enable
138 if(swapMode == GFD_ENDIAN_SWAP_MODE_8_IN_32)
139 {
140 u32 scale = GFD_ELEMENT_SIZE_32/elemSize;
141 u32 elems = (numElements + scale - 1)/scale;
142
143 // Swap Endian
144 GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32);
145 }
146 else if((swapMode == (GFD_ENDIAN_SWAP_MODE_8_IN_32 | GFD_ENDIAN_SWAP_MODE_BIG)) && _GFD_LITTLE_ENDIAN_CPU)
147 {
148 u32 scale = GFD_ELEMENT_SIZE_32/elemSize;
149 u32 elems = (numElements + scale - 1)/scale;
150
151 // Swap Endian
152 GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32);
153
154 // Swap Endian
155 GFDEndianSwap(pData, numElements, elemSize);
156 }
157 else if((swapMode == GFD_ENDIAN_SWAP_MODE_BIG) && _GFD_LITTLE_ENDIAN_CPU)
158 {
159 // Swap Endian
160 GFDEndianSwap(pData, numElements, elemSize);
161 }
162 return true;
163 }
164
GFDWriteFilePadBlock(FILE * fp,u32 padSize)165 bool GFD_API GFDWriteFilePadBlock(FILE *fp, u32 padSize)
166 {
167 if(padSize < 0)
168 return false;
169
170 // write header for pad header
171 if(!GFDWriteFileBlockHeader(fp, GFD_BLOCK_TYPE_PAD, padSize))
172 return false;
173
174 // seek file pointer for padding
175 fseek(fp, padSize, SEEK_CUR);
176
177 return true;
178 }
179