Ever wanted to have control over how GDK loads it's resources?
Dont like how all of your files are just spread out in the directory for all of your users to tingle with?
Or you found a way to hide your files, but it involves EXTRACTING them from archives, loading them, then DELETING them from disk?
Wish you could load a file from memory but dont want to use memblocks?
Well, I am here to tell you, YOU CAN!
And to be honest its not that hard, though this requires that you have access to the source code and can compile it, this could be expanded to Darkbasic Pro also more than likely..
-Allows you to control how GDK loads resources like objects,images,sounds,music etc
-No need for working with memblocks as this is similiar to loading a .dbo file (I suggest using .dbo for all of your 3d objects because GDK converts them anyway to .dbo when it loads other formats)
-DBOs are stored as BINARY, so if you want to manipulate this and make your own file formats, or stuff your resources into single .PAK like files then this will help you
-Can be expanded to allow for other format support!
NOTE: The code I am providing is just sample code I am using atm, I have not refined this and it WILL crash if you do not use it correctly but it shows the basic principle of the operation
EDIT: Currently the supplied method I have posted, will still load your textures as if it where a file on disk, I have not added it to accept textures from a buffer yet
UDPATED SOURCE + LIBS:
Alrighty, source + zipped libs!
I used vectors and strings for handling the data, you can change this if you want, just was easier for me
DarkSDKBasic3D.h
#include <vector>
void dbLoadObjectFromBuffer (const std::string& strBuffer, int iID );
void dbLoadObjectFromBuffer (const std::string& strBuffer,const std::vector<std::string>& strTextureBuffer,int iTextureMode,int iDBProMode,int iID );
void dbLoadObjectFromBuffer (const std::string& strBuffer,const std::vector<std::string>& strTextureBuffer,int iTextureMode,int iID );
void dbLoadObjectFromBuffer (const std::string& strBuffer,const std::vector<std::string>& strTextureBuffer,int iID );
CObjectsC.cpp
void dbLoadObjectFromBuffer (const std::string& strBuffer, int iID )
{
//Command for loading buffer
Load2 ( strBuffer, iID );
}
void dbLoadObjectFromBuffer (const std::string& strBuffer,const vector<string>& strTextureBuffer, int iID )
{
//Command for loading buffer
Load2 (strBuffer,strTextureBuffer,0, 0, iID );
}
void dbLoadObjectFromBuffer (const std::string& strBuffer,const vector<string>& strTextureBuffer,int iTextureMode, int iID )
{
//Command for loading buffer
Load2 (strBuffer,strTextureBuffer,iTextureMode, 0, iID );
}
void dbLoadObjectFromBuffer (const std::string& strBuffer,const vector<string>& strTextureBuffer,int iTextureMode,int iDBProMode, int iID )
{
//Command for loading buffer
Load2 (strBuffer,strTextureBuffer,iTextureMode, iDBProMode, iID );
}
DARKSDK_DLL void Load2 (const std::string& strBuffer, int iID )
{
// Test Entry Point for Custom function
LoadCore2 ( strBuffer, iID, 0, 0 );
}
DARKSDK_DLL void Load2 (const std::string& strBuffer,const vector<string>& strTextureBuffer,int iTextureMode,int iDBProMode,int iID )
{
// Test Entry Point for Custom function
LoadCore2 (strBuffer,strTextureBuffer,iID,iTextureMode,iDBProMode, 0 );
}
DARKSDK_DLL void LoadCore2 (const std::string& strBuffer, int iID, int iDBProMode, int iDivideTextureSize )
{
// ensure the object is okay to use
ConfirmNewObject ( iID );
// check memory allocation
ID_ALLOCATION ( iID );
// load the object
if ( !LoadDBO2 (strBuffer, &g_ObjectList [ iID ] ) )
return;
// setup new object and introduce to buffers
if ( !SetNewObjectFinalProperties ( iID, -1.0f ) )
return;
if ( g_ObjectList [ iID ]->iMeshCount == 0 )
return;
// add object id to shortlist
AddObjectToObjectListRef ( iID );
// calculate path from filename
//Fake filename
char szFilename[] = "";
char szPath [ MAX_PATH ];
if ( _strnicmp ( (char*)szFilename+strlen((char*)szFilename)-4, ".mdl", 4 )==NULL )
{
// MDL models store their textures in the temp folder
DBOCalculateLoaderTempFolder();
strcpy ( szPath, g_WindowsTempDirectory );
}
else
{
// Path is current model location
strcpy( szPath, "" );
LPSTR pFile = (LPSTR)szFilename;
DWORD dwLength = strlen(pFile);
for ( int n=dwLength; n>0; n-- )
{
if ( pFile[n]=='\\' || pFile[n]=='/' )
{
strcpy ( szPath, pFile );
szPath[n+1]=0;
break;
}
}
}
// prepare textures for all meshes (load them)
sObject* pObject = g_ObjectList [ iID ];
///*
for ( int iMesh = 0; iMesh < pObject->iMeshCount; iMesh++ )
{
LoadInternalTextures2 ( pObject->ppMeshList [ iMesh ], szPath, iDBProMode, iDivideTextureSize );
}
//*/
// 250704 - prepare effects for all meshes (load them)
for ( int iMesh = 0; iMesh < pObject->iMeshCount; iMesh++ )
{
// get mesh ptr
sMesh* pMesh = pObject->ppMeshList [ iMesh ];
if ( pMesh->bUseVertexShader )
{
// Search if effect already loaded (else create a new)
CreateNewOrSharedEffect ( pMesh, true );
}
}
}
DARKSDK_DLL void LoadCore2 (const std::string& strBuffer,const vector<string>& strTextureBuffer, int iID,int iTextureMode, int iDBProMode, int iDivideTextureSize )
{
// ensure the object is okay to use
ConfirmNewObject ( iID );
// check memory allocation
ID_ALLOCATION ( iID );
// load the object
if ( !LoadDBO2 (strBuffer, &g_ObjectList [ iID ] ) )
return;
// setup new object and introduce to buffers
if ( !SetNewObjectFinalProperties ( iID, -1.0f ) )
return;
if ( g_ObjectList [ iID ]->iMeshCount == 0 )
return;
// add object id to shortlist
AddObjectToObjectListRef ( iID );
// calculate path from filename
//Fake filename
//
char szFilename[] = "";
char szPath [ MAX_PATH ];
if ( _strnicmp ( (char*)szFilename+strlen((char*)szFilename)-4, ".mdl", 4 )==NULL )
{
// MDL models store their textures in the temp folder
DBOCalculateLoaderTempFolder();
strcpy ( szPath, g_WindowsTempDirectory );
}
else
{
// Path is current model location
strcpy( szPath, "" );
LPSTR pFile = (LPSTR)szFilename;
DWORD dwLength = strlen(pFile);
for ( int n=dwLength; n>0; n-- )
{
if ( pFile[n]=='\\' || pFile[n]=='/' )
{
strcpy ( szPath, pFile );
szPath[n+1]=0;
break;
}
}
}
//*/
// prepare textures for all meshes (load them)
sObject* pObject = g_ObjectList [ iID ];
///*
for (unsigned int iMesh = 0; iMesh < unsigned int(pObject->iMeshCount); iMesh++ )
{
///*
//strTextureBuffer ciTextures
if(strTextureBuffer.size() > 0)
{
if(iMesh < strTextureBuffer.size())
{
if(strTextureBuffer[iMesh] != "")
{
LoadInternalTextures2 ( pObject->ppMeshList [ iMesh ],strTextureBuffer[iMesh], iTextureMode,szPath, iDBProMode, iDivideTextureSize );
}
}
else
{
//If we do not have enough textures in buffer to fit number of unique meshes, then we will just reuse first texture
if(strTextureBuffer.front() != "")
{
LoadInternalTextures2 ( pObject->ppMeshList [ iMesh ],strTextureBuffer.front(), iTextureMode, szPath, iDBProMode, iDivideTextureSize );
}
}
}
}
//*/
// 250704 - prepare effects for all meshes (load them)
for ( int iMesh = 0; iMesh < pObject->iMeshCount; iMesh++ )
{
// get mesh ptr
sMesh* pMesh = pObject->ppMeshList [ iMesh ];
if ( pMesh->bUseVertexShader )
{
// Search if effect already loaded (else create a new)
CreateNewOrSharedEffect ( pMesh, true );
}
}
}
DBOFormat.cpp
DARKSDK_DLL bool LoadDBO2 (const std::string& strBuffer,sObject** ppObject )
{
// DBOBlock pointer
//DWORD dwBlockSize = 0;
//DWORD* pDBOBlock = NULL;
// No object to start with
*ppObject = NULL;
// Obtain extension
// if file native DBO format
/*
if ( _stricmp ( pExtension, "DBO" )==NULL )
{
// load DBO object directly
if ( !DBOLoadBlockFile ( pFilename, (DWORD*)&pDBOBlock, &dwBlockSize ) )
{
RunTimeError ( RUNTIMEERROR_B3DOBJECTLOADFAILED );
return false;
}
}
*/
// construct the object
if ( !DBOConvertBlockToObject ((DWORD)strBuffer.c_str(), strBuffer.length(), ppObject ) )
{
RunTimeError ( RUNTIMEERROR_B3DOBJECTLOADFAILED );
return false;
}
// free block when done
//SAFE_DELETE(&ppBlock);
// okay
return true;
}
DBOMesh.cpp
DARKSDK_DLL void LoadInternalTextures2 ( sMesh* pMesh,const std::string& strBuffer,int iTextureMode,LPSTR TexturePath, int iDBProMode, int iDivideTextureSize )
{
LoadInternalTextures2 ( pMesh, strBuffer, iTextureMode,TexturePath, iDBProMode, iDivideTextureSize, 0 );
}
DARKSDK_DLL void LoadInternalTextures2 ( sMesh* pMesh, LPSTR TexturePath, int iDBProMode, int iDivideTextureSize )
{
LoadInternalTextures2 ( pMesh, TexturePath, iDBProMode, iDivideTextureSize, 0 );
}
DARKSDK_DLL void LoadInternalTextures2 ( sMesh* pMesh, LPSTR TexturePath, int iDBProMode, int iDivideTextureSize, LPSTR pOptionalLightmapNoReduce )
{
// iDBProMode : 0-DBV1 / 1-DBPro defaults / 2-leave all states alone (for internal textureloaduse)
// 0-DBV1 legacy behaviour
// 1-DBPro : out of the box new pro standard
// 2-Leave states alone to keep material/diffuse effects
// 3-Leave states alone to keep material/texture effects
// 4-Ensure object blends texture and diffuse at stage zero
// 5-Leave states alone to keep multi-material effects
// load multimaterial textures from internal name
if ( pMesh->bUseMultiMaterial==true )
{
// Currrent texture if any used
sTexture* pTexture = NULL;
// Define textures for multi material array
DWORD dwMultiMatCount = pMesh->dwMultiMaterialCount;
for ( DWORD m=0; m<dwMultiMatCount; m++ )
{
// get multimat at index
sMultiMaterial* pMultiMat = &(pMesh->pMultiMaterial [ m ]);
// load texture
//int iImageIndex = 0;
int iImageIndex = LoadOrFindTextureAsImage ( pMultiMat->pName, TexturePath, iDivideTextureSize );
// store texture ref
if ( iImageIndex != 0 )
{
// maximum diffuse with texture (for DBV1 compatibility)
if ( iDBProMode==0 )
{
// 191203 - added flag to LOAD OBJECT (DBV1 by default)
pMultiMat->mMaterial.Diffuse.r = 1.0f;
pMultiMat->mMaterial.Diffuse.g = 1.0f;
pMultiMat->mMaterial.Diffuse.b = 1.0f;
pMultiMat->mMaterial.Diffuse.a = 1.0f;
}
// and the texture itself
pMultiMat->pTexturesRef = g_Image_GetPointer ( iImageIndex );
}
else
{
// no texture (uses diffuse colour for coloured model)
pMultiMat->pTexturesRef = NULL;
}
// in order to let users use ambient, force this!
if ( iDBProMode!=2 && iDBProMode!=3 && iDBProMode!=5 ) pMultiMat->mMaterial.Ambient = pMultiMat->mMaterial.Diffuse;
// leefix - 100303 - Define master texture for blending (first texture if any)
if ( iImageIndex != 0 && pTexture==NULL )
{
// free any existing texture data
SAFE_DELETE_ARRAY ( pMesh->pTextures );
// create single texture for mesh
pTexture = new sTexture[1];
// single texture for mesh
pMesh->dwTextureCount = 1;
pMesh->pTextures = pTexture;
// image index for sorting
pTexture->iImageID = iImageIndex;
pTexture->pTexturesRef = NULL;
// Blending states
pTexture->dwBlendMode = D3DTOP_MODULATE;
pTexture->dwBlendArg1 = D3DTA_TEXTURE;
}
}
// lee - 040306 - u6rc5 - force this mode on load
if ( iDBProMode==5 ) pMesh->bUsesMaterial = true;
}
else
{
// load standard textures for internal name
DWORD dwTextureCount = pMesh->dwTextureCount;
for ( DWORD t=0; t<dwTextureCount; t++ )
{
// get texture at index
sTexture* pTexture = &(pMesh->pTextures [ t ]);
// divide or not to divide
int iLocalDivideValueForStage = iDivideTextureSize;
if ( pOptionalLightmapNoReduce )
if ( _strnicmp ( pTexture->pName, pOptionalLightmapNoReduce, strlen(pOptionalLightmapNoReduce))==NULL )
iLocalDivideValueForStage=0;
// load texture
//int iImageIndex = 0;
int iImageIndex = LoadOrFindTextureAsImage ( pTexture->pName, TexturePath, iLocalDivideValueForStage );
// store image in texture
if ( iImageIndex != 0 )
{
// setup texture settings
pTexture->iImageID = iImageIndex;
pTexture->pTexturesRef = g_Image_GetPointer ( iImageIndex );
// lee - 200306 - u6b4 - new mode to blend texture and diffuse at stage zero (load object with material alpha setting)
if ( iDBProMode==4 )
{
// Mode 4 - retains material settings and blends with texture
if ( t==0 )
{
pTexture->dwBlendMode = D3DTOP_MODULATE;
pTexture->dwBlendArg1 = D3DTA_TEXTURE;
pTexture->dwBlendArg2 = D3DTA_DIFFUSE;
}
}
else
{
// Mode 0,1,2,3
// to alter texture behaviour from basic color to texture
if ( iDBProMode!=2 && iDBProMode!=3 )
{
// Force a MODULATE for default behaviours of [0] and [1]
pTexture->dwBlendMode = D3DTOP_MODULATE;
}
// Only force this for [0] [1] and [3] where we are expecting texture results
if ( iDBProMode!=2 ) pTexture->dwBlendArg1 = D3DTA_TEXTURE;
// maximum diffuse with texture (for DBV1 compatibility)
if ( iDBProMode!=2 && iDBProMode!=3 )
{
pMesh->mMaterial.Diffuse.r = 1.0f;
pMesh->mMaterial.Diffuse.g = 1.0f;
pMesh->mMaterial.Diffuse.b = 1.0f;
pMesh->mMaterial.Diffuse.a = 1.0f;
}
}
}
else
{
pTexture->iImageID = 0;
pTexture->pTexturesRef = NULL;
}
//240203-added more defaults for better backward compat. with Patch 3 and earlier
if ( iDBProMode!=2 && iDBProMode!=3 && iDBProMode!=4 ) pMesh->mMaterial.Ambient = pMesh->mMaterial.Diffuse;
}
}
}
DARKSDK_DLL void LoadInternalTextures2 ( sMesh* pMesh, const std::string& strBuffer,int iTextureMode, LPSTR TexturePath, int iDBProMode, int iDivideTextureSize, LPSTR pOptionalLightmapNoReduce )
{
// iDBProMode : 0-DBV1 / 1-DBPro defaults / 2-leave all states alone (for internal textureloaduse)
// 0-DBV1 legacy behaviour
// 1-DBPro : out of the box new pro standard
// 2-Leave states alone to keep material/diffuse effects
// 3-Leave states alone to keep material/texture effects
// 4-Ensure object blends texture and diffuse at stage zero
// 5-Leave states alone to keep multi-material effects
// load multimaterial textures from internal name
if ( pMesh->bUseMultiMaterial==true )
{
// Currrent texture if any used
sTexture* pTexture = NULL;
// Define textures for multi material array
DWORD dwMultiMatCount = pMesh->dwMultiMaterialCount;
for ( DWORD m=0; m<dwMultiMatCount; m++ )
{
// get multimat at index
sMultiMaterial* pMultiMat = &(pMesh->pMultiMaterial [ m ]);
// load texture
//int iImageIndex = 0;
//int iImageIndex = LoadOrFindTextureAsImage2 ( pMultiMat->pName, TexturePath, iDivideTextureSize );
int iImageIndex = LoadOrFindTextureAsImage2 (strBuffer, iTextureMode, pTexture->pName, TexturePath, iDivideTextureSize );
// store texture ref
if ( iImageIndex != 0 )
{
// maximum diffuse with texture (for DBV1 compatibility)
if ( iDBProMode==0 )
{
// 191203 - added flag to LOAD OBJECT (DBV1 by default)
pMultiMat->mMaterial.Diffuse.r = 1.0f;
pMultiMat->mMaterial.Diffuse.g = 1.0f;
pMultiMat->mMaterial.Diffuse.b = 1.0f;
pMultiMat->mMaterial.Diffuse.a = 1.0f;
}
// and the texture itself
pMultiMat->pTexturesRef = g_Image_GetPointer ( iImageIndex );
}
else
{
// no texture (uses diffuse colour for coloured model)
pMultiMat->pTexturesRef = NULL;
}
// in order to let users use ambient, force this!
if ( iDBProMode!=2 && iDBProMode!=3 && iDBProMode!=5 ) pMultiMat->mMaterial.Ambient = pMultiMat->mMaterial.Diffuse;
// leefix - 100303 - Define master texture for blending (first texture if any)
if ( iImageIndex != 0 && pTexture==NULL )
{
// free any existing texture data
SAFE_DELETE_ARRAY ( pMesh->pTextures );
// create single texture for mesh
pTexture = new sTexture[1];
// single texture for mesh
pMesh->dwTextureCount = 1;
pMesh->pTextures = pTexture;
// image index for sorting
pTexture->iImageID = iImageIndex;
pTexture->pTexturesRef = NULL;
// Blending states
pTexture->dwBlendMode = D3DTOP_MODULATE;
pTexture->dwBlendArg1 = D3DTA_TEXTURE;
}
}
// lee - 040306 - u6rc5 - force this mode on load
if ( iDBProMode==5 ) pMesh->bUsesMaterial = true;
}
else
{
// load standard textures for internal name
DWORD dwTextureCount = pMesh->dwTextureCount;
for ( DWORD t=0; t<dwTextureCount; t++ )
{
// get texture at index
sTexture* pTexture = &(pMesh->pTextures [ t ]);
// divide or not to divide
int iLocalDivideValueForStage = iDivideTextureSize;
if ( pOptionalLightmapNoReduce )
if ( _strnicmp ( pTexture->pName, pOptionalLightmapNoReduce, strlen(pOptionalLightmapNoReduce))==NULL )
iLocalDivideValueForStage=0;
// load texture
//int iImageIndex = 0;
int iImageIndex = LoadOrFindTextureAsImage2 (strBuffer, iTextureMode, pTexture->pName, TexturePath, iLocalDivideValueForStage );
// store image in texture
if ( iImageIndex != 0 )
{
// setup texture settings
pTexture->iImageID = iImageIndex;
pTexture->pTexturesRef = g_Image_GetPointer ( iImageIndex );
// lee - 200306 - u6b4 - new mode to blend texture and diffuse at stage zero (load object with material alpha setting)
if ( iDBProMode==4 )
{
// Mode 4 - retains material settings and blends with texture
if ( t==0 )
{
pTexture->dwBlendMode = D3DTOP_MODULATE;
pTexture->dwBlendArg1 = D3DTA_TEXTURE;
pTexture->dwBlendArg2 = D3DTA_DIFFUSE;
}
}
else
{
// Mode 0,1,2,3
// to alter texture behaviour from basic color to texture
if ( iDBProMode!=2 && iDBProMode!=3 )
{
// Force a MODULATE for default behaviours of [0] and [1]
pTexture->dwBlendMode = D3DTOP_MODULATE;
}
// Only force this for [0] [1] and [3] where we are expecting texture results
if ( iDBProMode!=2 ) pTexture->dwBlendArg1 = D3DTA_TEXTURE;
// maximum diffuse with texture (for DBV1 compatibility)
if ( iDBProMode!=2 && iDBProMode!=3 )
{
pMesh->mMaterial.Diffuse.r = 1.0f;
pMesh->mMaterial.Diffuse.g = 1.0f;
pMesh->mMaterial.Diffuse.b = 1.0f;
pMesh->mMaterial.Diffuse.a = 1.0f;
}
}
}
else
{
pTexture->iImageID = 0;
pTexture->pTexturesRef = NULL;
}
//240203-added more defaults for better backward compat. with Patch 3 and earlier
if ( iDBProMode!=2 && iDBProMode!=3 && iDBProMode!=4 ) pMesh->mMaterial.Ambient = pMesh->mMaterial.Diffuse;
}
}
}
DARKSDK_DLL int LoadOrFindTextureAsImage2 (const std::string& strBuffer,int iTextureMode, LPSTR pTextureName, LPSTR TexturePath, int iDivideTextureSize )
{
// load texture
int iImageIndex = 0;
// does we have a texture name
if ( strlen(pTextureName)==0 )
return 0;
// get filename only
char pNoPath [ _MAX_PATH ];
strcpy(pNoPath, pTextureName );
_strrev(pNoPath);
for(DWORD n=0; n<strlen(pNoPath); n++)
if(pNoPath[n]=='\\' || pNoPath[n]=='/' || (unsigned char)(pNoPath[n])<32)
pNoPath[n]=0;
_strrev(pNoPath);
// build a texture path and load it
char Path [ _MAX_PATH*2 ];
sprintf ( Path, "%s%s", TexturePath, pNoPath );
if ( strlen ( Path ) >= _MAX_PATH ) Path[_MAX_PATH]=0;
// texture load a : default file
iImageIndex = g_Image_InternalLoadEx2 ( strBuffer, iTextureMode,iDivideTextureSize );
if ( iImageIndex==0 )
{
// texture load b : file as DDS
char pDDSFile [ _MAX_PATH*2 ];
strcpy(pDDSFile, pNoPath);
DWORD dwLenDot = strlen(pDDSFile);
if ( dwLenDot>4 )
{
pDDSFile[dwLenDot-4]=0;
strcat(pDDSFile, ".dds");
sprintf ( Path, "%s%s", TexturePath, pDDSFile );
//iImageIndex = g_Image_InternalLoadEx ( Path, iDivideTextureSize );
iImageIndex = g_Image_InternalLoadEx2 ( strBuffer, iTextureMode,iDivideTextureSize );
if ( iImageIndex==0 )
{
// texture load c : original file
//iImageIndex = g_Image_InternalLoadEx ( pTextureName, iDivideTextureSize );
iImageIndex = g_Image_InternalLoadEx2 ( strBuffer, iTextureMode,iDivideTextureSize );
if ( iImageIndex==0 )
{
// texture load d : no path just file
//iImageIndex = g_Image_InternalLoadEx ( pNoPath, iDivideTextureSize );
iImageIndex = g_Image_InternalLoadEx2 ( strBuffer, iTextureMode,iDivideTextureSize );
if ( iImageIndex==0 )
{
// texture load e : 031208 - U71 - absolute path with relative path in model file
sprintf ( Path, "%s%s", TexturePath, pTextureName );
if ( strlen ( Path ) >= _MAX_PATH ) Path[_MAX_PATH]=0;
//iImageIndex = g_Image_InternalLoadEx ( Path, iDivideTextureSize );
//WORKING TEXTURE LINE
iImageIndex = g_Image_InternalLoadEx2 ( strBuffer, iTextureMode,iDivideTextureSize ); //ACTUAL WORKING TEXTURE PATH I FOUND
if ( iImageIndex==0 )
{
// texture load f : 031208 - U71 - as above, but as DDS
strcpy(pDDSFile, pTextureName);
DWORD dwLenDot = strlen(pDDSFile);
if ( dwLenDot>4 )
{
pDDSFile[dwLenDot-4]=0;
strcat(pDDSFile, ".dds");
sprintf ( Path, "%s%s", TexturePath, pDDSFile );
//iImageIndex = g_Image_InternalLoadEx ( Path, iDivideTextureSize );
iImageIndex = g_Image_InternalLoadEx2 ( strBuffer, iTextureMode, iDivideTextureSize );
}
}
}
}
}
}
}
return iImageIndex;
}
DBOExternals.cpp
DBPRO_GLOBAL IMAGE_LoadInternalTextureDividePFN2 g_Image_InternalLoadEx2;
DBOExternals.h
typedef int ( *IMAGE_LoadInternalTextureDividePFN2 ) ( const std::string&, int, int);
extern IMAGE_LoadInternalTextureDividePFN2 g_Image_InternalLoadEx2;
CommonC.cpp
g_Image_InternalLoadEx2 = dbLoadImageInternal2;
CImageC.cpp
void dbLoadImageFromBuffer (const std::string& strBuffer, char* szFilename, int iID , int TextureFlag, int iDivideTextureSize)
{
LoadEx2 (strBuffer, szFilename, iID, TextureFlag, iDivideTextureSize);
}
DARKSDK void LoadEx2 (const std::string& strBuffer, LPSTR szFilename, int iID, int iTextureFlag, int iDivideTextureSize )
{
if(Load2(strBuffer, szFilename, iID, iTextureFlag, false, iDivideTextureSize )==false)
{
//char pCWD[256]; _getcwd ( pCWD, 256 );
//char pErr[256]; sprintf ( pErr, "CWD:%s\nLOAD IMAGE %s,%d,%d,%d", pCWD, szFilename, iID, iTextureFlag, iDivideTextureSize);
//RunTimeError(RUNTIMEERROR_IMAGELOADFAILED,pErr);
}
}
int dbLoadImageInternal2 ( const std::string& strBuffer,int iTextureMode,int iDivideTextureSize)
{
return LoadInternal2 ( strBuffer,iTextureMode,iDivideTextureSize);
}
DARKSDK int LoadInternal2 (const std::string& strBuffer,int iTextureMode, int iDivideTextureSize )
{
// does image already exist?
int iImageID = 0;
//JOZEF
//Make a internal name of the file based upon the data within the string
std::string strTempTextureID = strBuffer.substr(0,250);
//strTempTextureID = sig;
//if ( !FindInternalImage ( szFilename, &iImageID ) )
//USE ABC till we add a checksum check
//if ( !FindInternalImage ((char*)strTempTextureID.c_str(), &iImageID ) )
if ( !FindInternalImage ("ABC.bmp", &iImageID ) )
{
// no, use standard loader
//bool boolass = Load2 (strBuffer,"image.bmp",iImageID, 0, true, iDivideTextureSize );
if ( Load2 (strBuffer,(char*)strTempTextureID.c_str(),iImageID,iTextureMode, true, iDivideTextureSize ) )
//if ( Load2 (strBuffer,"Image.bmp",iImageID, 0, true, iDivideTextureSize ) )
{
// new image returned
return iImageID;
}
else
{
// load failed
iImageID=0;
}
}
return iImageID;
}
DARKSDK bool Load2 (const std::string& strBuffer, char* szFilename, int iID, int iTextureFlag, bool bIgnoreNegLimit, int iDivideTextureSize )
{
// iTextureFlag (0-default/1-sectionofplate/2-cube)
// iDivideTextureSize (0-leave size,0>divide by)
if ( bIgnoreNegLimit==false )
{
if( iID<1 || iID>MAXIMUMVALUE )
{
RunTimeError(RUNTIMEERROR_IMAGEILLEGALNUMBER);
return false;
}
}
RemoveImage( iID );
// loads in image into the bank
tagData* test = NULL; // pointer to data structure
int iLen1; // used for checking length of strings
int iLen2; // used for checking length of strings
char szTest [ 256 ]; // text buffer
bool bFound = false; // flag which checks if we need to load the texture
// create a new block of memory
test = new tagData;
memset(test, 0, sizeof(tagData));
// check the memory was created
if ( test == NULL )
return false;
// clear out the memory
memset ( test, 0, sizeof ( test ) );
// clear out text buffers
memset ( test->szLongFilename, 0, sizeof ( char ) * 256 ); // clear out long filename
memset ( test->szShortFilename, 0, sizeof ( char ) * 256 ); // clear out short filename
memset ( szTest, 0, sizeof ( char ) * 256 ); // clear out test buffer
// get length of filename and copy to shortfilename
iLen1 = lstrlen ( szFilename ); // get length
memcpy ( test->szShortFilename, szFilename, sizeof ( char ) * iLen1 ); // copy to short filename
// sort out full filename
GetCurrentDirectory ( 256, szTest ); // get the apps full directory e.g. "c:\test\"
iLen1 = lstrlen ( szTest ); // get the length of the full directory
iLen2 = lstrlen ( szFilename ); // get the length of the passed filename
// copy memory
memcpy ( test->szLongFilename, szTest, sizeof ( char ) * iLen1 ); // copy the full dir to the long filename
// U74 BETA9 - 030709 - fix longfilename if full dir has no \ and filename does not start with
// memcpy ( test->szLongFilename + iLen1, szFilename + 1, sizeof ( char ) * iLen2 ); // append the filename onto the long file name
if ( szFilename[0]!='\\' )
{
if ( szTest[iLen1]!='\\' )
{
test->szLongFilename[iLen1]='\\';
memcpy ( test->szLongFilename + iLen1 + 1, szFilename, sizeof ( char ) * iLen2 );
}
else
memcpy ( test->szLongFilename + iLen1, szFilename, sizeof ( char ) * iLen2 );
}
else
{
// legacy support
memcpy ( test->szLongFilename + iLen1, szFilename + 1, sizeof ( char ) * iLen2 );
}
// The default is a setting of zero (0)
if( iTextureFlag==1 )
{
///*
// loads image into a section of the texture plate
if ( m_bSharing && !bFound )
test->lpTexture = GetTexture2 (strBuffer, szFilename, 1 ); // load the perfect texture
else
test->lpTexture = GetTexture2 (strBuffer, szFilename, 1 ); // load the perfect texture
// load failed
if ( test->lpTexture==NULL )
{
SAFE_DELETE(test);
return false;
}
// Set image settings
test->iHeight = m_iHeight; // store the width
test->iWidth = m_iWidth; // store the height
// get actual dimensions of texture/image
D3DSURFACE_DESC imageddsd;
test->lpTexture->GetLevelDesc(0, &imageddsd);
test->fTexUMax=(float)test->iWidth/(float)imageddsd.Width;
test->fTexVMax=(float)test->iHeight/(float)imageddsd.Height;
// Ensure smalltextres are handled
if(test->fTexUMax>1.0f) test->fTexUMax=1.0f;
if(test->fTexVMax>1.0f) test->fTexVMax=1.0f;
//*/
}
else
{
// Load Image Into Whole Texture Plate
D3DXIMAGE_INFO info; // image information
LoadFullTex2 (strBuffer, szFilename, &test->lpTexture, &info, iTextureFlag, iDivideTextureSize ); // loads into whole texture
// load failed
if ( test->lpTexture==NULL )
{
SAFE_DELETE(test);
return false;
}
// get file image info
test->iHeight = info.Height;
test->iWidth = info.Width;
// Entire texture used
test->fTexUMax=1.0f;
test->fTexVMax=1.0f;
}
// Get depth of texture
D3DSURFACE_DESC desc;
test->lpTexture->GetLevelDesc(0, &desc);
test->iDepth = GetBitDepthFromFormat(desc.Format);
// load failed
if ( test->lpTexture==NULL )
{
SAFE_DELETE(test);
return false;
}
// fill out rest of structure
test->bLocked = false;
// add to the list
m_List.insert( std::make_pair(iID, test) );
// ensure sprites all updated
// V109 BETA3 - only need to update image/textures, not internal textures (negatives)
if ( iID>0 ) g_Update_All_Sprites();
return true;
}
DARKSDK LPDIRECT3DTEXTURE9 GetTexture2 (const std::string& strBuffer, char* szFilename, int iOneToOnePixels )
{
// Uses actual or virtual file..
char VirtualFilename[_MAX_PATH];
strcpy(VirtualFilename, szFilename);
g_pGlob->UpdateFilenameFromVirtualTable( (DWORD)VirtualFilename);
// Decrypt and use media, re-encrypt
g_pGlob->Decrypt( (DWORD)VirtualFilename );
LPDIRECT3DTEXTURE9 Res = GetTextureCore2 (strBuffer, VirtualFilename, iOneToOnePixels, 0, 0 );
g_pGlob->Encrypt( (DWORD)VirtualFilename );
return Res;
}
DARKSDK LPDIRECT3DTEXTURE9 GetTextureCore2 (const std::string& strBuffer, char* szFilename, int iOneToOnePixels, int iFullTexturePlateMode, int iDivideTextureSize )
{
// V109 BETA3 - 220408 - new feature IMAGEBLOCK
DWORD dwFileInMemorySize = 0;
LPVOID pFileInMemoryData = NULL;
//Doesnt do anything
/*
if ( g_bImageBlockActive )
{
// final storage string of path and file resolver (makes the filename and path uniform for imageblock retrieval)
// and work out true file and path, then look for it in imageblock
char pFinalRelPathAndFile[512];
GetFileInMemory ( szFilename, &pFileInMemoryData, &dwFileInMemorySize, pFinalRelPathAndFile );
// Add relative path and file to image block
if ( g_iImageBlockMode==0 )
{
_chdir ( g_iImageBlockRootPath );
//Apparently doesnt do anything
//AddToImageBlock2 (ppBlock, dwBlockSize, pFinalRelPathAndFile );
}
}
*/
// loads a texture and returns a pointer to it
// make sure that the device is valid
if ( !m_pD3D )
return NULL;
// variable declarations
LPDIRECT3DTEXTURE9 lpTexture = NULL; // set texture to null
// get file image info
HRESULT hRes = 0;
D3DXIMAGE_INFO info;
if ( g_iImageBlockMode==1 && pFileInMemoryData )
hRes = D3DXGetImageInfoFromFileInMemory( pFileInMemoryData, dwFileInMemorySize, &info );
else
hRes = D3DXGetImageInfoFromFileInMemory((LPVOID)strBuffer.c_str(), strBuffer.length(), &info );
//hRes = D3DXGetImageInfoFromFile( szFilename, &info );
// V109 BETA8 - 060508 - if cannot find file/get info, fail as this file is in error
// if( FAILED ( hRes )) return NULL;
// U74 BETA9 - 040709 - get info from physical file if not in image block (previous fix was flawed)
if ( hRes==0 || hRes!=D3D_OK )
hRes = D3DXGetImageInfoFromFileInMemory((LPVOID)strBuffer.c_str(), strBuffer.length(), &info );
//hRes = D3DXGetImageInfoFromFile( szFilename, &info );
// if texture size needs diviing, do so now
if ( iDivideTextureSize>0 )
{
if ( iDivideTextureSize==16384 )
{
// notextureloadmode
info.Width = 1;
info.Height = 1;
}
else
{
// divide by specified value (reduce texture consumption)
info.Width /= iDivideTextureSize;
info.Height /= iDivideTextureSize;
}
}
// leeadd - 290104 - if mode is CUBE(2) or VOLUME(3), direct cube loader
if ( iFullTexturePlateMode==2 || iFullTexturePlateMode==3 || iDivideTextureSize==16384 )
{
if ( iDivideTextureSize==16384 )
{
// support for quick-fake-texture-load (apply texture to universe without loading it)
LPDIRECT3DTEXTURE9 pFakeTex = NULL;
hRes = D3DXCreateTexture ( m_pD3D,
info.Width,
info.Height,
1,//one mipmap only for one-to-one pixels
0,
g_DefaultD3Dformat,
D3DPOOL_MANAGED,
&pFakeTex );
lpTexture = pFakeTex;
}
else
{
if ( iFullTexturePlateMode==2 )
{
// support for cube textures when specify texture flag of two (2)
LPDIRECT3DCUBETEXTURE9 pCubeTex = NULL;
HRESULT hRes = 0;
if ( g_iImageBlockMode==1 && pFileInMemoryData )
hRes = D3DXCreateCubeTextureFromFileInMemoryEx( m_pD3D, pFileInMemoryData, dwFileInMemorySize, info.Width, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pCubeTex );
else
hRes = D3DXCreateCubeTextureFromFileEx( m_pD3D, szFilename, info.Width, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pCubeTex );
if ( SUCCEEDED( hRes ) )
{
// cube loaded fine
lpTexture = (LPDIRECT3DTEXTURE9)pCubeTex;
}
else
return NULL;
}
if ( iFullTexturePlateMode==3 )
{
// support for volume textures when specify 3
LPDIRECT3DVOLUMETEXTURE9 pVolumeTex = NULL;
HRESULT hRes = 0;
if ( g_iImageBlockMode==1 && pFileInMemoryData )
hRes = D3DXCreateVolumeTextureFromFileInMemoryEx( m_pD3D, pFileInMemoryData, dwFileInMemorySize,
info.Width, info.Height, info.Depth, 1, 0, D3DFMT_UNKNOWN,
D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL,
&pVolumeTex );
else
hRes = D3DXCreateVolumeTextureFromFileEx( m_pD3D, szFilename,
info.Width, info.Height, info.Depth, 1, 0, D3DFMT_UNKNOWN,
D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL,
&pVolumeTex );
if ( SUCCEEDED( hRes ) )
{
// volume loaded fine
lpTexture = (LPDIRECT3DTEXTURE9)pVolumeTex;
}
else
return NULL;
}
}
}
else
{
// leefix - 150503 - perfect texture is one-to-one pixels and no mipmaps or alpha
if ( iOneToOnePixels==1 )
{
// Keep Alpha from file
DWORD dwUseAlphaCode = 0;
if(_strnicmp( szFilename + (strlen(szFilename)-4), ".dds", 4)==NULL
|| _strnicmp( szFilename + (strlen(szFilename)-4), ".png", 4)==NULL
|| _strnicmp( szFilename + (strlen(szFilename)-4), ".tga", 4)==NULL)
dwUseAlphaCode = 0;
else
dwUseAlphaCode = m_Color;
// leeadd - 300305 - format selection (replaced info.Format or g_DefaultD3Dformat in createtexture as we need SET IMAGE COLORKEY to retain alpha!)
D3DFORMAT newImageFormat = info.Format;
if ( dwUseAlphaCode!=0 ) newImageFormat = g_DefaultD3Dformat;
// create a new texture/image
hRes = D3DXCreateTexture ( m_pD3D,
info.Width,
info.Height,
1,//one mipmap only for one-to-one pixels
0,
newImageFormat,
D3DPOOL_MANAGED,
&lpTexture );
// 010205 - default mem can run out
if ( lpTexture==NULL )
return NULL;
// adjust to actual size if texture smaller
D3DSURFACE_DESC desc;
lpTexture->GetLevelDesc(0,&desc);
if(desc.Width<info.Width) info.Width=desc.Width;
if(desc.Height<info.Height) info.Height=desc.Height;
if( SUCCEEDED ( hRes ))
{
LPDIRECT3DSURFACE9 pSurface=NULL;
hRes = lpTexture->GetSurfaceLevel(0, &pSurface);
if( SUCCEEDED ( hRes ))
{
// load surface data into it
RECT destrc = { 0, 0, info.Width, info.Height };
if ( g_iImageBlockMode==1 && pFileInMemoryData )
hRes = D3DXLoadSurfaceFromFileInMemory( pSurface, NULL, &destrc, pFileInMemoryData, dwFileInMemorySize, NULL, D3DX_FILTER_POINT, dwUseAlphaCode, &info );
else
hRes = D3DXLoadSurfaceFromFileInMemory( pSurface, NULL, &destrc,(LPVOID)strBuffer.c_str(), strBuffer.length(), NULL, D3DX_FILTER_POINT, dwUseAlphaCode, &info );
//hRes = D3DXLoadSurfaceFromFile( pSurface, NULL, &destrc, szFilename, NULL, D3DX_FILTER_POINT, dwUseAlphaCode, &info );
pSurface->Release();
}
}
// If any of the previous steps failed, release the target texture
// to signal a failure to load.
if ( FAILED ( hRes ) )
SAFE_RELEASE( lpTexture );
}
else
{
///*
// DDS or Other File Format (leefix - 220303 - added TGA to keep alpha load)
if(_strnicmp( szFilename + (strlen(szFilename)-4), ".dds", 4)==NULL
|| _strnicmp( szFilename + (strlen(szFilename)-4), ".png", 4)==NULL
|| _strnicmp( szFilename + (strlen(szFilename)-4), ".tga", 4)==NULL)
{
// lee - 180406 - u6rc10 - not unknown, use file format
D3DFORMAT newImageFormat = info.Format;
// if DDS, load directly with original mipmap data intact
if ( g_iImageBlockMode==1 && pFileInMemoryData )
{
hRes = D3DXCreateTextureFromFileInMemoryEx( m_pD3D, pFileInMemoryData, dwFileInMemorySize, info.Width,info.Height,D3DX_DEFAULT,0,D3DFMT_UNKNOWN,D3DPOOL_MANAGED,D3DX_DEFAULT,D3DX_DEFAULT,0,&info,NULL,&lpTexture );
}
else
{
//(LPVOID) ppBlock, dwBlockSize
hRes = D3DXCreateTextureFromFileInMemoryEx( m_pD3D,(LPVOID)strBuffer.c_str(), strBuffer.length(), info.Width,info.Height,D3DX_DEFAULT,0,D3DFMT_UNKNOWN,D3DPOOL_MANAGED,D3DX_DEFAULT,D3DX_DEFAULT,0,&info,NULL,&lpTexture );
/*
hRes = D3DXCreateTextureFromFileEx( m_pD3D,
szFilename,
info.Width,
info.Height,
D3DX_DEFAULT,
0,
newImageFormat,// 180406 - u6rc10 - D3DFMT_UNKNOWN,//g_DefaultD3Dformat,
D3DPOOL_MANAGED,
D3DX_DEFAULT,
D3DX_DEFAULT,
0, //m_Color, LEEFIX - DDS/TGA has its own Alphamap!
&info,
NULL,
&lpTexture );
*/
}
// 010205 - default mem can run out
if ( lpTexture==NULL )
return NULL;
// adjust to actual size if texture smaller
D3DSURFACE_DESC desc;
lpTexture->GetLevelDesc(0,&desc);
if(desc.Width<info.Width) info.Width=desc.Width;
if(desc.Height<info.Height) info.Height=desc.Height;
}
else
{
///*
// create a new texture/image
hRes = D3DXCreateTexture (
m_pD3D,
info.Width,
info.Height,
D3DX_DEFAULT,
0,
g_DefaultD3Dformat,
//D3DPOOL_DEFAULT, // lee - 240306 - u6b4 - seems this was video only - causing v-mem shortage (could only load few images)
D3DPOOL_MANAGED,
&lpTexture );
// 010205 - default mem can run out
if ( lpTexture==NULL )
return NULL;
// adjust to actual size if texture smaller
D3DSURFACE_DESC desc;
lpTexture->GetLevelDesc(0,&desc);
if(desc.Width<info.Width) info.Width=desc.Width;
if(desc.Height<info.Height) info.Height=desc.Height;
if( SUCCEEDED ( hRes ))
{
// get surface of texture (as many mipmap levels as it has)
for ( DWORD level=0; level<lpTexture->GetLevelCount(); level++ )
{
LPDIRECT3DSURFACE9 pSurface=NULL;
hRes = lpTexture->GetSurfaceLevel(level, &pSurface);
if( SUCCEEDED ( hRes ))
{
// load surface data into it
// leefix-260603-ditheris aweful!
// leefix-220703-changed again so level 0 is clean mip and rest are dithered for good distance textures
if ( g_iImageBlockMode==1 && pFileInMemoryData )
{
if ( level==0 )
hRes = D3DXLoadSurfaceFromFileInMemory( pSurface, NULL, NULL, pFileInMemoryData, dwFileInMemorySize, NULL, D3DX_FILTER_POINT, m_Color, &info );
else
hRes = D3DXLoadSurfaceFromFileInMemory( pSurface, NULL, NULL, pFileInMemoryData, dwFileInMemorySize, NULL, D3DX_DEFAULT, m_Color, &info );
}
else
{
//DWORD ppBlock, DWORD dwBlockSize
if ( level==0 )
{
//hRes = D3DXLoadSurfaceFromFile( pSurface, NULL, NULL, szFilename, NULL, D3DX_FILTER_POINT, m_Color, &info );
hRes = D3DXLoadSurfaceFromFileInMemory( pSurface, NULL, NULL,(LPVOID)strBuffer.c_str(), strBuffer.length(), NULL, D3DX_FILTER_POINT, m_Color, &info );
}
else
{
//hRes = D3DXLoadSurfaceFromFile( pSurface, NULL, NULL, szFilename, NULL, D3DX_DEFAULT, m_Color, &info );
//Slow load
hRes = D3DXLoadSurfaceFromFileInMemory( pSurface, NULL, NULL,(LPVOID)strBuffer.c_str(), strBuffer.length(), NULL, D3DX_DEFAULT, m_Color, &info );
}
}
pSurface->Release();
}
else
break;
}
}
//*/
}
//*/
}
}
// check the texture loaded in ok
if ( !lpTexture )
Error ( "Failed to load texture for image library" );
// needed image info
m_iWidth = info.Width; // file width
m_iHeight = info.Height; // file height
// finally return the pointer
return lpTexture;
}
DARKSDK bool LoadFullTex2 (const std::string& strBuffer, char* szFilename, LPDIRECT3DTEXTURE9* pImage, D3DXIMAGE_INFO* info, int iFullTexturePlateMode, int iDivideTextureSize )
{
// Uses actual or virtual file..
char VirtualFilename[_MAX_PATH];
strcpy(VirtualFilename, szFilename);
g_pGlob->UpdateFilenameFromVirtualTable( (DWORD)VirtualFilename);
// Decrypt and use media
bool bRes = false;
///*
g_pGlob->Decrypt( (DWORD)VirtualFilename );
// load the media
*pImage = GetTextureCore2 (strBuffer, VirtualFilename, 0, iFullTexturePlateMode, iDivideTextureSize );
if ( *pImage ) bRes = true;
// get media info
HRESULT hRes = 0;
if ( g_bImageBlockActive && g_iImageBlockMode==1 )
{
DWORD dwFileInMemorySize = 0;
LPVOID pFileInMemoryData = NULL;
char pFinalRelPathAndFile[512];
GetFileInMemory ( VirtualFilename, &pFileInMemoryData, &dwFileInMemorySize, pFinalRelPathAndFile );
hRes = D3DXGetImageInfoFromFileInMemory( pFileInMemoryData, dwFileInMemorySize, info );
}
// U74 BETA9 - 040709 - get info from physical file if not in image block
if ( hRes==0 || hRes!=D3D_OK )
{
hRes = D3DXGetImageInfoFromFileInMemory((LPVOID)strBuffer.c_str(), strBuffer.length(), info );
//hRes = D3DXGetImageInfoFromFile( VirtualFilename, info );
}
// re-encrypt if applicable
g_pGlob->Encrypt( (DWORD)VirtualFilename );
// success or no
//*/
return bRes;
}
CImageC.h
DARKSDK bool Load2 ( char* szFilename, int iID, int TextureFlag, bool bIgnoreNegLimit, int iDivideTextureSize );
DARKSDK bool Load2 (const std::string& strBuffer,char* szFilename, int iID, int TextureFlag, bool bIgnoreNegLimit, int iDivideTextureSize );
DARKSDK bool LoadFullTex2 (std::string strBuffer, char* szFilename, LPDIRECT3DTEXTURE9* pImage, int iFullTexMode, int iDivideTextureSize );
DarkSDKImage.h
void dbLoadImageFromBuffer (const std::string& strBuffer, char* szFilename, int iID , int TextureFlag, int iDivideTextureSize);
int dbLoadImageInternal2 (const std::string& strBuffer,int iTextureMode, int iDivideTextureSize);
Making dreams possible, one line at a time...