* The hash of textures is now computed the first time they are used. The hash is recomputed if the content might have changed.
* In some games, textures are used as rendering targets (e.g. a mirror or a portal in Portal). The hash calculation of these textures might slow down the game.
-> there is an option to disable the computation of hashes for rendering targets.
* Enable or Disable the support of tpf mods affect now the game immediately.
* Little rearrangements in the GUI.
* uMod can now extract the content of mods to disk and the game loads the textures from there. This solves the huge memory problem of uMod.
This commit is contained in:
code@koerner-de.net
2013-01-07 07:43:38 +00:00
parent 2593729634
commit 601c8c1504
34 changed files with 1523 additions and 1237 deletions
+134 -80
View File
@@ -81,17 +81,7 @@ uMod_TextureServer::~uMod_TextureServer(void)
//delete the files in memory
int num = CurrentMod.GetNumber();
for (int i = 0; i < num; i++)
{
delete [] CurrentMod[i]->pData; //delete the file content of the texture
delete CurrentMod[i]; //delete the structure
}
num = OldMod.GetNumber();
for (int i = 0; i < num; i++)
{
delete [] OldMod[i]->pData; //delete the file content of the texture
delete OldMod[i]; //delete the structure
}
CurrentMod[i]->Release();
if (Clients != NULL) delete [] Clients;
@@ -101,7 +91,7 @@ uMod_TextureServer::~uMod_TextureServer(void)
Pipe.Out = INVALID_HANDLE_VALUE;
}
int uMod_TextureServer::AddClient(uMod_TextureClient *client, TextureFileStruct* &update, int &number, const int version) // called from a client
int uMod_TextureServer::AddClient(uMod_TextureClient *client, TextureEntry* &update, int &number, const int version) // called from a client
{
Message("AddClient(%p): %p\n", client, this);
if (int ret = LockMutex())
@@ -219,7 +209,7 @@ int uMod_TextureServer::AddFile( char* buffer, DWORD64 size, DWORD64 hash, bool
gl_ErrorState |= uMod_ERROR_SERVER;
return (ret);
}
TextureFileStruct* temp = NULL;
TextureFileContent* temp = NULL;
int num = CurrentMod.GetNumber();
for (int i=0; i<num; i++) if (CurrentMod[i]->Hash == hash) //look through all current textures
@@ -231,20 +221,54 @@ int uMod_TextureServer::AddFile( char* buffer, DWORD64 size, DWORD64 hash, bool
return (RETURN_OK); // we still have added this texture
}
}
if (temp==NULL) // if not found, look through all old textures
bool new_file = true;
if (temp!=NULL) //if it was found, we delete the old file content
{
num = OldMod.GetNumber();
for (int i=0; i<num; i++) if (OldMod[i]->Hash == hash)
new_file = false;
if (temp->pData!=NULL) delete [] temp->pData;
temp->pData = NULL;
if (temp->pFileName!=NULL) delete [] temp->pFileName;
temp->pFileName = NULL;
}
else //if it was not found, we need to create a new object
{
new_file = true;
temp = new TextureFileContent;
}
temp->pData = buffer;
temp->Size = (unsigned int) size;
temp->Hash = hash;
//if (new_file) temp->ForceReload = false; // no need to force a load of the texture
//else
temp->ForceReload = force;
Message("uMod_TextureServer::End AddFile(%#llX)\n", hash);
if (new_file) CurrentMod.Add(temp); // new files must be added to the list of the CurrentMod
return (UnlockMutex());
}
int uMod_TextureServer::AddFile( wchar_t* file_name, DWORD64 hash, bool force)
{
Message("uMod_TextureServer::AddFile( %ls, %#llX, %d): %p\n", file_name, hash, force, this);
if (int ret = LockMutex())
{
gl_ErrorState |= uMod_ERROR_SERVER;
return (ret);
}
TextureFileContent* temp = NULL;
int num = CurrentMod.GetNumber();
for (int i=0; i<num; i++) if (CurrentMod[i]->Hash == hash) //look through all current textures
{
if (force) {temp = CurrentMod[i]; break;} // we need to reload it
else
{
temp = OldMod[i];
OldMod.Remove(temp);
CurrentMod.Add(temp);
if (force) break; // we must reload it
else
{
if (buffer!=NULL) delete [] buffer;
return (RETURN_OK); // we should not reload it
}
if (file_name!=NULL) delete [] file_name;
return (RETURN_OK); // we still have added this texture
}
}
@@ -254,21 +278,16 @@ int uMod_TextureServer::AddFile( char* buffer, DWORD64 size, DWORD64 hash, bool
new_file = false;
if (temp->pData!=NULL) delete [] temp->pData;
temp->pData = NULL;
if (temp->pFileName!=NULL) delete [] temp->pFileName;
temp->pFileName = NULL;
}
else //if it was not found, we need to create a new object
{
new_file = true;
temp = new TextureFileStruct;
temp->Reference = -1;
temp = new TextureFileContent;
}
temp->pData = buffer;
for (unsigned int i=0; i<size; i++) temp->pData[i] = buffer[i];
temp->Size = (unsigned int) size;
temp->NumberOfTextures = 0;
temp->Textures = NULL;
temp->pFileName = file_name;
temp->Hash = hash;
//if (new_file) temp->ForceReload = false; // no need to force a load of the texture
@@ -276,12 +295,11 @@ int uMod_TextureServer::AddFile( char* buffer, DWORD64 size, DWORD64 hash, bool
temp->ForceReload = force;
Message("uMod_TextureServer::End AddFile(%#llX)\n", hash);
if (new_file) CurrentMod.Add(temp); // new files must be added to the list of the CurrentMod+
if (new_file) CurrentMod.Add(temp); // new files must be added to the list of the CurrentMod
return (UnlockMutex());
}
int uMod_TextureServer::RemoveFile(DWORD64 hash) // called from Mainloop()
{
Message("RemoveFile( %#llx): %p\n", hash, this);
@@ -294,9 +312,10 @@ int uMod_TextureServer::RemoveFile(DWORD64 hash) // called from Mainloop()
int num = CurrentMod.GetNumber();
for (int i = 0; i < num; i++) if (CurrentMod[i]->Hash == hash)
{
TextureFileStruct* temp = CurrentMod[i];
TextureFileContent* temp = CurrentMod[i];
CurrentMod.Remove(temp);
return (OldMod.Add(temp));
temp->Release();
return 0;
}
return (UnlockMutex());
}
@@ -386,6 +405,23 @@ int uMod_TextureServer::SupportTPF(bool val) // called from Mainloop()
return (UnlockMutex());
}
int uMod_TextureServer::ComputeRenderTargets(bool val) // called from Mainloop()
{
if (BoolComputeRenderTargets == val) return (RETURN_OK);
BoolComputeRenderTargets = val;
if (int ret = LockMutex())
{
gl_ErrorState |= uMod_ERROR_SERVER;
return (ret);
}
for (int i = 0; i < NumberOfClients; i++)
{
Clients[i]->ComputeRenderTargets(BoolComputeRenderTargets);
}
return (UnlockMutex());
}
int uMod_TextureServer::SetSaveDirectory(wchar_t *dir) // called from Mainloop()
{
Message("uMod_TextureServer::SetSaveDirectory( %ls): %p\n", dir, this);
@@ -582,7 +618,7 @@ int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called fr
}
if (client != NULL)
{
TextureFileStruct* update;
TextureEntry* update;
int number;
if (int ret = PrepareUpdate( update, number)) return (ret);
client->AddUpdate(update, number);
@@ -591,7 +627,7 @@ int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called fr
{
for (int i=0; i<NumberOfClients; i++)
{
TextureFileStruct* update;
TextureEntry* update;
int number;
if (int ret = PrepareUpdate( update, number)) return (ret);
Clients[i]->AddUpdate(update, number);
@@ -612,32 +648,34 @@ int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called fr
int TextureFileStruct_Compare( const void * elem1, const void * elem2 )
{
TextureFileStruct *tex1 = (TextureFileStruct*)elem1;
TextureFileStruct *tex2 = (TextureFileStruct*)elem2;
if (tex1->Hash < tex2->Hash) return (-1);
if (tex1->Hash > tex2->Hash) return (+1);
TextureEntry *tex1 = (TextureEntry*)elem1;
TextureEntry *tex2 = (TextureEntry*)elem2;
if (tex1->Content()->Hash < tex2->Content()->Hash) return (-1);
if (tex1->Content()->Hash > tex2->Content()->Hash) return (+1);
return (0);
}
int uMod_TextureServer::PrepareUpdate(TextureFileStruct* &update, int &number) // called from the PropagateUpdate() and AddClient.
int uMod_TextureServer::PrepareUpdate(TextureEntry* &update, int &number) // called from the PropagateUpdate() and AddClient.
// Prepare an update for one client. The allocated memory must deleted by the client.
{
update = NULL;
number = 0;
TextureFileStruct* temp = NULL;
TextureEntry* temp = NULL;
int num = CurrentMod.GetNumber();
if (num>0)
{
try {temp = new TextureFileStruct[num];}
try {temp = new TextureEntry[num];}
catch (...)
{
gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER;
return (RETURN_NO_MEMORY);
}
for (int i=0; i<num; i++) cpy_file_struct(temp[i], (*(CurrentMod[i])));
qsort( temp, num, sizeof(TextureFileStruct), TextureFileStruct_Compare);
for (int i=0; i<num; i++)
temp[i].SetContent(CurrentMod[i]);
qsort( temp, num, sizeof(TextureEntry), TextureFileStruct_Compare);
}
update = temp;
@@ -676,6 +714,7 @@ int uMod_TextureServer::MainLoop(void) // run as a separated thread
DWORD64 texture_received = 0u;
char *texture_data = (char*)0;
bool texture_force = false;
bool texture_file_name = false;
DWORD64 texture_hash = 0u;
Message("MainLoop: started\n");
@@ -698,10 +737,27 @@ int uMod_TextureServer::MainLoop(void) // run as a separated thread
{
if (texture_received<texture_size)
{
if (texture_data==NULL)
{
try
{
texture_data = new char[(unsigned int) texture_size];
}
catch (...)
{
texture_size = 0u;
texture_data = (char*)0;
gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER;
}
}
while (pos<num && texture_received<texture_size) texture_data[texture_received++] = buffer[pos++];
if (texture_received==texture_size)
{
AddFile( texture_data, texture_size, texture_hash, texture_force);
if (texture_file_name)
AddFile( (wchar_t*) texture_data, texture_hash, texture_force);
else
AddFile( texture_data, texture_size, texture_hash, texture_force);
texture_data = (char*)0;
texture_size = 0u;
texture_received = 0u;
@@ -719,34 +775,34 @@ int uMod_TextureServer::MainLoop(void) // run as a separated thread
update_textures=true;
break;
}
/*
case CONTROL_FORCE_RELOAD_TEXTURE: force=true;
case CONTROL_ADD_TEXTURE:
case CONTROL_FORCE_RELOAD_TEXTURE:
{
size = commands->Value;
Message("MainLoop: CONTROL_ADD_TEXTURE (%#lX %u, %u %u): %p\n", commands->Hash, size, sizeof(MsgStruct), sizeof(char), this);
if (pos + sizeof(MsgStruct) + size <= num) AddFile( (wchar_t*) &buffer[pos + sizeof(MsgStruct)], commands->Hash, force);
//update_textures = true;
force = false;
texture_size = commands->Value;
texture_received = 0u;
texture_hash = commands->Hash;
texture_force=true;
texture_file_name=true;
Message("MainLoop: CONTROL_FORCE_RELOAD_TEXTURE (%#llX %llu, %p): %p\n", texture_hash, texture_size, texture_data, this);
break;
}
case CONTROL_ADD_TEXTURE:
{
texture_size = commands->Value;
texture_received = 0u;
texture_hash = commands->Hash;
texture_force=false;
texture_file_name=true;
Message("MainLoop: CONTROL_TEXTURE (%#llX %llu, %p): %p\n", texture_hash, texture_size, texture_data, this);
break;
}
*/
case CONTROL_FORCE_RELOAD_TEXTURE_DATA:
{
texture_size = commands->Value;
texture_received = 0u;
texture_hash = commands->Hash;
texture_force=true;
try
{
texture_data = new char[(unsigned int) texture_size];
}
catch (...)
{
texture_size = 0u;
texture_data = (char*)0;
gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER;
}
texture_file_name=false;
Message("MainLoop: CONTROL_FORCE_RELOAD_TEXTURE_DATA (%#llX %llu, %p): %p\n", texture_hash, texture_size, texture_data, this);
break;
}
@@ -755,17 +811,8 @@ int uMod_TextureServer::MainLoop(void) // run as a separated thread
texture_size = commands->Value;
texture_received = 0u;
texture_hash = commands->Hash;
texture_force=true;
try
{
texture_data = new char[(unsigned int) texture_size];
}
catch (...)
{
texture_size = 0u;
texture_data = (char*)0;
gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER;
}
texture_force=false;
texture_file_name=false;
Message("MainLoop: CONTROL_ADD_TEXTURE_DATA (%#llX %llu, %p): %p\n", texture_hash, texture_size, texture_data, this);
break;
}
@@ -812,6 +859,13 @@ int uMod_TextureServer::MainLoop(void) // run as a separated thread
else SupportTPF(true);
break;
}
case CONTROL_COMPUTE_RENDER_TARGETS:
{
Message("MainLoop: CONTROL_COMPUTE_RENDER_TARGETS (%#llX): %p\n", commands->Value, this);
if (commands->Value == 0) ComputeRenderTargets(false);
else ComputeRenderTargets(true);
break;
}
case CONTROL_SET_DIR:
{
Message("MainLoop: CONTROL_SET_DIR (%ls): %p\n", (wchar_t*) &buffer[pos + sizeof(MsgStruct)], this);