BugFix: checked for NULL pointer when removing a Mod

a lot of improvements and rearrangements in the GUI...
This commit is contained in:
code@koerner-de.net
2011-09-21 20:39:10 +00:00
parent 8fd918f382
commit 0263d78fed
22 changed files with 1385 additions and 576 deletions
+1
View File
@@ -44,6 +44,7 @@ OTM_GUI/OTM_Sender.cpp -text
OTM_GUI/OTM_Sender.h -text
OTM_GUI/OTM_Server.cpp -text
OTM_GUI/OTM_Server.h -text
OTM_GUI/bin/README.txt -text
OTM_GUI/config.gcc -text
OTM_GUI/makefile -text
OTM_GUI/unzip.cpp -text
+2
View File
@@ -215,6 +215,7 @@ int OTM_TextureHandler::Remove(OTM_IDirect3DTexture9* pTexture) //will be called
return (RETURN_OK);
}
/*
int OTM_TextureHandler::RemoveAll(void) //only for deleting all fake textures
{
Message("OTM_TextureHandler::RemoveAll() %d: %lu\n", Number, this);
@@ -222,3 +223,4 @@ int OTM_TextureHandler::RemoveAll(void) //only for deleting all fake textures
Number=0;
return (RETURN_OK);
}
*/
+1 -1
View File
@@ -65,7 +65,7 @@ public:
int Add( OTM_IDirect3DTexture9* texture);
int Remove( OTM_IDirect3DTexture9* texture);
int RemoveAll(void); //only for deleting all fake textures
//int RemoveAll(void); //only for deleting all fake textures
int GetNumber(void) {return (Number);}
OTM_IDirect3DTexture9 *operator [] (int i) {if (i<0||i>=Number) return (NULL); else return (Textures[i/FieldLength][i%FieldLength]);}
+4 -1
View File
@@ -151,7 +151,10 @@ bool HookThisProgramm( wchar_t *ret)
{
//This method should be changed. Maybe the directory should be the user application directory.
FILE* file;
if (_wfopen_s( &file, L"D:\\OTM.txt", L"rt")) return (false);
wchar_t *app_path = _wgetenv( L"APPDATA");
wchar_t file_name[MAX_PATH];
swprintf_s( file_name, MAX_PATH, L"%ls\\%ls\\%ls", app_path, OTM_APP_DIR, OTM_APP_DX9);
if (_wfopen_s( &file, file_name, L"rt")) return (false);
wchar_t Executable[MAX_PATH];
wchar_t Game[MAX_PATH];
+31 -46
View File
@@ -21,12 +21,14 @@ along with FooOpenTexMod. If not, see <http://www.gnu.org/licenses/>.
#include "OTM_Main.h"
int OTM_IDirect3DDevice9::SaveSingleTexture(bool val)
int OTM_IDirect3DDevice9::CreateSingleTexture(void)
{
if (val==BoolSaveSingleTexture) return (RETURN_OK);
if (val && SingleTexture==NULL) //Create green texture
if (SingleTexture==NULL) //Create green texture
{
if( D3D_OK != CreateTexture(8, 8, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, (IDirect3DTexture9**) &SingleTexture, NULL)) return (RETURN_TEXTURE_NOT_LOADED);
LastCreatedTexture = NULL;
SingleTexture->FAKE = true;
DWORD colour32 = D3DCOLOR_ARGB(255,0,255,0); //green
WORD colour16 = ((WORD)((colour32>>28)&0xF)<<12)
@@ -48,12 +50,7 @@ int OTM_IDirect3DDevice9::SaveSingleTexture(bool val)
for (int xy=0; xy < 8*8; xy++) *(pDst16++) = colour16;
pD3Dtex->UnlockRect(0);
}
else if (!val && SingleTexture!=NULL)
{
UnswitchTextures(SingleTexture);
}
BoolSaveSingleTexture = val;
return (RETURN_OK);
}
@@ -65,10 +62,6 @@ OTM_IDirect3DDevice9::OTM_IDirect3DDevice9(IDirect3DDevice9* pOriginal, OTM_Text
LastCreatedTexture = NULL;
m_pIDirect3DDevice9 = pOriginal; // store the pointer to original object
KeyBack = 0;
KeySave = 0;
KeyNext = 0;
BoolSaveSingleTexture = false;
CounterSaveSingleTexture = 0;
SingleTexture = NULL;
//Message("end OTM_IDirect3DDevice9( %lu, %lu): %lu\n", pOriginal, server, this);
@@ -111,9 +104,9 @@ ULONG OTM_IDirect3DDevice9::Release(void)
// Calling original function now
ULONG count = m_pIDirect3DDevice9->Release();
Message("%d = Release(): %lu\n", count, this);
Message("%lu = IDirect3DDevice9::Release(): %lu\n", count, this);
if (count==0)
if (count==0u)
{
// now, the Original Object has deleted itself, so do we here
if (OTM_Client!=NULL)
@@ -356,47 +349,39 @@ HRESULT OTM_IDirect3DDevice9::BeginScene(void)
OTM_Client->AddTexture( LastCreatedTexture);
LastCreatedTexture = NULL;
}
}
if (BoolSaveSingleTexture && KeyBack && KeySave && KeyNext)
{
if (GetAsyncKeyState( KeyBack ) &1 )
if (OTM_Client->BoolSaveSingleTexture)
{
UnswitchTextures( SingleTexture);
if (--CounterSaveSingleTexture<0) CounterSaveSingleTexture = OTM_Client->OriginalTextures.GetNumber() - 1;
if (CounterSaveSingleTexture >= 0) SwitchTextures( SingleTexture, OTM_Client->OriginalTextures[CounterSaveSingleTexture]);
}
if (GetAsyncKeyState( KeySave ) &1 )
{
SingleTexture->Hash = SingleTexture->CrossRef_D3Dtex->Hash;
OTM_Client->SaveTexture( SingleTexture);
SingleTexture->Hash = 0u;
}
if (GetAsyncKeyState( KeyNext ) &1 )
{
UnswitchTextures( SingleTexture);
if (++CounterSaveSingleTexture>=OTM_Client->OriginalTextures.GetNumber()) CounterSaveSingleTexture = 0;
if (CounterSaveSingleTexture < OTM_Client->OriginalTextures.GetNumber()) SwitchTextures( SingleTexture, OTM_Client->OriginalTextures[CounterSaveSingleTexture]);
}
}
if (SingleTexture==NULL) CreateSingleTexture();
/*
if (( gl_ErrorState & (OTM_ERROR_FATAL | OTM_ERROR_MUTEX) )) return(m_pIDirect3DDevice9->BeginScene()); //senseless to wait
if (LastCreatedTexture!=NULL)
{
gl_pTextureHandler->AddOriginalTexture( LastCreatedTexture);
LastCreatedTexture = NULL;
if (SingleTexture!=NULL)
{
if (OTM_Client->KeyBack>0 && (GetAsyncKeyState( OTM_Client->KeyBack ) &1) )
{
UnswitchTextures( SingleTexture);
if (--CounterSaveSingleTexture<0) CounterSaveSingleTexture = OTM_Client->OriginalTextures.GetNumber() - 1;
if (CounterSaveSingleTexture >= 0) SwitchTextures( SingleTexture, OTM_Client->OriginalTextures[CounterSaveSingleTexture]);
}
if (OTM_Client->KeySave>0 && (GetAsyncKeyState( OTM_Client->KeySave ) &1) )
{
SingleTexture->Hash = SingleTexture->CrossRef_D3Dtex->Hash;
OTM_Client->SaveTexture( SingleTexture);
SingleTexture->Hash = 0u;
}
if (OTM_Client->KeyNext>0 && (GetAsyncKeyState( OTM_Client->KeyNext ) &1) )
{
UnswitchTextures( SingleTexture);
if (++CounterSaveSingleTexture>=OTM_Client->OriginalTextures.GetNumber()) CounterSaveSingleTexture = 0;
if (CounterSaveSingleTexture < OTM_Client->OriginalTextures.GetNumber()) SwitchTextures( SingleTexture, OTM_Client->OriginalTextures[CounterSaveSingleTexture]);
}
}
}
}
if (WAIT_OBJECT_0!=WaitForSingleObject( gl_MutexTexture, 100)) gl_ErrorState |= OTM_ERROR_FATAL; //waiting 100ms, to wait infinite pass INFINITE
*/
return(m_pIDirect3DDevice9->BeginScene());
}
HRESULT OTM_IDirect3DDevice9::EndScene(void)
{
//Message("EndScene(): %lu\n", this);
/*
ReleaseMutex(gl_MutexTexture);
*/
return(m_pIDirect3DDevice9->EndScene());
}
+4 -8
View File
@@ -164,19 +164,15 @@ public:
OTM_IDirect3DTexture9* GetLastCreatedTexture(void) {return (LastCreatedTexture);}
int SetLastCreatedTexture(OTM_IDirect3DTexture9* pTexture) {LastCreatedTexture=pTexture; return (RETURN_OK);}
OTM_IDirect3DTexture9* GetSingleTexture(void) {return (SingleTexture);}
int SaveSingleTexture(bool val);
/*
int SetKeyBack( int key) {if (key>0) KeyBack=key; return (0);}
int SetKeySave( int key) {if (key>0) KeySave=key; return (0);}
int SetKeyNext( int key) {if (key>0) KeyNext=key; return (0);}
*/
private:
bool BoolSaveSingleTexture;
int CreateSingleTexture(void);
int CounterSaveSingleTexture;
int KeyBack;
int KeySave;
int KeyNext;
OTM_IDirect3DTexture9* SingleTexture;
IDirect3DDevice9* m_pIDirect3DDevice9;
+21 -10
View File
@@ -31,6 +31,10 @@ OTM_TextureClient::OTM_TextureClient(OTM_TextureServer* server, IDirect3DDevice9
Server = server;
D3D9Device = device;
BoolSaveAllTextures = false;
BoolSaveSingleTexture = false;
KeyBack = 0;
KeySave = 0;
KeyNext = 0;
SavePath[0]=0;
GameName[0]=0;
if (Server!=NULL)
@@ -46,7 +50,6 @@ OTM_TextureClient::OTM_TextureClient(OTM_TextureServer* server, IDirect3DDevice9
Update = NULL;
NumberOfUpdate = -1;
//Message("end OTM_TextureClient(void): %lu\n", this);
}
@@ -70,8 +73,9 @@ OTM_TextureClient::~OTM_TextureClient(void)
int OTM_TextureClient::AddTexture( OTM_IDirect3DTexture9* pTexture)
{
((OTM_IDirect3DDevice9*)D3D9Device)->SetLastCreatedTexture(NULL); //a loop would arise if a texture would be switched
if (pTexture->FAKE) return (RETURN_OK); // this is a fake texture
Message("AddTexture( %lu): %lu (%lu)\n", pTexture, this, GetCurrentThread());
Message("AddTexture( %lu): %lu (thread: %lu)\n", pTexture, this, GetCurrentThread());
D3DLOCKED_RECT d3dlr;
if (pTexture->LockRect( 0, &d3dlr, NULL, 0)!=D3D_OK)
@@ -226,16 +230,24 @@ int OTM_TextureClient::ReleaseAllFakeTexture(void)
int OTM_TextureClient::SaveAllTextures(bool val)
{
Message("SaveAllTextures( %d): %lu\n", val, this);
Message("OTM_TextureClient::SaveAllTextures( %d): %lu\n", val, this);
BoolSaveAllTextures=val;
return (RETURN_OK);
}
int OTM_TextureClient::SaveSingleTexture(bool val)
{
Message("SaveSingleTexture( %d): %lu\n", val, this);
if (D3D9Device!=NULL) return (((OTM_IDirect3DDevice9*)D3D9Device)->SaveSingleTexture(val));
else return (RETURN_NO_IDirect3DDevice9);
Message("OTM_TextureClient::SaveSingleTexture( %d): %lu\n", val, this);
if (BoolSaveSingleTexture && !val)
{
if (D3D9Device!=NULL)
{
OTM_IDirect3DTexture9* pTexture = ((OTM_IDirect3DDevice9*)D3D9Device)->GetSingleTexture();
if (pTexture!=NULL) UnswitchTextures(pTexture);
}
}
BoolSaveSingleTexture = val;
return (RETURN_OK);
}
@@ -347,8 +359,7 @@ int OTM_TextureClient::MergeUpdate(void)
}
if (!found)
{
//FakeTextures.Remove(FileToMod[i].pTexture);
FileToMod[i].pTexture->Release();
if (FileToMod[i].pTexture!=NULL) FileToMod[i].pTexture->Release();
}
}
@@ -409,7 +420,7 @@ int OTM_TextureClient::UnlockMutex(void)
int OTM_TextureClient::LookUpToMod( OTM_IDirect3DTexture9* pTexture) // should only be called for original textures
{
Message("LookUpToMod( %lu): hash: %lu, %lu\n", pTexture, pTexture->Hash, this);
Message("OTM_TextureClient::LookUpToMod( %lu): hash: %#lX, %lu\n", pTexture, pTexture->Hash, this);
if (pTexture->CrossRef_D3Dtex!=NULL) return (RETURN_OK); // to avoid broken links
MyTypeHash hash = pTexture->Hash;
for (int i=0; i<NumberToMod; i++)
@@ -420,7 +431,7 @@ int OTM_TextureClient::LookUpToMod( OTM_IDirect3DTexture9* pTexture) // should o
if (int ret = LoadTexture( & (FileToMod[i]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
{
Message("MergeUpdate(): textures not switched %#lX\n", hash);
Message("OTM_TextureClient::LookUpToMod(): textures not switched %#lX\n", hash);
fake_Texture->Release();
}
else
+8 -4
View File
@@ -50,9 +50,9 @@ public:
int SaveTexture(OTM_IDirect3DTexture9* pTexture);
int SetKeyBack( int key) {if (D3D9Device!=NULL) return (((OTM_IDirect3DDevice9*)D3D9Device)->SetKeyBack(key)); else return (RETURN_NO_IDirect3DDevice9);}
int SetKeySave( int key) {if (D3D9Device!=NULL) return (((OTM_IDirect3DDevice9*)D3D9Device)->SetKeySave(key)); else return (RETURN_NO_IDirect3DDevice9);}
int SetKeyNext( int key) {if (D3D9Device!=NULL) return (((OTM_IDirect3DDevice9*)D3D9Device)->SetKeyNext(key)); else return (RETURN_NO_IDirect3DDevice9);}
int SetKeyBack( int key) {if (key>0) KeyBack = key; return (RETURN_OK);}
int SetKeySave( int key) {if (key>0) KeySave = key; return (RETURN_OK);}
int SetKeyNext( int key) {if (key>0) KeyNext = key; return (RETURN_OK);}
int AddUpdate(TextureFileStruct* update, int number); //client must delete the temp array
int MergeUpdate(void);
@@ -60,11 +60,15 @@ public:
//OTM_TextureHandler FakeTextures;
OTM_TextureHandler OriginalTextures;
bool BoolSaveAllTextures;
bool BoolSaveSingleTexture;
int KeyBack;
int KeySave;
int KeyNext;
private:
OTM_TextureServer* Server;
IDirect3DDevice9* D3D9Device;
bool BoolSaveAllTextures;
wchar_t SavePath[MAX_PATH];
wchar_t GameName[MAX_PATH];
+11 -15
View File
@@ -71,20 +71,18 @@ int OTM_TextureServer::AddClient(OTM_TextureClient *client, TextureFileStruct**
gl_ErrorState |= OTM_ERROR_SERVER;
return (ret);
}
// the following functions must not change the original OTM_IDirect3DDevice9 object
// somehow on game start some OTM_IDirect3DDevice9 object are created, which must rest unchanged!!
// these objects are released and are not uses for rendering
client->SetGameName(GameName);
/*
DO NOT UNCOMMENT THIS
some games create special devices before the rendering device is created. those device should not receive SaveSingleTexture(...)
client->SaveAllTextures(BoolSaveAllTextures);
client->SaveSingleTexture(BoolSaveSingleTexture);
client->SetSaveDirectory(SavePath);
if (KeyBack > 0)
client->SetKeySave(KeyBack);
if (KeySave > 0)
client->SetKeySave(KeySave);
if (KeyNext > 0)
client->SetKeySave(KeyNext);
*/
if (KeyBack > 0) client->SetKeyBack(KeyBack);
if (KeySave > 0) client->SetKeySave(KeySave);
if (KeyNext > 0) client->SetKeyNext(KeyNext);
if (int ret = PrepareUpdate( update, number)) return (ret);
@@ -106,8 +104,6 @@ int OTM_TextureServer::AddClient(OTM_TextureClient *client, TextureFileStruct**
}
Clients[NumberOfClients++] = client;
//PropagateUpdate(client);
return (UnlockMutex());
}
@@ -190,7 +186,7 @@ int OTM_TextureServer::AddFile( char* buffer, unsigned int size, MyTypeHash has
if (new_file) temp->ForceReload = false;
else temp->ForceReload = force;
Message("End AddFile( %lu)\n", hash);
Message("End AddFile(%#lX)\n", hash);
if (new_file) return (CurrentMod.Add(temp));
else return (RETURN_OK);
}
@@ -276,7 +272,7 @@ int OTM_TextureServer::AddFile(wchar_t* file_name, MyTypeHash hash, bool force)
if (new_file) temp->ForceReload = false;
else temp->ForceReload = force;
Message("End AddFile( %lu)\n", hash);
Message("End AddFile(%#lX)\n", hash);
if (new_file) return (CurrentMod.Add(temp));
else return (RETURN_OK);
}
@@ -525,7 +521,7 @@ int OTM_TextureServer::MainLoop(void) // run as a separated thread !!
case CONTROL_ADD_TEXTURE_DATA:
{
size = commands->Value;
Message("MainLoop: CONTROL_ADD_TEXTURE (%#lX %u, %u %u): %lu\n", commands->Hash, size, sizeof(MsgStruct), sizeof(char), this);
Message("MainLoop: CONTROL_ADD_TEXTURE_DATA (%#lX %u, %u %u): %lu\n", commands->Hash, size, sizeof(MsgStruct), sizeof(char), this);
if (pos + sizeof(MsgStruct) + size <= num) AddFile( &buffer[pos + sizeof(MsgStruct)], size, commands->Hash, force);
update_textures = true;
force = false;
+169 -24
View File
@@ -36,11 +36,14 @@ BEGIN_EVENT_TABLE(OTM_Frame, wxFrame)
EVT_BUTTON(ID_Button_Open, OTM_Frame::OnButtonOpen)
EVT_BUTTON(ID_Button_Path, OTM_Frame::OnButtonPath)
EVT_BUTTON(ID_Button_Update, OTM_Frame::OnButtonUpdate)
EVT_BUTTON(ID_Button_Save, OTM_Frame::OnButtonSave)
EVT_MENU(ID_Menu_Pref, OTM_Frame::OnMenuPref)
EVT_MENU(ID_Menu_Quit, OTM_Frame::OnMenuQuit)
//EVT_MENU(ID_Menu_Pref, OTM_Frame::OnMenuPref)
//EVT_MENU(ID_Menu_Quit, OTM_Frame::OnMenuQuit)
EVT_MENU(ID_Menu_Help, OTM_Frame::OnMenuHelp)
EVT_MENU(ID_Menu_About, OTM_Frame::OnMenuAbout)
EVT_MENU(ID_Menu_AddGame, OTM_Frame::OnMenuAddGame)
EVT_MENU(ID_Menu_DeleteGame, OTM_Frame::OnMenuDeleteGame)
EVT_COMMAND (ID_Add_Game, OTM_EVENT_TYPE, OTM_Frame::OnAddGame)
EVT_COMMAND (ID_Delete_Game, OTM_EVENT_TYPE, OTM_Frame::OnDeleteGame)
@@ -52,7 +55,7 @@ IMPLEMENT_APP(MyApp)
bool MyApp::OnInit(void)
{
OTM_Frame *frame = new OTM_Frame( "OpenTexMod", wxDefaultPosition, wxSize(600,400));
OTM_Frame *frame = new OTM_Frame( "OpenTexMod V0.9 alpha by ROTA", wxDefaultPosition, wxSize(600,400));
SetTopWindow( frame );
return true;
@@ -73,16 +76,21 @@ OTM_Frame::OTM_Frame(const wxString& title, const wxPoint& pos, const wxSize& si
Server->Run();
MenuBar = new wxMenuBar;
MenuMain = new wxMenu;
//MenuMain = new wxMenu;
MenuGame = new wxMenu;
MenuHelp = new wxMenu;
MenuMain->Append( ID_Menu_Pref, Language.MenuPref, Language.MenuPref );
MenuMain->Append( ID_Menu_Quit, Language.MenuQuit, Language.MenuQuit );
//MenuMain->Append( ID_Menu_Pref, Language.MenuPref, Language.MenuPref );
//MenuMain->Append( ID_Menu_Quit, Language.MenuQuit, Language.MenuQuit );
MenuGame->Append( ID_Menu_AddGame, Language.MenuAddGame, Language.MenuAddGame );
MenuGame->Append( ID_Menu_DeleteGame, Language.MenuDeleteGame, Language.MenuDeleteGame );
MenuHelp->Append( ID_Menu_Help, Language.MenuHelp, Language.MenuHelp );
MenuHelp->Append( ID_Menu_About, Language.MenuAbout, Language.MenuAbout );
MenuBar->Append( MenuMain, Language.MainMenuStart );
//MenuBar->Append( MenuMain, Language.MainMenuStart );
MenuBar->Append( MenuGame, Language.MainMenuGame );
MenuBar->Append( MenuHelp, Language.MainMenuHelp );
SetMenuBar(MenuBar);
@@ -98,9 +106,12 @@ OTM_Frame::OTM_Frame(const wxString& title, const wxPoint& pos, const wxSize& si
OpenButton = new wxButton( this, ID_Button_Open, Language.ButtonOpen, wxDefaultPosition, wxSize(100,24));
DirectoryButton = new wxButton( this, ID_Button_Path, Language.ButtonDirectory, wxDefaultPosition, wxSize(100,24));
UpdateButton = new wxButton( this, ID_Button_Update, Language.ButtonUpdate, wxDefaultPosition, wxSize(100,24));
SaveButton = new wxButton( this, ID_Button_Save, Language.ButtonSave, wxDefaultPosition, wxSize(100,24));
ButtonSizer->Add( (wxWindow*) OpenButton, 1, wxEXPAND, 0);
ButtonSizer->Add( (wxWindow*) DirectoryButton, 1, wxEXPAND, 0);
ButtonSizer->Add( (wxWindow*) UpdateButton, 1, wxEXPAND, 0);
ButtonSizer->Add( (wxWindow*) SaveButton, 1, wxEXPAND, 0);
MainSizer->Add( ButtonSizer, 0, wxEXPAND , 0 );
@@ -108,7 +119,6 @@ OTM_Frame::OTM_Frame(const wxString& title, const wxPoint& pos, const wxSize& si
NumberOfGames = 0;
MaxNumberOfGames = 10;
Games = new OTM_GameInfo*[MaxNumberOfGames];
Clients = new OTM_Client*[MaxNumberOfGames];
Show( true );
@@ -118,7 +128,6 @@ OTM_Frame::OTM_Frame(const wxString& title, const wxPoint& pos, const wxSize& si
typedef void (*fkt_typ)(void);
fkt_typ InstallHook = (fkt_typ) GetProcAddress( hMod, "InstallHook");
InstallHook();
}
OTM_Frame::~OTM_Frame(void)
@@ -136,6 +145,8 @@ OTM_Frame::~OTM_Frame(void)
fkt_typ RemoveHook = (fkt_typ) GetProcAddress( hMod, "RemoveHook");
RemoveHook();
FreeLibrary(hMod);
if (Clients!=NULL) delete [] Clients;
}
int OTM_Frame::KillServer(void)
@@ -172,16 +183,14 @@ void OTM_Frame::OnAddGame( wxCommandEvent &event)
pipe.In = ((OTM_Event&)event).GetPipeIn();
pipe.Out = ((OTM_Event&)event).GetPipeOut();
OTM_GameInfo *game = new OTM_GameInfo( name);
OTM_Client *client = new OTM_Client( pipe, this);
client->Create();
client->Run();
OTM_GamePage *page = new OTM_GamePage( Notebook, game, client->Pipe, Language);
OTM_GamePage *page = new OTM_GamePage( Notebook, name, client->Pipe, Language);
Notebook->AddPage( page, name, true);
Games[NumberOfGames] = game;
Clients[NumberOfGames] = client;
NumberOfGames++;
}
@@ -193,12 +202,9 @@ void OTM_Frame::OnDeleteGame( wxCommandEvent &event)
for (int i=0; i<NumberOfGames; i++) if (Clients[i]==client)
{
Notebook->DeletePage(i);
//Games[i]->Wait();
Clients[i]->Delete();
delete Clients[i];
delete Games[i];
NumberOfGames--;
for (int j=i; j<NumberOfGames; j++) Games[j] = Games[j+1];
for (int j=i; j<NumberOfGames; j++) Clients[j] = Clients[j+1];
return;
}
@@ -209,9 +215,8 @@ void OTM_Frame::OnClose(wxCloseEvent& event)
{
if (event.CanVeto() && NumberOfGames>0)
{
event.Veto();
wxMessageBox("Very bad idea to close OpenTexMod before closing the hooked Games!", "ERROR", wxOK);
return;
if (wxMessageBox(Language.ExitGameAnyway, "ERROR", wxYES_NO)!=wxYES) {event.Veto(); return;}
}
event.Skip();
Destroy();
@@ -223,10 +228,10 @@ void OTM_Frame::OnButtonOpen(wxCommandEvent& WXUNUSED(event))
OTM_GamePage *page = (OTM_GamePage*) Notebook->GetCurrentPage();
if (page==NULL) return;
wxString file_name = wxFileSelector( Language.ChooseFile, TexturePath, "", "*.*", "textures (*.dds)|*.dds|zip (*.zip)|*.zip|tpf (*.tpf)|*.tpf", wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
wxString file_name = wxFileSelector( Language.ChooseFile, page->GetOpenPath(), "", "*.*", "textures (*.dds)|*.dds|zip (*.zip)|*.zip|tpf (*.tpf)|*.tpf", wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
if ( !file_name.empty() )
{
TexturePath = file_name.BeforeLast( '/');
page->SetOpenPath(file_name.BeforeLast( '/'));
page->AddTexture( file_name);
}
}
@@ -237,10 +242,10 @@ void OTM_Frame::OnButtonPath(wxCommandEvent& WXUNUSED(event))
OTM_GamePage *page = (OTM_GamePage*) Notebook->GetCurrentPage();
if (page==NULL) return;
wxString dir = wxDirSelector(Language.ChooseDir);
wxString dir = wxDirSelector( Language.ChooseDir, page->GetSavePath());
if ( !dir.empty() )
{
page->SetPath( dir);
page->SetSavePath( dir);
}
}
@@ -252,11 +257,151 @@ void OTM_Frame::OnButtonUpdate(wxCommandEvent& WXUNUSED(event))
page->UpdateGame();
}
void OTM_Frame::OnButtonSave(wxCommandEvent& WXUNUSED(event))
{
if (Notebook->GetPageCount()==0) return;
OTM_GamePage *page = (OTM_GamePage*) Notebook->GetCurrentPage();
if (page==NULL) return;
page->SaveToFile();
}
/*
void OTM_Frame::OnMenuPref(wxCommandEvent& WXUNUSED(event)) {}
void OTM_Frame::OnMenuQuit(wxCommandEvent& WXUNUSED(event)) {Destroy();}
void OTM_Frame::OnMenuHelp(wxCommandEvent& WXUNUSED(event)) {}
*/
void OTM_Frame::OnMenuHelp(wxCommandEvent& WXUNUSED(event))
{
wxFile dat;
if (!dat.Access( "README.txt", wxFile::read)) return;
dat.Open("README.txt", wxFile::read);
if (!dat.IsOpened()) {return;}
unsigned len = dat.Length();
char* buffer;
try {buffer = new char [len+1];}
catch (...) {return ;}
unsigned int result = dat.Read( buffer, len);
dat.Close();
if (len!=result) {delete [] buffer; return;}
buffer[len] = 0;
wxString msg = buffer;
wxMessageBox(msg, "help", wxOK);
}
void OTM_Frame::OnMenuAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox("OpenTexMod V0.0 by ROTA", "Info", wxOK);
wxMessageBox(L"OpenTexMod V0.9 alpha by ROTA\nhttp://code.google.com/p/texmod/", "Info", wxOK);
};
void OTM_Frame::OnMenuAddGame(wxCommandEvent& WXUNUSED(event))
{
wxString file_name = wxFileSelector( Language.ChooseFile, "", "", "exe", "binary (*.exe)|*.exe", wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
if ( !file_name.empty() )
{
file_name = file_name.AfterLast('\\');
wxArrayString array;
GetHookedGames( array);
int num = array.GetCount();
for (int i=0; i<num; i++) if (array[i] == file_name)
{
wxMessageBox(Language.GameAlreadyAdded, "ERROR", wxOK);
return;
}
array.Add(file_name);
SetHookedGames( array);
}
}
void OTM_Frame::OnMenuDeleteGame(wxCommandEvent& WXUNUSED(event))
{
wxArrayInt selections;
wxArrayString array;
GetHookedGames(array);
wxGetSelectedChoices( selections, Language.DeleteGame, Language.DeleteGame, array);
int num = selections.GetCount();
for (int i=0; i<num; i++)
{
array.RemoveAt( selections[i]-i); //this will work only if selections is sorted !!
}
SetHookedGames(array);
}
int OTM_Frame::GetHookedGames( wxArrayString &array)
{
wxFile file;
wxString name;
wchar_t *app_path = _wgetenv( L"APPDATA");
name.Printf("%ls\\%ls\\%ls", app_path, OTM_APP_DIR, OTM_APP_DX9);
if (!file.Access(name, wxFile::read)) return -1;
file.Open(name, wxFile::read);
if (!file.IsOpened()) {return -1;}
unsigned len = file.Length();
unsigned char* buffer;
try {buffer = new unsigned char [len+1];}
catch (...) {return -1;}
unsigned int result = file.Read( buffer, len);
file.Close();
if (result != len) return -1;
buffer[len]=0;
wxString content;
content = buffer;
delete [] buffer;
wxStringTokenizer token( content, "\n");
int num = token.CountTokens();
array.Empty();
for (int i=0; i<num; i++)
{
array.Add( token.GetNextToken());
}
file.Close();
return 0;
}
int OTM_Frame::SetHookedGames( const wxArrayString &array)
{
wxFile file;
wxString name;
wchar_t *app_path = _wgetenv( L"APPDATA");
name.Printf("%ls\\%ls", app_path, OTM_APP_DIR);
if (! wxDir::Exists(name))
{
wxDir::Make(name);
}
name.Printf("%ls\\%ls\\%ls", app_path, OTM_APP_DIR, OTM_APP_DX9);
file.Open(name, wxFile::write);
if (!file.IsOpened()) {return -1;}
wxString content;
int num = array.GetCount();
for (int i=0; i<num; i++)
{
content = array[i];
content << "\n";
file.Write( content.char_str(), content.Len());
}
file.Close();
return 0;
}
+10 -6
View File
@@ -40,15 +40,20 @@ public:
void OnButtonOpen(wxCommandEvent& WXUNUSED(event));
void OnButtonPath(wxCommandEvent& WXUNUSED(event));
void OnButtonUpdate(wxCommandEvent& WXUNUSED(event));
void OnButtonSave(wxCommandEvent& WXUNUSED(event));
void OnMenuPref(wxCommandEvent& WXUNUSED(event));
void OnMenuQuit(wxCommandEvent& WXUNUSED(event));
//void OnMenuPref(wxCommandEvent& WXUNUSED(event));
//void OnMenuQuit(wxCommandEvent& WXUNUSED(event));
void OnMenuHelp(wxCommandEvent& WXUNUSED(event));
void OnMenuAbout(wxCommandEvent& WXUNUSED(event));
void OnMenuAddGame(wxCommandEvent& WXUNUSED(event));
void OnMenuDeleteGame(wxCommandEvent& WXUNUSED(event));
private:
int KillServer(void);
int GetHookedGames( wxArrayString &array);
int SetHookedGames( const wxArrayString &array);
OTM_Server *Server;
@@ -59,21 +64,20 @@ private:
wxButton *OpenButton;
wxButton *DirectoryButton;
wxButton *UpdateButton;
wxButton *SaveButton;
wxMenuBar *MenuBar;
wxMenu *MenuMain;
//wxMenu *MenuMain;
wxMenu *MenuGame;
wxMenu *MenuHelp;
wxBoxSizer *MainSizer;
wxBoxSizer *ButtonSizer;
wxString TexturePath;
int NumberOfGames;
int MaxNumberOfGames;
OTM_GameInfo **Games;
OTM_Client **Clients;
DECLARE_EVENT_TABLE();
+233 -6
View File
@@ -25,12 +25,11 @@ along with FooOpenTexMod. If not, see <http://www.gnu.org/licenses/>.
OTM_GameInfo::OTM_GameInfo(const wxString &name)
{
Name = name;
SaveSingleTexture = false;
SaveAllTextures = false;
KeyBack = 0;
KeySave = 0;
KeyNext = 0;
Checked = NULL;
NumberOfChecked = 0;
LengthOfChecked = 0;
Init();
}
@@ -38,6 +37,211 @@ OTM_GameInfo::~OTM_GameInfo(void)
{
}
void OTM_GameInfo::Init(void)
{
SaveSingleTexture = false;
SaveAllTextures = false;
KeyBack = -1;
KeySave = -1;
KeyNext = -1;
NumberOfChecked = 0;
SavePath.Empty();
OpenPath.Empty();
Textures.Empty();
}
int OTM_GameInfo::SaveToFile( const wxString &file_name)
{
wxString name = file_name;
name += L"_save.txt";
wxFile file;
//if (!file.Access(name, wxFile::write)) return -1;
file.Open(name, wxFile::write);
if (!file.IsOpened()) {return -1;}
wxString content;
if (SavePath.Len()>0)
{
content.Printf( L"SavePath:%ls\n", SavePath.wc_str());
file.Write( content.char_str(), content.Len());
}
if (OpenPath.Len()>0)
{
content.Printf( L"OpenPath:%ls\n", OpenPath.wc_str());
file.Write( content.char_str(), content.Len());
}
content.Printf( L"SaveAllTextures:%d\nSaveSingeTexture:%d\n", SaveAllTextures, SaveSingleTexture);
file.Write( content.char_str(), content.Len());
if (KeyBack>=0)
{
content.Printf( L"KeyBack:%d\n", KeyBack);
file.Write( content.char_str(), content.Len());
}
if (KeySave>=0)
{
content.Printf( L"KeySave:%d\n", KeySave);
file.Write( content.char_str(), content.Len());
}
if (KeyNext>=0)
{
content.Printf( L"KeyNext:%d\n", KeyNext);
file.Write( content.char_str(), content.Len());
}
int num = Textures.GetCount();
for (int i=0; i<num; i++)
{
if (i<NumberOfChecked)
{
if (Checked[i]) content.Printf( L"Add_true:%ls\n", Textures[i].wc_str());
else content.Printf( L"Add_false:%ls\n", Textures[i].wc_str());
}
else content.Printf( L"Add_true:%ls\n", Textures[i].wc_str());
file.Write( content.char_str(), content.Len());
}
file.Close();
return 0;
}
int OTM_GameInfo::LoadFromFile( const wxString &file_name)
{
Init();
wxString name = file_name;
name += L"_save.txt";
wxFile file;
if (!file.Access(name, wxFile::read)) return -1;
file.Open(name, wxFile::read);
if (!file.IsOpened()) {return -1;}
unsigned len = file.Length();
unsigned char* buffer;
try {buffer = new unsigned char [len+1];}
catch (...) {return -1;}
unsigned int result = file.Read( buffer, len);
file.Close();
if (result != len) return -1;
buffer[len]=0;
wxString content;
content = buffer;
delete [] buffer;
wxStringTokenizer token( content, "\n");
int num = token.CountTokens();
if (LengthOfChecked<num)
{
if (Checked!=NULL) delete [] Checked;
try {Checked = new bool [num+100];}
catch (...) {Checked=NULL; return -1;}
LengthOfChecked = num+100;
}
wxString line;
wxString command;
wxString temp;
for (int i=0; i<num; i++)
{
line = token.GetNextToken();
command = line.BeforeFirst(':');
if (command == L"Add_true")
{
Checked[NumberOfChecked++] = true;
Textures.Add(line.AfterFirst(':'));
}
else if (command == L"Add_false")
{
Checked[NumberOfChecked++] = false;
Textures.Add(line.AfterFirst(':'));
}
else if (command == L"SavePath") SavePath = line.AfterFirst(':');
else if (command == L"OpenPath") OpenPath = line.AfterFirst(':');
else if (command == L"SaveAllTextures")
{
temp = line.AfterFirst(':');
if (temp[0]=='0') SaveAllTextures = false;
else SaveAllTextures = true;
}
else if (command == L"SaveSingleTexture")
{
temp = line.AfterFirst(':');
if (temp[0]=='0') SaveSingleTexture = false;
else SaveSingleTexture = true;
}
else if (command == L"KeyBack")
{
temp = line.AfterFirst(':');
long key;
if (temp.ToLong( &key)) KeyBack = key;
else KeyBack = -1;
}
else if (command == L"KeySave")
{
temp = line.AfterFirst(':');
long key;
if (temp.ToLong( &key)) KeySave = key;
else KeySave = -1;
}
else if (command == L"KeyNext")
{
temp = line.AfterFirst(':');
long key;
if (temp.ToLong( &key)) KeyNext = key;
else KeyNext = -1;
}
if (NumberOfChecked>=LengthOfChecked)
{
bool *t_bool;
try {t_bool = new bool [LengthOfChecked+100];}
catch (...) {return -1;}
for (int i=0; i<LengthOfChecked; i++) t_bool[i]=Checked[i];
delete [] Checked;
Checked = t_bool;
LengthOfChecked +=100;
}
}
return 0;
}
int OTM_GameInfo::GetChecked( bool* array, int num) const
{
for (int i=0; i<num && i<NumberOfChecked; i++) array[i] = Checked[i];
return 0;
}
int OTM_GameInfo::SetChecked( bool* array, int num)
{
if (num>NumberOfChecked)
{
if (Checked!=NULL) delete [] Checked;
try {Checked = new bool [num+100];}
catch (...) {Checked=NULL; return -1;}
LengthOfChecked = num+100;
}
for (int i=0; i<num; i++) Checked[i] = array[i];
return 0;
}
int OTM_GameInfo::SetSaveSingleTexture(bool val)
{
SaveSingleTexture = val;
@@ -55,7 +259,7 @@ void OTM_GameInfo::SetTextures(const wxArrayString &textures)
Textures = textures;
}
void OTM_GameInfo::GetTextures( wxArrayString &textures)
void OTM_GameInfo::GetTextures( wxArrayString &textures) const
{
textures = Textures;
}
@@ -66,4 +270,27 @@ void OTM_GameInfo::AddTexture( const wxString &textures)
}
OTM_GameInfo& OTM_GameInfo::operator = (const OTM_GameInfo &rhs)
{
SaveSingleTexture = rhs.SaveSingleTexture;
SaveAllTextures = rhs.SaveAllTextures;
KeyBack = rhs.KeyBack;
KeySave = rhs.KeySave;
KeyNext = rhs.KeyNext;
if (LengthOfChecked<rhs.LengthOfChecked)
{
if (Checked!=NULL) delete [] Checked;
Checked = new bool [rhs.LengthOfChecked];
LengthOfChecked = rhs.LengthOfChecked;
}
NumberOfChecked = rhs.NumberOfChecked;
for (int i=0; i<NumberOfChecked; i++) Checked[i] = rhs.Checked[i];
SavePath = rhs.SavePath;
OpenPath = rhs.OpenPath;
Textures = rhs.Textures;
return *this;
}
+30 -9
View File
@@ -29,35 +29,55 @@ class OTM_GameInfo
public:
OTM_GameInfo(const wxString &name);
~OTM_GameInfo(void);
void Init(void);
wxString Name;
int SaveToFile() {return SaveToFile( Name);}
int SaveToFile( const wxString &file_name);
int LoadFromFile() {return LoadFromFile( Name);}
int LoadFromFile( const wxString &file_name);
int GetChecked( bool* array, int num) const;
int SetChecked( bool* array, int num);
int SetSaveSingleTexture(bool val);
bool GetSaveSingleTexture(void) {return SaveSingleTexture;}
bool GetSaveSingleTexture(void) const {return SaveSingleTexture;}
int SetSaveAllTextures(bool val);
bool GetSaveAllTextures(void) {return SaveAllTextures;}
bool GetSaveAllTextures(void) const {return SaveAllTextures;}
void SetTextures(const wxArrayString &textures);
void GetTextures( wxArrayString &textures);
void GetTextures( wxArrayString &textures) const;
void AddTexture( const wxString &textures);
int GetNumberOfTextures(void) const {return Textures.GetCount();}
int SendTextures(void);
int GetKeyBack() {return KeyBack;}
int GetKeyBack() const {return KeyBack;}
int SetKeyBack(int key) {KeyBack=key; return 0;}
int GetKeySave() {return KeySave;}
int GetKeySave() const {return KeySave;}
int SetKeySave(int key) {KeySave=key; return 0;}
int GetKeyNext() {return KeyNext;}
int GetKeyNext() const {return KeyNext;}
int SetKeyNext(int key) {KeyNext=key; return 0;}
int SetPath(const wxString &path) {Path=path; return 0;}
wxString GetPath(void) {return Path;}
int SetOpenPath(const wxString &path) {OpenPath=path; return 0;}
wxString GetOpenPath(void) const {return OpenPath;}
int SetSavePath(const wxString &path) {SavePath=path; return 0;}
wxString GetSavePath(void) const {return SavePath;}
OTM_GameInfo& operator = (const OTM_GameInfo &rhs);
private:
bool *Checked;
int NumberOfChecked;
int LengthOfChecked;
bool SaveSingleTexture;
bool SaveAllTextures;
wxArrayString Textures;
@@ -66,7 +86,8 @@ private:
int KeySave;
int KeyNext;
wxString Path;
wxString OpenPath;
wxString SavePath;
};
+238 -394
View File
@@ -16,471 +16,315 @@ You should have received a copy of the GNU General Public License
along with FooOpenTexMod. If not, see <http://www.gnu.org/licenses/>.
*/
#include "OTM_Main.h"
OTM_GamePage::OTM_GamePage( wxNotebook *parent, OTM_GameInfo *game, PipeStruct &pipe, OTM_Language &lang) : wxPanel(parent), Language(lang), Sender(pipe)
/*
#ifndef __CDT_PARSER__
BEGIN_EVENT_TABLE(OTM_GamePage, wxFrame)
EVT_BUTTON(ID_Button_Open, OTM_Frame::OnButtonUp)
EVT_BUTTON(ID_Button_Path, OTM_Frame::OnButtonDown)
EVT_BUTTON(ID_Button_Update, OTM_Frame::OnButtonDelete)
END_EVENT_TABLE()
#endif
*/
OTM_GamePage::OTM_GamePage( wxNotebook *parent, const wxString &name, PipeStruct &pipe, OTM_Language &lang) : wxPanel(parent), Language(lang), Game(name), GameOld(name), Sender(pipe, lang)
{
MainSizer = new wxBoxSizer(wxVERTICAL);
Game = game;
wxArrayString array;
SizerKeys[0] = new wxBoxSizer(wxHORIZONTAL);
SizerKeys[1] = new wxBoxSizer(wxHORIZONTAL);
array = Language.Keys;
array[0] = Language.KeyBack;
ChoiceKeyBack = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, array);
MainSizer->Add( (wxWindow*) ChoiceKeyBack, 1, wxEXPAND, 0);
TextKeyBack = new wxTextCtrl(this, wxID_ANY, Language.KeyBack, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
SizerKeys[0]->Add( (wxWindow*) TextKeyBack, 1, wxEXPAND, 0);
ChoiceKeyBack = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, Language.KeyStrings);
SizerKeys[1]->Add( (wxWindow*) ChoiceKeyBack, 1, wxEXPAND, 0);
array = Language.Keys;
array[0] = Language.KeySave;
ChoiceKeySave = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, array);
MainSizer->Add( (wxWindow*) ChoiceKeySave, 1, wxEXPAND, 0);
TextKeySave = new wxTextCtrl(this, wxID_ANY, Language.KeySave, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
SizerKeys[0]->Add( (wxWindow*) TextKeySave, 1, wxEXPAND, 0);
ChoiceKeySave = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, Language.KeyStrings);
SizerKeys[1]->Add( (wxWindow*) ChoiceKeySave, 1, wxEXPAND, 0);
array = Language.Keys;
array[0] = Language.KeyNext;
ChoiceKeyNext = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, array);
MainSizer->Add( (wxWindow*) ChoiceKeyNext, 1, wxEXPAND, 0);
TextKeyNext = new wxTextCtrl(this, wxID_ANY, Language.KeyNext, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
SizerKeys[0]->Add( (wxWindow*) TextKeyNext, 1, wxEXPAND, 0);
ChoiceKeyNext = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, Language.KeyStrings);
SizerKeys[1]->Add( (wxWindow*) ChoiceKeyNext, 1, wxEXPAND, 0);
MainSizer->Add( SizerKeys[0], 0, wxEXPAND, 0);
MainSizer->Add( SizerKeys[1], 0, wxEXPAND, 0);
SaveSingleTexture = new wxCheckBox( this, -1, Language.CheckBoxSaveSingleTexture);
MainSizer->Add( (wxWindow*) SaveSingleTexture, 0, wxEXPAND, 0);
SaveAllTextures = new wxCheckBox( this, -1, Language.CheckBoxSaveAllTextures);
MainSizer->Add( (wxWindow*) SaveAllTextures, 0, wxEXPAND, 0);
SavePath = new wxTextCtrl(this, wxID_ANY, Language.TextCtrlSavePath, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
MainSizer->Add( (wxWindow*) SavePath, 0, wxEXPAND, 0);
MainSizer->AddSpacer(10);
Game->GetTextures( array);
NumberOfEntry = array.GetCount()+2;
MaxNumberOfEntry = NumberOfEntry+100;
CheckBoxes = new wxCheckBox*[MaxNumberOfEntry];
CheckBoxes[0] = new wxCheckBox( this, -1, Language.CheckBoxSaveSingleTexture);
CheckBoxes[0]->SetValue( Game->GetSaveSingleTexture());
MainSizer->Add( (wxWindow*) CheckBoxes[0], 1, wxEXPAND, 0);
CheckBoxes[1] = new wxCheckBox( this, -1, Language.CheckBoxSaveAllTextures);
CheckBoxes[1]->SetValue( Game->GetSaveAllTextures());
MainSizer->Add( (wxWindow*) CheckBoxes[1], 1, wxEXPAND, 0);
wxString name;
for (int i=2; i<NumberOfEntry;i++)
if (Game.LoadFromFile())
{
name = array[i-1];
name = name.AfterLast( '/');
CheckBoxes[i] = new wxCheckBox( this, -1, name);
CheckBoxes[i]->SetValue( true);
MainSizer->Add( (wxWindow*) CheckBoxes[i], 1, wxEXPAND, 0);
NumberOfEntry = 0;
MaxNumberOfEntry = 100;
CheckBoxes = new wxCheckBox*[MaxNumberOfEntry];
CheckBoxVSizer = new wxBoxSizer(wxVERTICAL);
CheckBoxHSizers = new wxBoxSizer*[MaxNumberOfEntry];
CheckButtonUp = new wxButton*[MaxNumberOfEntry];
CheckButtonDown = new wxButton*[MaxNumberOfEntry];
CheckButtonDelete = new wxButton*[MaxNumberOfEntry];
SavePath->SetValue(Language.TextCtrlSavePath);
}
else
{
if (Sender.Send( Game, GameOld)==0) GameOld = Game;
int key = Game.GetKeyBack();
if (key>=0) ChoiceKeyBack->SetSelection( key);
key = Game.GetKeySave();
if (key>=0) ChoiceKeySave->SetSelection( key);
key = Game.GetKeyNext();
if (key>=0) ChoiceKeyNext->SetSelection( key);
SaveSingleTexture->SetValue( Game.GetSaveSingleTexture());
SaveAllTextures->SetValue( Game.GetSaveAllTextures());
wxString save_path = Language.TextCtrlSavePath;
save_path << Game.GetSavePath();
SavePath->SetValue(save_path);
wxArrayString array;
Game.GetTextures( array);
NumberOfEntry = array.GetCount();
MaxNumberOfEntry = NumberOfEntry+100;
CheckBoxes = new wxCheckBox*[MaxNumberOfEntry];
bool *checked = new bool[NumberOfEntry];
Game.GetChecked( checked, NumberOfEntry);
CheckBoxVSizer = new wxBoxSizer(wxVERTICAL);
CheckBoxHSizers = new wxBoxSizer*[MaxNumberOfEntry];
CheckButtonUp = new wxButton*[MaxNumberOfEntry];
CheckButtonDown = new wxButton*[MaxNumberOfEntry];
CheckButtonDelete = new wxButton*[MaxNumberOfEntry];
wxString name;
for (int i=0; i<NumberOfEntry;i++)
{
CheckBoxHSizers[i] = new wxBoxSizer(wxHORIZONTAL);
CheckBoxes[i] = new wxCheckBox( this, -1, array[i]);
CheckBoxes[i]->SetValue( checked[i]);
wchar_t button_txt[2];
button_txt[0] = 8657;
button_txt[1] = 0;
CheckButtonUp[i] = new wxButton( this, ID_Button_Texture+3*i, button_txt, wxDefaultPosition, wxSize(24,24));
Bind( wxEVT_COMMAND_BUTTON_CLICKED, &OTM_GamePage::OnButtonUp, this, ID_Button_Texture+3*i);
button_txt[0] = 8659;
CheckButtonDown[i] = new wxButton( this, ID_Button_Texture+3*i+1, button_txt, wxDefaultPosition, wxSize(24,24));
Bind( wxEVT_COMMAND_BUTTON_CLICKED, &OTM_GamePage::OnButtonDown, this, ID_Button_Texture+3*i+1);
CheckButtonDelete[i] = new wxButton( this, ID_Button_Texture+3*i+2, L"X", wxDefaultPosition, wxSize(24,24));
Bind( wxEVT_COMMAND_BUTTON_CLICKED, &OTM_GamePage::OnButtonDelete, this, ID_Button_Texture+3*i+2);
CheckBoxHSizers[i]->Add( (wxWindow*) CheckBoxes[i], 1, wxEXPAND, 0);
CheckBoxHSizers[i]->Add( (wxWindow*) CheckButtonUp[i], 0, wxEXPAND, 0);
CheckBoxHSizers[i]->Add( (wxWindow*) CheckButtonDown[i], 0, wxEXPAND, 0);
CheckBoxHSizers[i]->Add( (wxWindow*) CheckButtonDelete[i], 0, wxEXPAND, 0);
MainSizer->Add( CheckBoxHSizers[i], 0, wxEXPAND, 0);
}
delete [] checked;
}
SetSizer(MainSizer);
}
OTM_GamePage::~OTM_GamePage(void)
{
delete [] CheckBoxHSizers;
delete [] CheckButtonUp;
delete [] CheckButtonDown;
delete [] CheckButtonDelete;
delete [] CheckBoxes;
}
void OTM_GamePage::SetPath( const wxString &path)
int OTM_GamePage::SetSavePath( const wxString &path)
{
if (path!=Game->GetPath())
{
Game->SetPath( path);
Sender.SendPath( path);
}
wxString save_path = path;
save_path.Prepend(Language.TextCtrlSavePath);
SavePath->SetValue(save_path);
Game.SetSavePath( path);
return 0;
}
void OTM_GamePage::AddTexture( const wxString &file_name)
{
if (NumberOfEntry>=MaxNumberOfEntry) return;
Game->AddTexture( file_name);
wxString file = file_name.AfterLast( '/');
CheckBoxes[NumberOfEntry] = new wxCheckBox( this, -1, file);
CheckBoxHSizers[NumberOfEntry] = new wxBoxSizer(wxHORIZONTAL);
CheckBoxes[NumberOfEntry] = new wxCheckBox( this, -1, file_name);
CheckBoxes[NumberOfEntry]->SetValue( true);
MainSizer->Add( (wxWindow*) CheckBoxes[NumberOfEntry], 1, wxEXPAND, 0);
NumberOfEntry++;
wchar_t button_txt[2];
button_txt[0] = 8657;
button_txt[1] = 0;
CheckButtonUp[NumberOfEntry] = new wxButton( this, ID_Button_Texture+3*NumberOfEntry, button_txt, wxDefaultPosition, wxSize(24,24));
Bind( wxEVT_COMMAND_BUTTON_CLICKED, &OTM_GamePage::OnButtonUp, this, ID_Button_Texture+3*NumberOfEntry);
button_txt[0] = 8659;
CheckButtonDown[NumberOfEntry] = new wxButton( this, ID_Button_Texture+3*NumberOfEntry+1, button_txt, wxDefaultPosition, wxSize(24,24));
Bind( wxEVT_COMMAND_BUTTON_CLICKED, &OTM_GamePage::OnButtonDown, this, ID_Button_Texture+3*NumberOfEntry+1);
CheckButtonDelete[NumberOfEntry] = new wxButton( this, ID_Button_Texture+3*NumberOfEntry+2, L"X", wxDefaultPosition, wxSize(24,24));
Bind( wxEVT_COMMAND_BUTTON_CLICKED, &OTM_GamePage::OnButtonDelete, this, ID_Button_Texture+3*NumberOfEntry+2);
CheckBoxHSizers[NumberOfEntry]->Add( (wxWindow*) CheckBoxes[NumberOfEntry], 1, wxEXPAND, 0);
CheckBoxHSizers[NumberOfEntry]->Add( (wxWindow*) CheckButtonUp[NumberOfEntry], 0, wxEXPAND, 0);
CheckBoxHSizers[NumberOfEntry]->Add( (wxWindow*) CheckButtonDown[NumberOfEntry], 0, wxEXPAND, 0);
CheckBoxHSizers[NumberOfEntry]->Add( (wxWindow*) CheckButtonDelete[NumberOfEntry], 0, wxEXPAND, 0);
MainSizer->Add( CheckBoxHSizers[NumberOfEntry], 0, wxEXPAND, 0);
NumberOfEntry++;
Game.AddTexture( file_name);
MainSizer->Layout();
}
int OTM_GamePage::UpdateGame(void)
{
bool save_tex = CheckBoxes[0]->GetValue();
if (save_tex != Game->GetSaveSingleTexture())
{
Sender.SendSaveSingleTexture(save_tex);
Game->SetSaveSingleTexture(save_tex);
if (save_tex)
{
//to add get choices
int key_back = VK_DIVIDE;
int key_save = VK_MULTIPLY;
int key_next = VK_SUBTRACT;
Game.SetSaveSingleTexture(SaveSingleTexture->GetValue());
Game.SetSaveAllTextures(SaveAllTextures->GetValue());
if (key_back!=Game->GetKeyBack())
{
Game->SetKeyBack( key_back);
Sender.SendKeyBack(key_back);
}
if (key_save!=Game->GetKeySave())
{
Game->SetKeySave( key_save);
Sender.SendKeySave(key_save);
}
if (key_next!=Game->GetKeyNext())
{
Game->SetKeyNext( key_next);
Sender.SendKeyNext(key_next);
}
}
}
int key = ChoiceKeyBack->GetSelection();
if (key!=wxNOT_FOUND) Game.SetKeyBack(key);
save_tex = CheckBoxes[1]->GetValue();
if (save_tex != Game->GetSaveAllTextures())
{
Sender.SendSaveAllTextures(save_tex);
Game->SetSaveAllTextures(save_tex);
}
key = ChoiceKeySave->GetSelection();
if (key!=wxNOT_FOUND) Game.SetKeySave(key);
if (NumberOfEntry<=2) return 0;
wxArrayString textures;
Game->GetTextures( textures);
int num = textures.GetCount();
if (num!=NumberOfEntry-2) return -1;
AddTextureClass *tex = new AddTextureClass[num];
wxString file_type;
unsigned long temp_hash;
for (int i=0; i<num; i++)
{
file_type = textures[i];
file_type = file_type.AfterLast( '.');
if (file_type == L"zip")
{
AddZip( &tex[i], textures[i], CheckBoxes[i+2]->GetValue(), true, false);
}
else if (file_type == L"tpf")
{
AddZip( &tex[i], textures[i], CheckBoxes[i+2]->GetValue(), true, true);
}
else if (file_type == L"dds")
{
AddFile( &tex[i], textures[i], CheckBoxes[i+2]->GetValue(), true);
}
else
{
wxString msg = Language.FileNotSupported;
msg << textures[i];
wxMessageBox(msg, "ERROR", wxOK);
}
}
Sender.SendTextures( num, tex);
key = ChoiceKeyNext->GetSelection();
if (key!=wxNOT_FOUND) Game.SetKeyNext(key);
bool *checked = new bool[NumberOfEntry];
for (int i=0; i<NumberOfEntry; i++) checked[i] = CheckBoxes[i]->GetValue();
Game.SetChecked( checked, NumberOfEntry);
delete [] checked;
if (int ret = Sender.Send( Game, GameOld)) return ret;
GameOld = Game;
return 0;
}
int OTM_GamePage::AddFile( AddTextureClass *tex, wxString file, bool add, bool force)
int OTM_GamePage::SaveToFile( const wxString &file_name)
{
tex->SetSize(1);
unsigned long temp_hash;
Game.SetSaveSingleTexture(SaveSingleTexture->GetValue());
Game.SetSaveAllTextures(SaveAllTextures->GetValue());
wxString name = file.AfterLast( '_');
name = name.BeforeLast( '.');
if (!name.ToULong( &temp_hash, 16)) return -1; // return if hash could not be extracted
int key = ChoiceKeyBack->GetSelection();
if (key!=wxNOT_FOUND) Game.SetKeyBack(key);
tex->Add[0] = add;
if (add)
{
wxFile dat(file, wxFile::read);
if (!dat.IsOpened()) {return -1;}
unsigned len = file.Length();
key = ChoiceKeySave->GetSelection();
if (key!=wxNOT_FOUND) Game.SetKeySave(key);
try {tex->Textures[0] = new char [len];}
catch (...) {tex->Textures[0] = NULL; return -1;}
key = ChoiceKeyNext->GetSelection();
if (key!=wxNOT_FOUND) Game.SetKeyNext(key);
unsigned int result = dat.Read( (void*) tex->Textures[0], len);
dat.Close();
bool *checked = new bool[NumberOfEntry];
for (int i=0; i<NumberOfEntry; i++) checked[i] = CheckBoxes[i]->GetValue();
Game.SetChecked( checked, NumberOfEntry);
delete [] checked;
if (result != len) return -1;
tex->Size[0] = len;
}
else {tex->Size[0] = 0; tex->Textures[0] = NULL;}
tex->Num = 1;
tex->Force[0] = true;
tex->Hash[0] = temp_hash;
return 0;
return Game.SaveToFile( file_name);
}
int OTM_GamePage::AddZip( AddTextureClass *tex, wxString file, bool add, bool force, bool tpf)
void OTM_GamePage::OnButtonUp(wxCommandEvent& event)
{
wxFile dat(file, wxFile::read);
if (!dat.IsOpened()) {return -1;}
unsigned len = dat.Length();
int id = (event.GetId() - ID_Button_Texture)/3;
if (id <=0 || id>= NumberOfEntry) return;
unsigned char* buffer;
try {buffer = new unsigned char [len];}
catch (...) {return -1;}
wxArrayString array;
Game.GetTextures( array);
unsigned int result = dat.Read( buffer, len);
dat.Close();
wxString cpy = array[id];
array[id] = array[id-1];
array[id-1] = cpy;
if (result != len) return -1;
Game.SetTextures( array);
if (tpf)
{
/*
*
* BIG THANKS TO Tonttu
* (TPFcreate 1.5)
*
*/
unsigned int TPF_XOR = 0x3FA43FA4u;
const char pw[] = {0x73, 0x2A, 0x63, 0x7D, 0x5F, 0x0A, 0xA6, 0xBD,
0x7D, 0x65, 0x7E, 0x67, 0x61, 0x2A, 0x7F, 0x7F,
0x74, 0x61, 0x67, 0x5B, 0x60, 0x70, 0x45, 0x74,
0x5C, 0x22, 0x74, 0x5D, 0x6E, 0x6A, 0x73, 0x41,
0x77, 0x6E, 0x46, 0x47, 0x77, 0x49, 0x0C, 0x4B,
0x46, 0x6F, '\0'};
CheckBoxes[id]->SetLabel(array[id]);
CheckBoxes[id-1]->SetLabel(array[id-1]);
unsigned int j=0;
while ( j <= result - 4 )
{
*( unsigned int* )( &buffer[j] ) ^= TPF_XOR;
j += 4;
}
while ( j < result )
{
buffer[j] ^= (unsigned char )( TPF_XOR >> 24 );
TPF_XOR <<= 4;
j++;
}
if (add) AddContent( (char*) buffer, len, pw, tex, add, force);
else RemoveContent( (char*) buffer, len, pw, tex, add, force);
}
else
{
if (add) AddContent( (char*) buffer, len, NULL, tex, add, force);
else RemoveContent( (char*) buffer, len, NULL, tex, add, force);
}
delete [] buffer;
return 0;
bool cpy_checked = CheckBoxes[id]->GetValue();
CheckBoxes[id]->SetValue(CheckBoxes[id-1]);
CheckBoxes[id-1]->SetValue(cpy_checked);
}
int OTM_GamePage::AddContent( char* buffer, unsigned int len, const char* pw, AddTextureClass *tex, bool add, bool force)
void OTM_GamePage::OnButtonDown(wxCommandEvent& event)
{
HZIP hz = OpenZip( (void*) buffer, len, pw);
int id = (event.GetId() - ID_Button_Texture-1)/3;
if (id <0 || id>= NumberOfEntry-1) return;
ZIPENTRY ze;
int index;
FindZipItem( hz, L"texmod.def", false, &index, &ze);
if (index>=0) //if texmod.def is present in the zip file
{
char* def;
int len = ze.unc_size;
try {def=new char[len+1];}
catch(...) {CloseZip(hz); return -1;}
ZRESULT zr = UnzipItem( hz,index, def, len);
wxArrayString array;
Game.GetTextures( array);
if (zr!=ZR_OK && zr!=ZR_MORE) {delete [] def; CloseZip(hz); return -1;}
def[len]=0;
wxString cpy = array[id];
array[id] = array[id+1];
array[id+1] = cpy;
int count = 0;
for (int i=0; i<len; i++) if (def[i]=='\n') count++;
if (def[len-1]!='\n') count++;
Game.SetTextures( array);
tex->SetSize(count+1);
CheckBoxes[id]->SetLabel(array[id]);
CheckBoxes[id+1]->SetLabel(array[id+1]);
unsigned long temp_hash;
int pos = 0;
count = 0;
wxString def_file;
def_file = def;
wxString conv;
while (1)
{
if (def_file.Len()<11) break;
conv = def_file.BeforeFirst( '|');
if (!conv.ToULong( &temp_hash, 16))
{
def_file = def_file.AfterFirst( '\n');
continue;
}
def_file = def_file.AfterFirst( '|');
conv = def_file.BeforeFirst( '\n');
conv.Replace( "\r", "");
FindZipItem( hz, conv.wc_str(), false, &index, &ze); // look for texture
if (index>=0)
{
try {tex->Textures[count] = new char[ze.unc_size];}
catch(...)
{
tex->Textures[count] = NULL;
def_file = def_file.AfterFirst( '\n');
continue;
}
if (ZR_OK!=UnzipItem( hz, index, tex->Textures[count], ze.unc_size))
{
delete [] tex->Textures[count];
tex->Textures[count] = NULL;
}
else
{
tex->Hash[count] = temp_hash;
tex->Add[count] = true;
tex->Size[count] = ze.unc_size;
tex->Force[count] = force;
count++;
}
}
def_file = def_file.AfterFirst( '\n');
}
tex->Num = count;
}
else // texmod.def is not present in the zip file
{
wxString name;
wxString file;
GetZipItem( hz, -1, &ze); //ask for number of entries
index = ze.index;
tex->SetSize(index);
int count = 0;
unsigned long temp_hash;
for (int i=0; i<index; i++)
{
if (GetZipItem( hz, i, &ze)!=ZR_OK) continue; //ask for name and size
file = ze.name;
name = file.AfterLast( '.');
if (name!="dds") continue; //if this is not texture file, continue
name = file.AfterLast( '_');
name = name.BeforeLast( '.');
if (!name.ToULong( &temp_hash, 16)) continue; //if hash couldt not be extracted
try {tex->Textures[count] = new char[ze.unc_size];}
catch(...)
{
tex->Textures[count] = NULL;
continue;
}
ZRESULT rz = UnzipItem( hz, i, tex->Textures[count], ze.unc_size);
if (ZR_OK!=rz)
{
delete [] tex->Textures[count];
tex->Textures[count] = NULL;
}
else
{
tex->Hash[count] = temp_hash;
tex->Add[count] = true;
tex->Size[count] = ze.unc_size;
tex->Force[count] = force;
count++;
}
}
tex->Num = count;
}
CloseZip(hz);
return 0;
bool cpy_checked = CheckBoxes[id]->GetValue();
CheckBoxes[id]->SetValue(CheckBoxes[id+1]);
CheckBoxes[id+1]->SetValue(cpy_checked);
}
int OTM_GamePage::RemoveContent( char* buffer, unsigned int len, const char* pw, AddTextureClass *tex, bool add, bool force)
void OTM_GamePage::OnButtonDelete(wxCommandEvent& event)
{
HZIP hz = OpenZip( (void*) buffer, len, pw);
int id = (event.GetId() - ID_Button_Texture-2)/3;
if (id <0 || id>= NumberOfEntry) return;
ZIPENTRY ze;
int index;
FindZipItem( hz, L"texmod.def", true, &index, &ze);
wxArrayString array;
Game.GetTextures( array);
if (index>=0)
{
char* def;
int len = ze.unc_size;
try {def=new char[len+1];}
catch(...) {return -1;}
for (int i=id+1; i<NumberOfEntry; i++) CheckBoxes[i-1]->SetLabel(array[i]);
if (ZR_OK!=UnzipItem( hz,index, def, len)) {delete [] def; return -1;}
def[len]=0;
int count = 0;
for (int i=0; i<len; i++) if (def[i]=='\n') count++;
if (def[len-1]!='\n') count++;
tex->SetSize(count);
array.RemoveAt(id, 1);
Game.SetTextures( array);
NumberOfEntry--;
unsigned long temp_hash;
int pos = 0;
count = 0;
wxString def_file;
def_file = def;
wxString conv;
Unbind( wxEVT_COMMAND_BUTTON_CLICKED, &OTM_GamePage::OnButtonUp, this, 3*id);
Unbind( wxEVT_COMMAND_BUTTON_CLICKED, &OTM_GamePage::OnButtonDown, this, 3*id+1);
Unbind( wxEVT_COMMAND_BUTTON_CLICKED, &OTM_GamePage::OnButtonDelete, this, 3*id+2);
while (1)
{
if (def_file.Len()<11) break;
conv = def_file.BeforeFirst( '|');
if (!conv.ToULong( &temp_hash, 16))
{
def_file = def_file.AfterFirst( '\n');
continue;
}
CheckBoxVSizer->Detach( CheckBoxHSizers[NumberOfEntry]);
tex->Hash[count] = temp_hash;
tex->Add[count] = false;
tex->Size[count] = 0;
tex->Force[count] = force;
count++;
CheckBoxHSizers[NumberOfEntry]->Detach( (wxWindow*) CheckBoxes[NumberOfEntry]);
CheckBoxHSizers[NumberOfEntry]->Detach( (wxWindow*) CheckButtonUp[NumberOfEntry]);
CheckBoxHSizers[NumberOfEntry]->Detach( (wxWindow*) CheckButtonDown[NumberOfEntry]);
CheckBoxHSizers[NumberOfEntry]->Detach( (wxWindow*) CheckButtonDelete[NumberOfEntry]);
def_file = def_file.AfterFirst( '\n');
}
tex->Num = count;
}
else
{
wxString name;
wxString file;
GetZipItem( hz, -1, &ze);
index = ze.index;
tex->SetSize(index);
int count = 0;
unsigned long temp_hash;
for (int i=0; i<index; i++)
{
if (GetZipItem( hz, i, &ze)!=ZR_OK) continue;
file = ze.name;
name = file.AfterLast( '.');
if (name!="dds") continue;
name = file.AfterLast( '_');
name = name.BeforeLast( '.');
if (!name.ToULong( &temp_hash, 16)) continue;
tex->Hash[count] = temp_hash;
tex->Add[count] = false;
tex->Size[count] = 0;
tex->Force[count] = force;
count++;
}
tex->Num = count;
}
CloseZip(hz);
return 0;
delete CheckBoxHSizers[NumberOfEntry];
CheckBoxHSizers[NumberOfEntry] = NULL;
delete CheckBoxes[NumberOfEntry];
CheckBoxes[NumberOfEntry] = NULL;
delete CheckButtonUp[NumberOfEntry];
CheckButtonUp[NumberOfEntry] = NULL;
delete CheckButtonDown[NumberOfEntry];
CheckButtonDown[NumberOfEntry] = NULL;
delete CheckButtonDelete[NumberOfEntry];
CheckButtonDelete[NumberOfEntry] = NULL;
}
+37 -12
View File
@@ -22,43 +22,68 @@ along with FooOpenTexMod. If not, see <http://www.gnu.org/licenses/>.
#define OTM_GAMEPAGE_H_
#include "OTM_Main.h"
#include "unzip.h"
// this page is opened if a game is started.
class OTM_GamePage : public wxPanel
{
public:
OTM_GamePage( wxNotebook *parent, OTM_GameInfo *game, PipeStruct &pipe, OTM_Language &lang);
OTM_GamePage( wxNotebook *parent, const wxString &name, PipeStruct &pipe, OTM_Language &lang);
virtual ~OTM_GamePage(void);
void AddTexture( const wxString &file_name);
void SetPath( const wxString &file_name);
int UpdateGame(void);
int SaveToFile() {return SaveToFile(Game.Name);}
int SaveToFile( const wxString &file_name);
//int LoadFromFile( const wxString &file_name) {return Game->LoadFromFile( file_name);}
int SetOpenPath(const wxString &path) {return Game.SetOpenPath(path);}
wxString GetOpenPath(void) {return Game.GetOpenPath();}
int SetSavePath(const wxString &path);
wxString GetSavePath(void) {return Game.GetSavePath();}
void OnButtonUp(wxCommandEvent& WXUNUSED(event));
void OnButtonDown(wxCommandEvent& WXUNUSED(event));
void OnButtonDelete(wxCommandEvent& WXUNUSED(event));
private:
int AddFile( AddTextureClass *tex, wxString file, bool add, bool force);
int AddZip( AddTextureClass *tex, wxString file, bool add, bool force, bool tpf);
int AddContent( char* buffer, unsigned int len, const char* pw, AddTextureClass *tex, bool add, bool force);
int RemoveContent( char* buffer, unsigned int len, const char* pw, AddTextureClass *tex, bool add, bool force);
wxBoxSizer *SizerKeys[2];
wxTextCtrl *TextKeyBack;
wxTextCtrl *TextKeySave;
wxTextCtrl *TextKeyNext;
wxChoice *ChoiceKeyBack;
wxChoice *ChoiceKeySave;
wxChoice *ChoiceKeyNext;
wxBoxSizer *MainSizer;
wxCheckBox *SaveAllTextures;
wxCheckBox *SaveSingleTexture;
wxTextCtrl *SavePath;
wxBoxSizer **CheckBoxHSizers;
wxBoxSizer *CheckBoxVSizer;
wxButton **CheckButtonUp;
wxButton **CheckButtonDown;
wxButton **CheckButtonDelete;
wxCheckBox **CheckBoxes;
int NumberOfEntry;
int MaxNumberOfEntry;
OTM_Language &Language;
OTM_GameInfo *Game;
OTM_GameInfo Game;
OTM_GameInfo GameOld;
OTM_Sender Sender;
//DECLARE_EVENT_TABLE();
};
#endif /* OTM_GAMEPAGE_H_ */
+137 -7
View File
@@ -30,30 +30,46 @@ int OTM_Language::LoadLanguage(int lang)
{
if (lang==0) //English
{
MenuPref = L"Preferences";
MenuQuit = L"Quit";
//MenuPref = L"Preferences";
//MenuQuit = L"Quit";
MenuHelp = L"Help";
MenuAbout = L"About";
MenuAddGame = L"Add game";
MenuDeleteGame = L"Delete Game";
MainMenuStart = L"Start";
//MainMenuStart = L"Start";
MainMenuGame = L"Game";
MainMenuHelp = L"Help";
ButtonOpen = L"Open texture";
ButtonDirectory = L"Set save directory";
ButtonUpdate = L"Update";
ButtonSave = L"Save as default";
ChooseFile = L"Choose a texture file";
ChooseDir = L"Choose a directory";
CheckBoxSaveSingleTexture = L"Save single texture";
CheckBoxSaveAllTextures = L"Save all textures";
TextCtrlSavePath = L"Save path: ";
DeleteGame = L"Select the games to be deleted.";
GameAlreadyAdded = L"Game has been already added.";
FileNotSupported = L"This file type is not supported:\n";
ExitGameAnyway = L"Closing OpenTexMod while a game is running might lead to a crash of the game.\nExit anyway?";
}
LoadKeys(lang);
return 0;
}
#define QUOTES(x) #x
#define AddKey( name, key ) \
{ \
KeyStrings.Add( name ); \
KeyValues.Add( key ); \
}
int OTM_Language::LoadKeys(int lang)
{
@@ -64,9 +80,8 @@ int OTM_Language::LoadKeys(int lang)
KeyNext = L"Next";
}
Keys.Empty();
Keys.Add(L"Default");
return 0;
KeyStrings.Empty();
KeyValues.Empty();
/*
#define VK_LBUTTON 0x01
@@ -82,7 +97,21 @@ int OTM_Language::LoadKeys(int lang)
// * 0x07 : unassigned
*/
AddKey( "VK_BACK", VK_BACK );
AddKey( "VK_TAB", VK_TAB );
AddKey( "VK_CLEAR", VK_CLEAR );
AddKey( "VK_RETURN", VK_RETURN );
AddKey( "VK_SHIFT", VK_SHIFT );
AddKey( "VK_CONTROL", VK_CONTROL );
AddKey( "VK_MENU", VK_MENU );
AddKey( "VK_PAUSE", VK_PAUSE );
AddKey( "VK_CAPITAL", VK_CAPITAL );
//AddKey( );
//AddKey( );
//AddKey( );
//AddKey( );
/*
#define VK_BACK 0x08
#define VK_TAB 0x09
@@ -107,13 +136,35 @@ int OTM_Language::LoadKeys(int lang)
#define VK_HANJA 0x19
#define VK_KANJI 0x19
*/
AddKey( "VK_ESCAPE", VK_ESCAPE );
/*
#define VK_ESCAPE 0x1B
#define VK_CONVERT 0x1C
#define VK_NONCONVERT 0x1D
#define VK_ACCEPT 0x1E
#define VK_MODECHANGE 0x1F
*/
AddKey( "VK_SPACE", VK_SPACE );
AddKey( "VK_PRIOR", VK_PRIOR );
AddKey( "VK_NEXT", VK_NEXT );
AddKey( "VK_END", VK_END );
AddKey( "VK_HOME", VK_HOME );
AddKey( "VK_LEFT", VK_LEFT );
AddKey( "VK_UP", VK_UP );
AddKey( "VK_RIGHT", VK_RIGHT );
AddKey( "VK_DOWN", VK_DOWN );
AddKey( "VK_SELECT", VK_SELECT );
AddKey( "VK_PRINT", VK_PRINT );
AddKey( "VK_EXECUTE", VK_EXECUTE );
AddKey( "VK_SNAPSHOT", VK_SNAPSHOT );
AddKey( "VK_INSERT", VK_INSERT );
AddKey( "VK_DELETE", VK_DELETE );
AddKey( "VK_HELP", VK_HELP );
/*
#define VK_SPACE 0x20
#define VK_PRIOR 0x21
#define VK_NEXT 0x22
@@ -135,7 +186,48 @@ int OTM_Language::LoadKeys(int lang)
// * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
// * 0x40 : unassigned
// * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
*/
int count = 0x30;
AddKey( "0", count++);
AddKey( "1", count++);
AddKey( "2", count++);
AddKey( "3", count++);
AddKey( "4", count++);
AddKey( "5", count++);
AddKey( "6", count++);
AddKey( "7", count++);
AddKey( "8", count++);
AddKey( "9", count++);
count = 0x41;
AddKey( "a", count++);
AddKey( "b", count++);
AddKey( "c", count++);
AddKey( "d", count++);
AddKey( "e", count++);
AddKey( "f", count++);
AddKey( "g", count++);
AddKey( "h", count++);
AddKey( "i", count++);
AddKey( "j", count++);
AddKey( "k", count++);
AddKey( "l", count++);
AddKey( "m", count++);
AddKey( "n", count++);
AddKey( "o", count++);
AddKey( "p", count++);
AddKey( "q", count++);
AddKey( "r", count++);
AddKey( "s", count++);
AddKey( "t", count++);
AddKey( "u", count++);
AddKey( "v", count++);
AddKey( "w", count++);
AddKey( "x", count++);
AddKey( "y", count++);
AddKey( "z", count++);
/*
#define VK_LWIN 0x5B
#define VK_RWIN 0x5C
@@ -143,8 +235,41 @@ int OTM_Language::LoadKeys(int lang)
// 0x5E : reserved
*/
AddKey( "VK_SLEEP", VK_SLEEP );
AddKey( "VK_NUMPAD0", VK_NUMPAD0 );
AddKey( "VK_NUMPAD1", VK_NUMPAD1 );
AddKey( "VK_NUMPAD2", VK_NUMPAD2 );
AddKey( "VK_NUMPAD3", VK_NUMPAD3 );
AddKey( "VK_NUMPAD4", VK_NUMPAD4 );
AddKey( "VK_NUMPAD5", VK_NUMPAD5 );
AddKey( "VK_NUMPAD6", VK_NUMPAD6 );
AddKey( "VK_NUMPAD7", VK_NUMPAD7 );
AddKey( "VK_NUMPAD8", VK_NUMPAD8 );
AddKey( "VK_NUMPAD9", VK_NUMPAD9 );
AddKey( "VK_MULTIPLY", VK_MULTIPLY );
AddKey( "VK_ADD", VK_ADD );
AddKey( "VK_SEPARATOR", VK_SEPARATOR );
AddKey( "VK_SUBTRACT", VK_SUBTRACT );
AddKey( "VK_DECIMAL", VK_DECIMAL );
AddKey( "VK_DIVIDE", VK_DIVIDE );
AddKey( "VK_F1", VK_F1 );
AddKey( "VK_F2", VK_F2 );
AddKey( "VK_F3", VK_F3 );
AddKey( "VK_F4", VK_F4 );
AddKey( "VK_F5", VK_F5 );
AddKey( "VK_F6", VK_F6 );
AddKey( "VK_F7", VK_F7 );
AddKey( "VK_F8", VK_F8 );
AddKey( "VK_F9", VK_F9 );
AddKey( "VK_F10", VK_F10 );
AddKey( "VK_F12", VK_F12 );
AddKey( "VK_F12", VK_F12 );
/*
#define VK_SLEEP 0x5F
#define VK_NUMPAD0 0x60
@@ -190,7 +315,11 @@ int OTM_Language::LoadKeys(int lang)
// 0x88 - 0x8F : unassigned
*/
AddKey( "VK_NUMLOCK", VK_NUMLOCK );
AddKey( "VK_SCROLL", VK_SCROLL );
/*
#define VK_NUMLOCK 0x90
#define VK_SCROLL 0x91
@@ -328,5 +457,6 @@ int OTM_Language::LoadKeys(int lang)
*/
return 0;
}
+13 -4
View File
@@ -33,28 +33,37 @@ public:
wxString MenuQuit;
wxString MenuHelp;
wxString MenuAbout;
wxString MenuAddGame;
wxString MenuDeleteGame;
wxString MainMenuStart;
wxString MainMenuGame;
wxString MainMenuHelp;
wxString ButtonOpen;
wxString ButtonDirectory;
wxString ButtonUpdate;
wxString ButtonSave;
wxString ChooseFile;
wxString ChooseDir;
wxString CheckBoxSaveSingleTexture;
wxString CheckBoxSaveAllTextures;
wxString TextCtrlSavePath;
wxString DeleteGame;
wxString GameAlreadyAdded;
wxString FileNotSupported;
wxString ExitGameAnyway;
wxString KeyBack;
wxString KeySave;
wxString KeyNext;
wxArrayString Keys;
wxString FileNotSupported;
wxArrayString KeyStrings;
wxArrayInt KeyValues;
private:
int LoadKeys(int lang);
+13 -2
View File
@@ -38,12 +38,16 @@ along with FooOpenTexMod. If not, see <http://www.gnu.org/licenses/>.
#define wxUSE_DIRDLG 1
#define wxUSE_CHOICE 1
#define wxUSE_FILE 1
#define wxUSE_TEXTCTRL 1
#define wxUSE_CHOICEDLG 1
#endif
#include "wx\wx.h"
#include "wx\notebook.h"
#include <wx/file.h>
#include <wx/dir.h>
#include <wx/tokenzr.h>
//#include <wx/thread.h>
//#include "wx/checkbox.h"
//#include <wx/msgdlg.h>
@@ -51,6 +55,8 @@ along with FooOpenTexMod. If not, see <http://www.gnu.org/licenses/>.
//#include <wx/button.h>
//#include <wx/filedlg.h>
//#include <wx/choice.h>
//#include <wx/textctrl.h>
//#include <wx/choicdlg.h>
#include <windows.h>
@@ -60,17 +66,22 @@ along with FooOpenTexMod. If not, see <http://www.gnu.org/licenses/>.
class OTM_Frame;
#define MAX_TEXTURES 1024
enum
{
ID_Button_Open = wxID_HIGHEST,
ID_Button_Path,
ID_Button_Update,
ID_Button_Save,
ID_Menu_Pref,
ID_Menu_Quit,
ID_Menu_Help,
ID_Menu_About,
ID_Menu_AddGame,
ID_Menu_DeleteGame,
ID_Add_Game,
ID_Delete_Game
ID_Delete_Game,
ID_Button_Texture, //this entry must be the last!!
};
#define ABORT_SERVER L"OTM_Abort_Server"
@@ -78,9 +89,9 @@ enum
#include "OTM_Language.h"
#include "OTM_Event.h"
#include "OTM_Sender.h"
#include "OTM_Client.h"
#include "OTM_GameInfo.h"
#include "OTM_Sender.h"
#include "OTM_Server.h"
#include "OTM_GamePage.h"
#include "OTM_GUI.h"
+337 -23
View File
@@ -20,6 +20,7 @@ along with FooOpenTexMod. If not, see <http://www.gnu.org/licenses/>.
#include "OTM_Main.h"
#include "unzip.h"
AddTextureClass::AddTextureClass(void)
{
@@ -59,7 +60,16 @@ AddTextureClass::~AddTextureClass(void)
}
}
OTM_Sender::OTM_Sender(PipeStruct &pipe) : Pipe(pipe)
OTM_Sender::OTM_Sender(PipeStruct &pipe, OTM_Language &lang) : Pipe(pipe), Language(lang)
{
try {Buffer = new char[BIG_BUFSIZE];}
catch (...) {Buffer=NULL;}
@@ -70,6 +80,80 @@ OTM_Sender::~OTM_Sender(void)
if (Buffer!=NULL) delete [] Buffer;
}
int OTM_Sender::Send( const OTM_GameInfo &game, const OTM_GameInfo &game_old)
{
int key = game.GetKeyBack();
if (key>=0 && key!=game_old.GetKeyBack())
{
key = Language.KeyValues[key];
SendKey( key, CONTROL_KEY_BACK);
}
key = game.GetKeySave();
if (key>=0 && key!=game_old.GetKeySave())
{
key = Language.KeyValues[key];
SendKey( key, CONTROL_KEY_SAVE);
}
key = game.GetKeyNext();
if (key>=0 && key!=game_old.GetKeyNext())
{
key = Language.KeyValues[key];
SendKey( key, CONTROL_KEY_NEXT);
}
if ( game.GetSaveSingleTexture() != game_old.GetSaveSingleTexture() ) SendSaveSingleTexture( game.GetSaveSingleTexture());
if ( game.GetSaveAllTextures() != game_old.GetSaveAllTextures() ) SendSaveAllTextures(game.GetSaveAllTextures());
wxString path;
path = game.GetSavePath();
if (path!=game_old.GetSavePath()) SendPath(path);
// the rest of this function is not optimized !!
if (game.GetNumberOfTextures()<=0) return 0;
wxArrayString textures;
game.GetTextures( textures);
int num = textures.GetCount();
bool *checked = new bool [num];
game.GetChecked( checked, num);
AddTextureClass *tex = new AddTextureClass[num];
wxString file_type;
unsigned long temp_hash;
for (int i=0; i<num; i++)
{
file_type = textures[i];
file_type = file_type.AfterLast( '.');
if (file_type == L"zip")
{
AddZip( &tex[i], textures[i], checked[i], true, false);
}
else if (file_type == L"tpf")
{
AddZip( &tex[i], textures[i], checked[i], true, true);
}
else if (file_type == L"dds")
{
AddFile( &tex[i], textures[i], checked[i], true);
}
else
{
wxString msg = Language.FileNotSupported;
msg << textures[i];
wxMessageBox(msg, "ERROR", wxOK);
}
}
return SendTextures( num, tex);
}
int OTM_Sender::SendSaveAllTextures(bool val)
{
MsgStruct msg;
@@ -98,18 +182,30 @@ int OTM_Sender::SendTextures(unsigned int num, AddTextureClass *tex)
{
if (Buffer==NULL) return (RETURN_NO_MEMORY);
int count = 0;
for (unsigned int i=0u; i<num; i++) count+=tex->Num;
unsigned long *hash = new unsigned long[count];
count = 0;
//wxMessageBox("OTM_Sender::SendTextures", "start", wxOK);
MsgStruct *msg;
int pos = 0;
for (unsigned int i=0u; i<num; i++) for (unsigned int j=0u; j<tex[i].Num; j++)
{
bool hit = false;
unsigned long temp_hash = tex[i].Hash[j];
for (int h=0; h<count; h++) if (temp_hash == hash[h]) {hit= true; break;}
if (hit) continue;
if (tex[i].Size[j]+sizeof(MsgStruct)+pos>BIG_BUFSIZE)
{
if (int ret = SendToGame( Buffer, pos)) return ret;
pos = 0;
}
hash[count++] = temp_hash;
msg = (MsgStruct*) &Buffer[pos];
msg->Hash = tex[i].Hash[j];
msg->Hash = temp_hash;
msg->Value = tex[i].Size[j];
pos += sizeof(MsgStruct);
@@ -124,41 +220,23 @@ int OTM_Sender::SendTextures(unsigned int num, AddTextureClass *tex)
}
else msg->Control = CONTROL_REMOVE_TEXTURE;
}
delete [] hash;
if (pos) if (int ret = SendToGame( Buffer, pos)) return ret;
return 0;
}
int OTM_Sender::SendKeyBack(int key)
int OTM_Sender::SendKey(int key, int ctr)
{
MsgStruct msg;
msg.Control = CONTROL_KEY_BACK;
msg.Control = ctr;
msg.Value = key;
msg.Hash = 0u;
return SendToGame( (void*) &msg, sizeof(MsgStruct));
}
int OTM_Sender::SendKeySave(int key)
{
MsgStruct msg;
msg.Control = CONTROL_KEY_SAVE;
msg.Value = key;
msg.Hash = 0u;
return SendToGame( (void*) &msg, sizeof(MsgStruct));
}
int OTM_Sender::SendKeyNext(int key)
{
MsgStruct msg;
msg.Control = CONTROL_KEY_NEXT;
msg.Value = key;
msg.Hash = 0u;
return SendToGame( (void*) &msg, sizeof(MsgStruct));
}
@@ -191,3 +269,239 @@ int OTM_Sender::SendToGame( void *msg, unsigned long len)
if (!FlushFileBuffers(Pipe.Out)) return -1;
return 0;
}
int OTM_Sender::AddFile( AddTextureClass *tex, wxString file, bool add, bool force)
{
tex->SetSize(1);
unsigned long temp_hash;
wxString name = file.AfterLast( '_');
name = name.BeforeLast( '.');
if (!name.ToULong( &temp_hash, 16)) return -1; // return if hash could not be extracted
tex->Add[0] = add;
if (add)
{
wxFile dat;
if (!dat.Access(name, wxFile::read)) return -1;
dat.Open(file, wxFile::read);
if (!dat.IsOpened()) {return -1;}
unsigned len = file.Length();
try {tex->Textures[0] = new char [len];}
catch (...) {tex->Textures[0] = NULL; return -1;}
unsigned int result = dat.Read( (void*) tex->Textures[0], len);
dat.Close();
if (result != len) return -1;
tex->Size[0] = len;
}
else {tex->Size[0] = 0; tex->Textures[0] = NULL;}
tex->Num = 1;
tex->Force[0] = true;
tex->Hash[0] = temp_hash;
return 0;
}
int OTM_Sender::AddZip( AddTextureClass *tex, wxString file, bool add, bool force, bool tpf)
{
wxFile dat;
if (!dat.Access(file, wxFile::read)) return -1;
dat.Open(file, wxFile::read);
if (!dat.IsOpened()) {return -1;}
unsigned len = dat.Length();
unsigned char* buffer;
try {buffer = new unsigned char [len];}
catch (...) {return -1;}
unsigned int result = dat.Read( buffer, len);
dat.Close();
if (result != len) return -1;
if (tpf)
{
/*
*
* BIG THANKS TO Tonttu
* (TPFcreate 1.5)
*
*/
unsigned int TPF_XOR = 0x3FA43FA4u;
const char pw[] = {0x73, 0x2A, 0x63, 0x7D, 0x5F, 0x0A, 0xA6, 0xBD,
0x7D, 0x65, 0x7E, 0x67, 0x61, 0x2A, 0x7F, 0x7F,
0x74, 0x61, 0x67, 0x5B, 0x60, 0x70, 0x45, 0x74,
0x5C, 0x22, 0x74, 0x5D, 0x6E, 0x6A, 0x73, 0x41,
0x77, 0x6E, 0x46, 0x47, 0x77, 0x49, 0x0C, 0x4B,
0x46, 0x6F, '\0'};
unsigned int j=0;
while ( j <= result - 4 )
{
*( unsigned int* )( &buffer[j] ) ^= TPF_XOR;
j += 4;
}
while ( j < result )
{
buffer[j] ^= (unsigned char )( TPF_XOR >> 24 );
TPF_XOR <<= 4;
j++;
}
AddContent( (char*) buffer, len, pw, tex, add, force);
}
else
{
AddContent( (char*) buffer, len, NULL, tex, add, force);
}
delete [] buffer;
return 0;
}
int OTM_Sender::AddContent( char* buffer, unsigned int len, const char* pw, AddTextureClass *tex, bool add, bool force)
{
HZIP hz = OpenZip( (void*) buffer, len, pw);
ZIPENTRY ze;
int index;
FindZipItem( hz, L"texmod.def", false, &index, &ze);
if (index>=0) //if texmod.def is present in the zip file
{
char* def;
int len = ze.unc_size;
try {def=new char[len+1];}
catch(...) {CloseZip(hz); return -1;}
ZRESULT zr = UnzipItem( hz,index, def, len);
if (zr!=ZR_OK && zr!=ZR_MORE) {delete [] def; CloseZip(hz); return -1;}
def[len]=0;
wxStringTokenizer token( def, "\n");
int num = token.CountTokens();
tex->SetSize(num);
unsigned long temp_hash;
int pos = 0;
int count = 0;
wxString entry;
wxString conv;
for (int i=0; i<num; i++)
{
entry = token.GetNextToken();
conv = entry.BeforeFirst( '|');
if (!conv.ToULong( &temp_hash, 16)) continue;
conv = entry.AfterFirst( '|');
conv.Replace( "\r", "");
if (add)
{
FindZipItem( hz, conv.wc_str(), false, &index, &ze); // look for texture
if (index>=0)
{
try {tex->Textures[count] = new char[ze.unc_size];}
catch(...)
{
tex->Textures[count] = NULL;
continue;
}
if (ZR_OK!=UnzipItem( hz, index, tex->Textures[count], ze.unc_size))
{
delete [] tex->Textures[count];
tex->Textures[count] = NULL;
}
else
{
tex->Hash[count] = temp_hash;
tex->Add[count] = true;
tex->Size[count] = ze.unc_size;
tex->Force[count] = force;
count++;
}
}
}
else
{
tex->Hash[count] = temp_hash;
tex->Add[count] = false;
tex->Size[count] = 0;
tex->Force[count] = force;
count++;
}
}
tex->Num = count;
}
else // texmod.def is not present in the zip file
{
wxString name;
wxString file;
GetZipItem( hz, -1, &ze); //ask for number of entries
index = ze.index;
tex->SetSize(index);
int count = 0;
unsigned long temp_hash;
for (int i=0; i<index; i++)
{
if (GetZipItem( hz, i, &ze)!=ZR_OK) continue; //ask for name and size
file = ze.name;
name = file.AfterLast( '.');
if (name!="dds") continue; //if this is not texture file, continue
name = file.AfterLast( '_');
name = name.BeforeLast( '.');
if (!name.ToULong( &temp_hash, 16)) continue; //if hash couldt not be extracted
if (add)
{
try {tex->Textures[count] = new char[ze.unc_size];}
catch(...)
{
tex->Textures[count] = NULL;
continue;
}
ZRESULT rz = UnzipItem( hz, i, tex->Textures[count], ze.unc_size);
if (ZR_OK!=rz)
{
delete [] tex->Textures[count];
tex->Textures[count] = NULL;
}
else
{
tex->Hash[count] = temp_hash;
tex->Add[count] = true;
tex->Size[count] = ze.unc_size;
tex->Force[count] = force;
count++;
}
}
else
{
tex->Hash[count] = temp_hash;
tex->Add[count] = false;
tex->Size[count] = 0;
tex->Force[count] = force;
count++;
}
}
tex->Num = count;
}
CloseZip(hz);
return 0;
}
+10 -4
View File
@@ -44,17 +44,17 @@ public:
class OTM_Sender
{
public:
OTM_Sender(PipeStruct &pipe);
OTM_Sender(PipeStruct &pipe, OTM_Language &lang);
~OTM_Sender(void);
int Send( const OTM_GameInfo &game, const OTM_GameInfo &game_old);
int SendSaveAllTextures(bool val);
int SendSaveSingleTexture(bool val);
int SendTextures(unsigned int num, AddTextureClass *tex);
int SendKeyBack(int key);
int SendKeySave(int key);
int SendKeyNext(int key);
int SendKey(int key, int ctr);
int SendPath( const wxString &path);
@@ -62,7 +62,13 @@ private:
char *Buffer;
int SendToGame( void* msg, unsigned long len);
int AddFile( AddTextureClass *tex, wxString file, bool add, bool force);
int AddZip( AddTextureClass *tex, wxString file, bool add, bool force, bool tpf);
int AddContent( char* buffer, unsigned int len, const char* pw, AddTextureClass *tex, bool add, bool force);
PipeStruct &Pipe;
OTM_Language &Language;
};
+71
View File
@@ -0,0 +1,71 @@
WARNING: You use this program at your own risk!
1) If the program crash, you won't get probably any support from the game developer,
but you can report the bug under http://code.google.com/p/texmod/issues/list
2) Games can detected if they are modified, so you might risk a ban
of your online account!
3) This is an open-source project. The code can be retrieved, modified and compiled
by everyone. Download OpenTexMod only from sources you trust!
Download it by your self and don't use versions, send to you by team or guild members!
http://code.google.com/p/texmod/downloads/list
What can OpenTexMod alpha V0.1?
-extract and save single textures from a DX9 game (the target texture can be toggled in the game)
-extract and save all textures from a DX9 game
-load textures into a game to replace target textures
-support zip-files as whole mod package
-support the original TexMod *.tpf files
All these options can be switched on or off, while the game is already running!
So you can search for a texture in the game, save it to disk, edit it,
load it into the game, edit it again and load it into the game again, ...
and all without a restart of the game.
How does OpenTexMod interact with the game?
OpenTexMod intercept the connection between the game and DirectX.
It is required, that OpenTexMod is running before the game is started.
The GUI of OpenTexMod act as a server. A game which is successfully
intercepted with the OpenTexMod-dll will connect on program start to the server.
The GUI of OpenTexMod can handle multiple games at the same time. It will
also process each instance of a game as separate process (if the same game
was started more than once).
How to get OpenTexMod work?
There are two ways how OpenTexMod can intercept the DirectX connection:
1) (recommended) Add the games-binary through the menu Games->"Add game"
If you want to get it work with steam, don't add the steam.exe but rather the game.exe.
Once you have added the game, OpenTexMod will keep it in mind on further program start.
2) Copy the d3d9.dll (from the OpenTexMod directory) into the game directory.
Some games load a dll first from their own directory before they look up the system directory.
Only for these games this method will work.
WARNING: never copy this dll into your system directory!!
If you have chosen one of the two methods, you simply start OpenTexMod
and afterwards the game. There is no need to (and either you can't) start
the game through OpenTexMod.
If the game starts and all works fine, a new tab opens immediately in OpenTexMod.
In this tab you can now mod the game. Press the "update" button to commit
the changes to the game. You can also save your current settings. They will be loaded
and committed automatically when you start the same game the next time.
To load a mod, you must set the check mark of the file. If you wish to unload a mod,
just remove the check mark and click on update again. At the moment pressing the
X button of a file will remove it from the list but won't unload the mod from the game.
Due to the fact that different mods can modify the same target texture, only the
mod-texture of the first file in the list is taken into account. The action of this file
(load or unload) is proceeded regardless of what the following mods are opposed
to do with their mod-textures.
+4
View File
@@ -20,6 +20,10 @@ typedef struct
HANDLE Out;
} PipeStruct;
#define OTM_APP_DX9 L"OTM_DX9.txt"
#define OTM_APP_DIR L"OpenTexMod"
#define PIPE_OTM2Game L"\\\\.\\pipe\\OTM2Game"
#define PIPE_Game2OTM L"\\\\.\\pipe\\Game2OTM"