/*---------------------------------------------------------------------------* Copyright 2010-2011 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. 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. *---------------------------------------------------------------------------*/ #include #include #include #include #include #include "windows/gx2.h" #include "cafe/gfd.h" #include "gfdFile.h" bool GFD_API GFDWriteFileHeader(FILE *fp, GFDGPUVersion gpuVer, GFDAlignMode alignMode) { GFDHeader header; memset(&header, 0, sizeof(header)); header.magic = GFD_SWAP_8_IN_32(GFD_HEADER_MAGIC); header.size = GFD_HEADER_SIZE; header.majorVersion = GFD_HEADER_MAJOR; header.minorVersion = GFD_HEADER_MINOR; header.gpuVersion = gpuVer; header.alignMode = alignMode; return GFDWriteFilePPCData(fp, (GFD_HEADER_SIZE + 3) / 4, GFD_ELEMENT_SIZE_32, (u32 *) &header); } bool GFD_API GFDWriteFileBlockHeader(FILE *fp, GFDBlockType type, u32 size) { GFDBlockHeader blockHeader; memset(&blockHeader, 0, sizeof(blockHeader)); blockHeader.magic = GFD_SWAP_8_IN_32(GFD_BLOCK_HEADER_MAGIC); blockHeader.size = GFD_BLOCK_HEADER_SIZE; blockHeader.type = type; blockHeader.majorVersion = GFD_BLOCK_HEADER_MAJOR; blockHeader.minorVersion = GFD_BLOCK_HEADER_MINOR; blockHeader.dataSize = size; // following data block size in bytes, doesn't include this header return GFDWriteFilePPCData(fp, (GFD_BLOCK_HEADER_SIZE + 3) / 4, GFD_ELEMENT_SIZE_32, (u32 *) &blockHeader); } bool GFD_API GFDWriteFileGPUData(FILE *fp, u32 numElements, GFDElementSize elemSize, GFDEndianSwapMode swapMode, void *pData) { size_t retWords = 0; // Set Swap Enable if(swapMode == GFD_ENDIAN_SWAP_MODE_8_IN_32) { u32 scale = GFD_ELEMENT_SIZE_32/elemSize; u32 elems = (numElements + scale - 1)/scale; // Swap Endian GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32); // Write data retWords = fwrite((u32*)pData, GFD_ELEMENT_SIZE_32, elems, fp); // Revert Endian GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32); } else if((swapMode == (GFD_ENDIAN_SWAP_MODE_8_IN_32 | GFD_ENDIAN_SWAP_MODE_BIG)) && _GFD_LITTLE_ENDIAN_CPU) { u32 scale = GFD_ELEMENT_SIZE_32/elemSize; u32 elems = (numElements + scale - 1)/scale; // Swap Endian GFDEndianSwap(pData, numElements, elemSize); // Swap Endian GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32); // Write data retWords = fwrite((u32*)pData, GFD_ELEMENT_SIZE_32, elems, fp); // Revert Endian GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32); // Revert Endian GFDEndianSwap(pData, numElements, elemSize); } else if((swapMode == GFD_ENDIAN_SWAP_MODE_BIG) && _GFD_LITTLE_ENDIAN_CPU) { // Swap Endian GFDEndianSwap(pData, numElements, elemSize); // Write data retWords = fwrite(pData, elemSize, numElements, fp); // Revert Endian GFDEndianSwap(pData, numElements, elemSize); } else { // Write data retWords = fwrite(pData, elemSize, numElements, fp); } if(retWords != numElements) return false; return true; } errno_t GFD_API GFDOpenFile(FILE **fp, const char* fileName, const char *mode) { // ABoggs - Adding more logging to determine why this is failing in autotest. (Bug8147) errno_t err = fopen_s(fp, fileName, mode); if( err != 0 ) perror( "An error occurred in GFDOpenFile" ); return( err ); } int GFD_API GFDCloseFile(FILE *fp) { return fclose(fp); } bool GFD_API GFDReadFileGPUData(void *pData, u32 numElements, GFDElementSize elemSize, GFDEndianSwapMode swapMode, FILE *fp) { // read data size_t retWords = fread( pData, elemSize, numElements , fp); if(retWords != numElements) return false; // Set Swap Enable if(swapMode == GFD_ENDIAN_SWAP_MODE_8_IN_32) { u32 scale = GFD_ELEMENT_SIZE_32/elemSize; u32 elems = (numElements + scale - 1)/scale; // Swap Endian GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32); } else if((swapMode == (GFD_ENDIAN_SWAP_MODE_8_IN_32 | GFD_ENDIAN_SWAP_MODE_BIG)) && _GFD_LITTLE_ENDIAN_CPU) { u32 scale = GFD_ELEMENT_SIZE_32/elemSize; u32 elems = (numElements + scale - 1)/scale; // Swap Endian GFDEndianSwap((u32*)pData, elems, GFD_ELEMENT_SIZE_32); // Swap Endian GFDEndianSwap(pData, numElements, elemSize); } else if((swapMode == GFD_ENDIAN_SWAP_MODE_BIG) && _GFD_LITTLE_ENDIAN_CPU) { // Swap Endian GFDEndianSwap(pData, numElements, elemSize); } return true; } bool GFD_API GFDWriteFilePadBlock(FILE *fp, u32 padSize) { if(padSize < 0) return false; // write header for pad header if(!GFDWriteFileBlockHeader(fp, GFD_BLOCK_TYPE_PAD, padSize)) return false; // seek file pointer for padding fseek(fp, padSize, SEEK_CUR); return true; }