// Verifies that directory exists.
// Returns success if the directory exists and is readable (failure may mean
// it's busy or permissions denied on win32)
//-----------------------------------------------------------------------------
CPUTResult CPUTFileSystem::DoesDirectoryExist(const cString &path)
{
#ifdef CPUT_OS_ANDROID
    // On Android, all files are in the APK and are compressed.
    // We do not have access to the standard file system, so
    // all files need streaming from memory through the android asset manager
    AAssetManager* assetManager = CPUTWindowAndroid::GetAppState()->activity->assetManager;
    
    AAssetDir* AssetDir = AAssetManager_openDir(assetManager, path.c_str());
    if (AssetDir)
        return CPUT_SUCCESS;
#else
    struct stat fileAttributes;
    
    int result = stat(path.c_str(), &fileAttributes);
    if (result == -1) {
        DEBUG_ERROR(strerror(errno));
        result = CPUT_ERROR; 
    }
	
    if (S_ISDIR(fileAttributes.st_mode)) {
        return CPUT_SUCCESS;
    }
#endif
    return CPUT_ERROR;
}
// Read the entire contents of a file and return a pointer/size to it
//-----------------------------------------------------------------------------
CPUTResult CPUTFileSystem::ReadFileContents(const cString &fileName, UINT *pSizeInBytes, void **ppData, bool bAddTerminator, bool bLoadAsBinary)
{
    FILE *pFile = NULL;

    errno_t err;
    if (bLoadAsBinary) {
#if defined (UNICODE) || defined(_UNICODE)
        err = _wfopen_s(&pFile, fileName.c_str(), _L("rb"));
#else
        err = fopen_s(&pFile, fileName.c_str(), "rb");
#endif
    } else {
#if defined (UNICODE) || defined(_UNICODE)
        err = _wfopen_s(&pFile, fileName.c_str(), _L("r"));
#else
        err = fopen_s(&pFile, fileName.c_str(), "r");
#endif
    }

    if(0 == err)
    {
        // get file size
        fseek(pFile, 0, SEEK_END);
        *pSizeInBytes = ftell(pFile);
        fseek (pFile, 0, SEEK_SET);

        // allocate buffer
        *ppData = (void*) new char[*pSizeInBytes];
        ASSERT( *ppData, _L("Out of memory") );

        // read it all in
        UINT numBytesRead = (UINT) fread(*ppData, sizeof(char), *pSizeInBytes, pFile);
        if (bAddTerminator)
        {
            ((char *)(*ppData))[numBytesRead++] = '\0';
            (*pSizeInBytes)++;
        }
        //fixme - this isn't doing what it appears to be doing. counts off for Windows...
        //ASSERT( numBytesRead == *pSizeInBytes, _L("File read byte count mismatch.") );
        UNREFERENCED_PARAMETER(numBytesRead);

        // close and return
        fclose(pFile);
        return CPUT_SUCCESS;
    }

    // some kind of file error, translate the error code and return it
    return TranslateFileError(err);
}
//-----------------------------------------------------------------------------
CPUTResult CPUTTextureDX11::CreateNativeTexture(
    ID3D11Device *pD3dDevice,
    const cString &fileName,
    ID3D11ShaderResourceView **ppShaderResourceView,
    ID3D11Resource **ppTexture,
    bool ForceLoadAsSRGB)
{
    HRESULT hr;

    hr = DirectX::CreateDDSTextureFromFileEx(
        pD3dDevice,
        fileName.c_str(),
        0,//maxsize
        D3D11_USAGE_DEFAULT,
        D3D11_BIND_SHADER_RESOURCE,
        0,
        0,
        ForceLoadAsSRGB,
        ppTexture,
        ppShaderResourceView);
	if( FAILED( hr ) )
	{
		ASSERT( false, _L("Failed to load texture: ") + fileName )
		return CPUT_TEXTURE_LOAD_ERROR;
	}

    CPUTSetDebugName( *ppTexture, fileName );
    CPUTSetDebugName( *ppShaderResourceView, fileName );

    return CPUT_SUCCESS;
}
CPUTFileSystem::CPUTandroidifstream::CPUTandroidifstream(const cString &fileName, std::ios_base::openmode mode) : iCPUTifstream(fileName, mode)
{
    mpAsset = NULL;
    mpAssetDir = NULL;
    mbEOF = true;
    
    // Extract the file and dir
    int length = fileName.length();
    int index = fileName.find_last_of("\\/");
    cString file = fileName.substr(index + 1, (length - 1 - index));
    cString dir  = fileName.substr(0, index);
    
    // On Android, all files are in the APK and are compressed.
    // We do not have access to the standard file system, so
    // all files need streaming from memory through the android asset manager
    AAssetManager* assetManager = CPUTWindowAndroid::GetAppState()->activity->assetManager;
    
    mpAssetDir = AAssetManager_openDir(assetManager, dir.c_str());
    if (!mpAssetDir)
        DEBUG_PRINT("Failed to load asset Dir");
    
    const char* assetFileName = NULL;
    while ((assetFileName = AAssetDir_getNextFileName(mpAssetDir)) != NULL) 
    {
        if (strcmp(file.c_str(), assetFileName) == 0)
        {
            // For some reason we need to pass in the fully pathed filename here, rather than the relative filename
            // that we have just been given. This feels like a bug in Android!
            mpAsset = AAssetManager_open(assetManager, fileName.c_str()/*assetFileName*/, AASSET_MODE_STREAMING);
            if (mpAsset)
                mbEOF = false;
            return;
        }
    }
}
// Use DX11 compile from file method to do all the heavy lifting
//-----------------------------------------------------------------------------
CPUTResult CPUTAssetLibraryDX11::CompileShaderFromMemory(
    const char     *pShaderSource,
    const cString  &shaderMain,
    const cString  &shaderProfile,
    ID3DBlob      **ppBlob
)
{
    CPUTResult result = CPUT_SUCCESS;

    char pShaderMainAsChar[128];
    char pShaderProfileAsChar[128];
    ASSERT( shaderMain.length()     < 128, _L("Shader main name '")    + shaderMain    + _L("' longer than 128 chars.") );
    ASSERT( shaderProfile.length()  < 128, _L("Shader profile name '") + shaderProfile + _L("' longer than 128 chars.") );
    size_t count;
    wcstombs_s( &count, pShaderMainAsChar,    shaderMain.c_str(),    128 );
    wcstombs_s( &count, pShaderProfileAsChar, shaderProfile.c_str(), 128 );

    // use DirectX to compile the shader file
    ID3DBlob *pErrorBlob = NULL;
    D3D10_SHADER_MACRO pShaderMacros[2] = { "_CPUT", "1", NULL, NULL }; // TODO: Support passed-in, and defined in .mtl file.  Perhaps under [Shader Defines], etc
    char *pShaderMainAsChars = ws2s(shaderMain.c_str());
    HRESULT hr = D3DX11CompileFromMemory(
        pShaderSource,     // shader as a string
        strlen( pShaderSource ), //
        pShaderMainAsChars, // Use entrypoint as file name
        pShaderMacros,        // macro define's
        NULL,                 // includes
        pShaderMainAsChar,    // main function name
        pShaderProfileAsChar, // shader profile/feature level
        0,                    // flags 1
        0,                    // flags 2
        NULL,                 // threaded load? (no for right now)
        ppBlob,               // blob data with compiled code
        &pErrorBlob,          // any compile errors stored here
        NULL
    );
    ASSERT( SUCCEEDED(hr), _L("Error compiling shader '") + shaderMain + _L("'.\n") + (pErrorBlob ? s2ws((char*)pErrorBlob->GetBufferPointer()) : _L("no error message") ) );
    if(pErrorBlob)
    {
        pErrorBlob->Release();
    }
    delete pShaderMainAsChars;
    return result;
}
CPUTKey MapKey(cString strKey)
{
    for(int i = 0; i < KEY_NUM_KEYS; i++)
    {
        if( 0 == strKey.compare(CPUTKeyMap[i].name))
            return CPUTKeyMap[i].value;
    }
    DEBUG_PRINT(_L("Unknown Key: %s"), strKey.c_str());
    return KEY_NUM_KEYS;
}
// Open a file and return file pointer to it
//-----------------------------------------------------------------------------
CPUTResult CPUTFileSystem::OpenFile(const cString &fileName, FILE **ppFilePointer)
{
#ifdef CPUT_OS_ANDROID
    DEBUG_PRINT("OpenFile stubbed");
#else
    *ppFilePointer = fopen(fileName.c_str(), "r");
    
    if (*ppFilePointer == NULL) {
        return CPUT_ERROR;
    }
#endif    
    return CPUT_SUCCESS;
}
void CPUTGUIElement::SetText(cString string)
{
    DEBUG_PRINT(_L("GUIElement SetText: %s"), string.c_str());
    mText = string;
    if(mpFont && mpTextMaterial)
    {
        DEBUG_PRINT(_L("\t have font and material"));
        if(!mpTextMesh)
        {
#ifdef CPUT_FOR_DX11
            mpTextMesh = new CPUTMeshDX11();
#else
            mpTextMesh = new CPUTMeshOGL();
#endif
        }
        unsigned int numCharacters = (unsigned int) string.size();
        unsigned int numVertices = numCharacters * 6;
        CPUTGUIVertex* pVB = new CPUTGUIVertex[numVertices];

        CPUTBufferElementInfo pGUIVertex[3] = {
            { "POSITION", 0, 0, CPUT_F32, 3, 3*sizeof(float), 0 },            
            { "TEXCOORD", 0, 1, CPUT_F32, 2, 2*sizeof(float), 3*sizeof(float)},
            { "COLOR",    0, 2, CPUT_F32, 4, 4*sizeof(float), 5*sizeof(float)},
        };
        mpFont->LayoutText(NULL, &mTextWidth, &mTextHeight, mText, 0, 0);
        mTextX = (mWidth-mTextWidth)/2;
        mTextY = (mHeight-mTextHeight)/2;
        mpFont->LayoutText(pVB, &mTextWidth, &mTextHeight, mText, 0, 0);
        mpTextMesh->CreateNativeResources(NULL, 1, 3, pGUIVertex, numVertices, pVB, NULL, 0, NULL);
        
#ifdef CPUT_FOR_DX11
        mpTextMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST);
        
        D3D11_INPUT_ELEMENT_DESC layout[] =
        {
            { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },            
            { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
            { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        };
        UINT numElements = ARRAYSIZE( layout );
        ID3DBlob* pBlob = ((CPUTMaterialEffectDX11*)mpTextMaterial->GetMaterialEffects()[0])->GetVertexShader()->GetBlob();
        
        CPUT_DX11::GetDevice()->CreateInputLayout( layout, numElements, pBlob->GetBufferPointer(), pBlob->GetBufferSize(), &mpVertexLayout );
        CPUTSetDebugName( mpVertexLayout, "CPUT GUI InputLayout object");
#else
#endif
        SAFE_DELETE_ARRAY(pVB);
    }
}
int GetEventValue(StringMap eventMap[], cString event)
{
    int i = 0; 
    while(eventMap[i].value > 0)
    {
        if(event.compare(eventMap[i].key) == 0)
        {
            DEBUG_PRINT(_L("Found Event: %s\n"), event.c_str());
            return eventMap[i].value;

        }
        i++;
    }
    return -1;
}
Example #10
0
//-----------------------------------------------------------------------------
void CPUTSetDebugName( void *pResource, cString name )
{
#ifdef _DEBUG
    char pCharString[CPUT_MAX_STRING_LENGTH];
    const wchar_t *pWideString = name.c_str();
    UINT ii;
    UINT length = min( (UINT)name.length(), (CPUT_MAX_STRING_LENGTH-1));
    for(ii=0; ii<length; ii++)
    {
        pCharString[ii] = (char)pWideString[ii];
    }
    pCharString[ii] = 0; // Force NULL termination
    ((ID3D11DeviceChild*)pResource)->SetPrivateData( WKPDID_D3DDebugObjectName, (UINT)name.length(), pCharString );
#endif // _DEBUG
}
// Verifies that file exists at specified path
// // #### this should probably just return a bool
//-----------------------------------------------------------------------------
CPUTResult CPUTFileSystem::DoesFileExist(const cString &pathAndFilename)
{
#ifdef CPUT_OS_ANDROID
    DEBUG_PRINT("DoesFileExist stubbed");
#else
    struct stat fileAttributes;
    
    int result = stat(pathAndFilename.c_str(), &fileAttributes);
    if (result == -1) {
        DEBUG_ERROR(strerror(errno));
        result = CPUT_ERROR; 
    }
	
    if (S_ISREG(fileAttributes.st_mode)) {
        return CPUT_SUCCESS;
    }
#endif    
    return CPUT_ERROR;
}
// Takes a relative/full path+fileName and returns the absolute path with drive
// letter, absolute path, fileName and extension of this file.
// Truncates total path/file length to CPUT_MAX_PATH
//-----------------------------------------------------------------------------
CPUTResult CPUTFileSystem::ResolveAbsolutePathAndFilename(const cString &fileName, cString *pResolvedPathAndFilename)
{
    CPUTResult  result   = CPUT_SUCCESS;
#ifdef CPUT_OS_ANDROID
    pResolvedPathAndFilename->assign(fileName);
#else
    char       *fullPath = NULL;

    fullPath = realpath(fileName.c_str(), NULL);
    if (fullPath == NULL) {
        DEBUG_ERROR(fileName);
        DEBUG_ERROR(strerror(errno));
        result = CPUT_ERROR;
        return result;
    }
    
    pResolvedPathAndFilename->assign(fullPath);
    
    free(fullPath); // realpath() mallocs the memory required to hold the path name, so we need to free it
#endif
    return result;
}
Example #13
0
// Pop up a message box with specified title/text
//-----------------------------------------------------------------------------
void CPUT_DX11::CPUTMessageBox(const cString DialogBoxTitle, const cString DialogMessage)
{
    CPUTOSServices::GetOSServices()->OpenMessageBox(DialogBoxTitle.c_str(), DialogMessage.c_str());
}
Example #14
0
//-----------------------------------------------------------------------------
CPUTResult CPUTModel::LoadModelPayload(const cString &File)
{
    CPUTResult result = CPUT_SUCCESS;

    std::ifstream file(File.c_str(), std::ios::in | std::ios::binary);
    ASSERT( !file.fail(), _L("CPUTModelDX11::LoadModelPayload() - Could not find binary model file: ") + File );

    // set up for mesh creation loop
    UINT meshIndex = 0;
    while(file.good() && !file.eof())
    {
        // TODO: rearrange while() to avoid if(eof).  Should perform only one branch per loop iteration, not two
        CPUTRawMeshData vertexFormatDesc;
        vertexFormatDesc.Read(file);
        if(file.eof())
        {
            // TODO:  Wtf?  Why would we get here?  We check eof at the top of loop.  If it isn't eof there, why is it eof here?
            break;
        }
        ASSERT( meshIndex < mMeshCount, _L("Actual mesh count doesn't match stated mesh count"));

        // create the mesh.
        CPUTMesh *pMesh = mpMesh[meshIndex];

        // always a triangle list (at this point)
        pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST);

        // get number of data blocks in the vertex element (pos,norm,uv,etc)
        // YUCK! TODO: Use fixed-size array of elements
        CPUTBufferInfo *pVertexElementInfo = new CPUTBufferInfo[vertexFormatDesc.mFormatDescriptorCount];
        // pMesh->SetBounds(vertexFormatDesc.mBboxCenter, vertexFormatDesc.mBboxHalf);

        // running count of each type of  element
        int positionStreamCount=0;
        int normalStreamCount=0;
        int texCoordStreamCount=0;
        int tangentStreamCount=0;
        int binormalStreamCount=0;
        int colorStreamCount=0;

        int RunningOffset = 0;
        for(UINT ii=0; ii<vertexFormatDesc.mFormatDescriptorCount; ii++)
        {
            // lookup the CPUT data type equivalent
            pVertexElementInfo[ii].mElementType = CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT[vertexFormatDesc.mpElements[ii].mVertexElementType];
            ASSERT((pVertexElementInfo[ii].mElementType !=CPUT_UNKNOWN ) , _L(".MDL file load error.  This model file has an unknown data type in it's model data."));
            // calculate the number of elements in this stream block (i.e. F32F32F32 = 3xF32)
            pVertexElementInfo[ii].mElementComponentCount = vertexFormatDesc.mpElements[ii].mElementSizeInBytes/CPUT_DATA_FORMAT_SIZE[pVertexElementInfo[ii].mElementType];
            // store the size of each element type in bytes (i.e. 3xF32, each element = F32 = 4 bytes)
            pVertexElementInfo[ii].mElementSizeInBytes = vertexFormatDesc.mpElements[ii].mElementSizeInBytes;
            // store the number of elements (i.e. 3xF32, 3 elements)
            pVertexElementInfo[ii].mElementCount = vertexFormatDesc.mVertexCount;
            // calculate the offset from the first element of the stream - assumes all blocks appear in the vertex stream as the order that appears here
            pVertexElementInfo[ii].mOffset = RunningOffset;
            RunningOffset = RunningOffset + pVertexElementInfo[ii].mElementSizeInBytes;

            // extract the name of stream
            pVertexElementInfo[ii].mpSemanticName = CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[ii];

            switch(vertexFormatDesc.mpElements[ii].mVertexElementSemantic)
            {
            case CPUT_VERTEX_ELEMENT_POSITON:
                pVertexElementInfo[ii].mpSemanticName = "POSITION";
                pVertexElementInfo[ii].mSemanticIndex = positionStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_NORMAL:
                pVertexElementInfo[ii].mpSemanticName = "NORMAL";
                pVertexElementInfo[ii].mSemanticIndex = normalStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_TEXTURECOORD:
                pVertexElementInfo[ii].mpSemanticName = "TEXCOORD";
                pVertexElementInfo[ii].mSemanticIndex = texCoordStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_TANGENT:
                pVertexElementInfo[ii].mpSemanticName = "TANGENT";
                pVertexElementInfo[ii].mSemanticIndex = tangentStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_BINORMAL:
                pVertexElementInfo[ii].mpSemanticName = "BINORMAL";
                pVertexElementInfo[ii].mSemanticIndex = binormalStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_VERTEXCOLOR:
                pVertexElementInfo[ii].mpSemanticName = "COLOR";
                pVertexElementInfo[ii].mSemanticIndex = colorStreamCount++;
                break;
            default:
                cString errorString = _L("Invalid vertex semantic in: '")+File+_L("'\n");
                TRACE(errorString.c_str());
                ASSERT(0, errorString);
            }
        }

        // Index buffer
        CPUTBufferInfo indexDataInfo;
        indexDataInfo.mElementType           = (vertexFormatDesc.mIndexType == tUINT32) ? CPUT_U32 : CPUT_U16;
        indexDataInfo.mElementComponentCount = 1;
        indexDataInfo.mElementSizeInBytes    = (vertexFormatDesc.mIndexType == tUINT32) ? sizeof(UINT32) : sizeof(UINT16);
        indexDataInfo.mElementCount          = vertexFormatDesc.mIndexCount;
        indexDataInfo.mOffset                = 0;
        indexDataInfo.mSemanticIndex         = 0;
        indexDataInfo.mpSemanticName         = NULL;

        if( pVertexElementInfo->mElementCount && indexDataInfo.mElementCount )
        {
            result = pMesh->CreateNativeResources(
                this,
                meshIndex,
                vertexFormatDesc.mFormatDescriptorCount,
                pVertexElementInfo,
                (void*)vertexFormatDesc.mpVertices,
                &indexDataInfo,
                &vertexFormatDesc.mpIndices[0]
            );
            if(CPUTFAILED(result))
            {
                return result;
            }

            // CC added
            result = pMesh->ExtractVerticesandIndices();
            if(CPUTFAILED(result))
            {
                return result;  
            }
            // CC added ends
        }
        delete [] pVertexElementInfo;
        pVertexElementInfo = NULL;
        ++meshIndex;
    }
    ASSERT( file.eof(), _L("") );

    // close file
    file.close();

    return result;
}
// load a file and return it's contents
//-----------------------------------------------------------------------------
CPUTResult CPUTAssetLibraryOGLES::LoadShaderFileString(const cString Filename, void** ppData)
{
    if(NULL == ppData)
    {
        ASSERT( ppData, _L("Invalid data pointer for storing shader string"));
        return CPUT_ERROR_INVALID_PARAMETER;
    }

    FILE* pFile = NULL;
#if defined (UNICODE) || defined(_UNICODE)
    errno_t err = _wfopen_s(&pFile, Filename.c_str(), _L("r"));
#else
    errno_t err = fopen_s(&pFile, Filename.c_str(), _L("r"));
#endif
    ASSERT( (0 == err), _L("Error loading shader file: ")+Filename);
    if(0 != err)
    {
        // error opening file
        //        char message[250];
        //        sprintf_s(message, 250, "Could not find file: %s\n", filename);
        //        MessageBox("Error: Load file", message, CPUT_MB_ERROR);

        return CPUT_ERROR_FILE_NOT_FOUND;
    }


    // file open - read contents
    // get file size
    err = fseek( pFile, 0, SEEK_END );
    ASSERT( (0 == err), _L("Error reading contents of shader file: ")+Filename);
    if(0!=err)
    {
        //        char message[250];
        //        sprintf_s(message, 250, "Error getting file size: %s\n", filename);
        //        MessageBox("Error: Load file", message, CPUT_MB_ERROR);
        fclose(pFile);
        return CPUT_ERROR_FILE_READ_ERROR;
    }

    long endPos = ftell( pFile );

    fseek( pFile, 0, SEEK_SET );
    ASSERT( (0 == err), _L("Error getting size of shader file: ")+Filename);
    if(0!=err)
    {
        //        char message[250];
        //        sprintf_s(message, 250, "Error getting file size: %s\n", filename);
        //        MessageBox("Error: Load file", message, CPUT_MB_ERROR);
        fclose(pFile);
        return CPUT_ERROR_FILE_READ_ERROR;
    }

    // allocate buffer
    char* pContents = new char[endPos+1];

    // read the contents!
    size_t actuallyRead = fread(pContents, sizeof(char), endPos, pFile);
    pContents[actuallyRead] = '\0'; // always null terminate on your own - not guaranteed by fread()

    // close file
    err = fclose(pFile);
    ASSERT( (0 == err), _L("Error closing shader file: ")+Filename);

    
    if(pFile)
    {   
        if(0 != err)
        {
            // file did not close properly!
            //           char message[250];
            //           sprintf_s(message, 250, "File did not close properly: %s\n", filename);
            //           MessageBox("Error: Load file", message, CPUT_MB_ERROR);
            delete [] pContents;
            return CPUT_ERROR_FILE_CLOSE_ERROR;
        }
    }

    // set the return buffer
    *ppData = pContents;

    return CPUT_SUCCESS;
}
// Read the entire contents of a file and return a pointer/size to it
//-----------------------------------------------------------------------------
CPUTResult CPUTFileSystem::ReadFileContents(const cString &fileName, UINT *pSizeInBytes, void **ppData, bool bAddTerminator, bool bLoadAsBinary)
{
#ifdef CPUT_OS_ANDROID
    // Extract the file and dir
    int length = fileName.length();
    int index = fileName.find_last_of("\\/");
    cString file = fileName.substr(index + 1, (length - 1 - index));
    cString dir  = fileName.substr(0, index);
    
    DEBUG_PRINT("ReadFileContents(%s) : dir [%s], file [%s]", fileName.c_str(), dir.c_str(), file.c_str());
    
    
    // On Android, all files are in the APK and are compressed.
    // We do not have access to the standard file system, so
    // all files need streaming from memory through the android asset manager
    AAssetManager* assetManager = CPUTWindowAndroid::GetAppState()->activity->assetManager;
    
    AAssetDir* assetDir = AAssetManager_openDir(assetManager, dir.c_str());
    if (!assetDir)
        DEBUG_PRINT("Failed to load asset Dir");
    
    const char* assetFileName = NULL;
    while ((assetFileName = AAssetDir_getNextFileName(assetDir)) != NULL) 
    {
        if (strcmp(file.c_str(), assetFileName) == 0)
        {
            // For some reason we need to pass in the fully pathed filename here, rather than the relative filename
            // that we have just been given. This feels like a bug in Android!
            AAsset* asset = AAssetManager_open(assetManager, fileName.c_str()/*assetFileName*/, AASSET_MODE_STREAMING);
            if (!asset)
            {
                DEBUG_PRINT("Asset failed to load for file %s", fileName.c_str());
                return CPUT_ERROR;
            }
            
            *pSizeInBytes = AAsset_getLength(asset);
            
            // allocate buffer
            if (bAddTerminator)
                *ppData = (void*) new char[*pSizeInBytes + 1];
            else
                *ppData = (void*) new char[*pSizeInBytes];
            
            if (!*ppData)
            {
                DEBUG_PRINT("Out of memory loading %s", fileName.c_str());
                return CPUT_ERROR;
            }
                
            // read it all in
            int numBytesRead = AAsset_read(asset, *ppData, *pSizeInBytes);
            if (bAddTerminator)
            {
                ((char *)(*ppData))[numBytesRead++] = '\0';
                *pSizeInBytes++;
            }
            ASSERT( numBytesRead == *pSizeInBytes, _L("File read byte count mismatch.") );
            
            AAsset_close(asset);
            AAssetDir_close(assetDir);    
            return CPUT_SUCCESS;
        }
    }
    AAssetDir_close(assetDir);    
#else
    FILE *pFile = NULL;

    if (bLoadAsBinary) {
#if defined (UNICODE) || defined(_UNICODE)
    	_wfopen_s(&pFile, fileName.c_str(), _L("r"));
#else
    	pFile = fopen(fileName.c_str(), "r");
#endif
    } else {
#if defined (UNICODE) || defined(_UNICODE)
    	_wfopen_s(&pFile, fileName.c_str(), _L("r"));
#else
    	pFile = fopen(fileName.c_str(), "r");
#endif
    }

    if(pFile)
    {
        // get file size
        fseek(pFile, 0, SEEK_END);
        *pSizeInBytes = ftell(pFile);
        fseek (pFile, 0, SEEK_SET);

        // allocate buffer
        *ppData = (void*) new char[*pSizeInBytes];
        ASSERT( *ppData, _L("Out of memory") );

        // read it all in
        UINT numBytesRead = (UINT) fread(*ppData, sizeof(char), *pSizeInBytes, pFile);
        if (bAddTerminator)
        {
            ((char *)(*ppData))[numBytesRead++] = '\0';
            *pSizeInBytes++;
        }
        ASSERT( numBytesRead == *pSizeInBytes, _L("File read byte count mismatch.") );

        // close and return
        fclose(pFile);
        return CPUT_SUCCESS;
    }

#endif    
    // some kind of file error, translate the error code and return it
    return CPUT_ERROR;
//    return TranslateFileError(err);

}
// Pop up a message box with specified title/text
//-----------------------------------------------------------------------------
void CPUT_OGL::CPUTMessageBox(const cString DialogBoxTitle, const cString DialogMessage)
{
    CPUTOSServices::OpenMessageBox(DialogBoxTitle.c_str(), DialogMessage.c_str());
}
Example #18
0
CPUTResult CPUTTextureDX11::CreateNativeTexture(
    ID3D11Device *pD3dDevice,
    const cString &fileName,
    ID3D11ShaderResourceView **ppShaderResourceView,
    ID3D11Resource **ppTexture,
    bool ForceLoadAsSRGB
){
    CPUTResult result;
    HRESULT hr;

    // Set up loading structure
    //
    // Indicate all texture parameters should come from the file
    D3DX11_IMAGE_LOAD_INFO LoadInfo;
    ZeroMemory(&LoadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO));
    LoadInfo.Width          = D3DX11_FROM_FILE;
    LoadInfo.Height         = D3DX11_FROM_FILE;
    LoadInfo.Depth          = D3DX11_FROM_FILE;
    LoadInfo.FirstMipLevel  = D3DX11_FROM_FILE;
    LoadInfo.MipLevels      = D3DX11_FROM_FILE;
    // LoadInfo.Usage          = D3D11_USAGE_IMMUTABLE; // TODO: maintain a "mappable" flag?  Set immutable if not mappable?
    LoadInfo.Usage          = D3D11_USAGE_DEFAULT;
    LoadInfo.BindFlags      = D3D11_BIND_SHADER_RESOURCE;
    LoadInfo.CpuAccessFlags = 0;
    LoadInfo.MiscFlags      = 0;
    LoadInfo.MipFilter      = D3DX11_FROM_FILE;
    LoadInfo.pSrcInfo       = NULL;
    LoadInfo.Format         = (DXGI_FORMAT) D3DX11_FROM_FILE;
    LoadInfo.Filter         = D3DX11_FILTER_NONE;

    // if we're 'forcing' load of sRGB data, we need to verify image is sRGB
    // or determine image format that best matches the non-sRGB source format in hopes that the conversion will be faster
    // and data preserved
    if(true == ForceLoadAsSRGB)
    {
        // get the source image info
        D3DX11_IMAGE_INFO SrcInfo;
        hr = D3DX11GetImageInfoFromFile(fileName.c_str(), NULL, &SrcInfo, NULL);
        ASSERT( SUCCEEDED(hr), _L(" - Error loading texture '")+fileName+_L("'.") );

        // find a closest equivalent sRGB format
        result = GetSRGBEquivalent(SrcInfo.Format, LoadInfo.Format);
        ASSERT( CPUTSUCCESS(result), _L("Error loading texture '")+fileName+_L("'.  It is specified this texture must load as sRGB, but the source image is in a format that cannot be converted to sRGB.\n") );

        // set filtering mode to interpret 'in'-coming data as sRGB, and storing it 'out' on an sRGB surface
        //
        // As it stands, we don't have any tools that support sRGB output in DXT compressed textures.
        // If we later support a format that does provide sRGB, then the filter 'in' flag will need to be removed
        LoadInfo.Filter = D3DX11_FILTER_NONE | D3DX11_FILTER_SRGB_IN | D3DX11_FILTER_SRGB_OUT;
#if 0
        // DWM: TODO:  We want to catch the cases where the loader needs to do work.
        // This happens if the texture's pixel format isn't supported by DXGI.
        // TODO: how to determine?

        // if a runtime conversion must happen report a performance warning error.
        // Note: choosing not to assert here, as this will be a common issue.
        if( SrcInfo.Format != LoadInfo.Format)
        {
            cString dxgiName = GetDXGIFormatString(SrcInfo.Format);
            cString errorString = _T(__FUNCTION__);
            errorString += _L("- PERFORMANCE WARNING: '") + fileName
            +_L("' has an image format ")+dxgiName
            +_L(" but must be run-time converted to ")+GetDXGIFormatString(LoadInfo.Format)
            +_L(" based on requested sRGB target buffer.\n");
            TRACE( errorString.c_str() );
        }
#endif
    }
    //hr = D3DX11CreateTextureFromFile( pD3dDevice, fileName.c_str(), &LoadInfo, NULL, ppTexture, NULL );
    hr = MyCreateTextureFromFile( pD3dDevice, fileName.c_str(), &LoadInfo, NULL, ppTexture, NULL );
    ASSERT( SUCCEEDED(hr), _L("Failed to load texture: ") + fileName );
    CPUTSetDebugName( *ppTexture, fileName );

    hr = pD3dDevice->CreateShaderResourceView( *ppTexture, NULL, ppShaderResourceView );
    ASSERT( SUCCEEDED(hr), _L("Failed to create texture shader resource view.") );
    CPUTSetDebugName( *ppShaderResourceView, fileName );

    return CPUT_SUCCESS;
}
//----------------------------------------------------------------
CPUTResult CPUTConfigFile::LoadFile(const cString &szFilename)
{
    int nBytes = 0;
    char *pFileContents = NULL;
#if 1
    CPUTResult result = CPUTFileSystem::ReadFileContents(szFilename, (UINT *)&nBytes, (void **)&pFileContents, true);
    if(CPUTFAILED(result))
    {
        DEBUG_PRINT(_L("Failed to read file %s"), szFilename.c_str());
        return result;
    }
    
#else
    // Load the file
    FILE               *pFile = NULL;
    CPUTResult result = CPUTFileSystem::OpenFile(szFilename, &pFile);
    if(CPUTFAILED(result))
    {
        return result;
    }
//    locale_t locale = newlocale(LC_ALL_MASK, setlocale(LC_ALL, NULL), NULL);

    /* Determine file size */
    fseek(pFile, 0, SEEK_END);
    nBytes = ftell(pFile); // for text files, this is an overestimate
    fseek(pFile, 0, SEEK_SET);

    /* Read the whole thing */
    pFileContents = new char[nBytes + 1];
    nBytes = (int)fread(pFileContents, 1, nBytes, pFile);
    fclose(pFile);

    pFileContents[nBytes] = 0; // add 0-terminator
#endif
    CPUTConfigBlock    *pCurrBlock = NULL;
    int                 nCurrBlock = 0;
    
    /* Count the number of blocks */
    const char *pCur = pFileContents;
    const char *pStart, *pEnd;

    while(ReadLine(&pStart, &pEnd, &pCur))
    {
        const char *pOpen = FindFirst(pStart, pEnd, '[');
        const char *pClose = FindLast(pOpen + 1, pEnd, ']');
        if (pOpen < pClose)
        {
            // This line is a valid block header
            mnBlockCount++;
        }
    }

    // For files that don't have any blocks, just add the entire file to one block
    if(mnBlockCount == 0)
    {
        mnBlockCount   = 1;
    }

    pCur = pFileContents;
    mpBlocks = new CPUTConfigBlock[mnBlockCount];
    pCurrBlock = mpBlocks;

    /* Find the first block first */
    while(ReadLine(&pStart, &pEnd, &pCur))
    {
        const char *pOpen = FindFirst(pStart, pEnd, '[');
        const char *pClose = FindLast(pOpen + 1, pEnd, ']');
        if (pOpen < pClose)
        {
            // This line is a valid block header
            pCurrBlock = mpBlocks + nCurrBlock++;
//            AssignStr(pCurrBlock->mszName, pOpen + 1, pClose, locale);
			pCurrBlock->mszName.assign(pOpen + 1, pClose);
            std::transform(pCurrBlock->mszName.begin(), pCurrBlock->mszName.end(), pCurrBlock->mszName.begin(), tolow);
        }
        else if (pStart < pEnd)
        {
            // It's a value
            if (pCurrBlock == NULL)
            {
                continue;
            }

            const char *pEquals = FindFirst(pStart, pEnd, '=');
            if (pEquals == pEnd)
            {
                // No value, just a key, save it anyway
                // Optimistically, we assume it's new
                cString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName;
                //AssignStr(name, pStart, pEnd, locale);
				name.assign(pStart, pEnd);

                bool dup = false;
                for(int ii=0;ii<pCurrBlock->mnValueCount;++ii)
                {
                    if(!pCurrBlock->mpValues[ii].szName.compare(name))
                    {
                        dup = true;
                        break;
                    }
                }
                if(!dup)
                {
                    pCurrBlock->mnValueCount++;
                }
            }
            else
            {
                const char *pNameStart = pStart;
                const char *pNameEnd = pEquals;
                const char *pValStart = pEquals + 1;
                const char *pValEnd = pEnd;

                RemoveWhitespace(pNameStart, pNameEnd);
                RemoveWhitespace(pValStart, pValEnd);

                // Optimistically assume the name is new
                cString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName;
//                AssignStr(name, pNameStart, pNameEnd, locale);
				name.assign(pNameStart, pNameEnd);
                std::transform(name.begin(), name.end(), name.begin(), tolow);

                bool dup = false;
                for(int ii=0;ii<pCurrBlock->mnValueCount;++ii)
                {
                    if(!pCurrBlock->mpValues[ii].szName.compare(name))
                    {
                        dup = true;
                        break;
                    }
                }
                if(!dup)
                {
//                    AssignStr(pCurrBlock->mpValues[pCurrBlock->mnValueCount].szValue, pValStart, pValEnd, locale);
					pCurrBlock->mpValues[pCurrBlock->mnValueCount].szValue.assign(pValStart, pValEnd);
                    pCurrBlock->mnValueCount++;
                }
            }
        }
    }

    delete[] pFileContents;
    return CPUT_SUCCESS;
}