From 0263d78fed3a307f8f6ca2bd26b6ef38b70f8187 Mon Sep 17 00:00:00 2001 From: "code@koerner-de.net" Date: Wed, 21 Sep 2011 20:39:10 +0000 Subject: [PATCH] BugFix: checked for NULL pointer when removing a Mod a lot of improvements and rearrangements in the GUI... --- .gitattributes | 1 + OTM_DX9/OTM_ArrayHandler.cpp | 2 + OTM_DX9/OTM_ArrayHandler.h | 2 +- OTM_DX9/OTM_DX9_dll.cpp | 5 +- OTM_DX9/OTM_IDirect3DDevice9.cpp | 77 ++-- OTM_DX9/OTM_IDirect3DDevice9.h | 12 +- OTM_DX9/OTM_TextureClient.cpp | 31 +- OTM_DX9/OTM_TextureClient.h | 12 +- OTM_DX9/OTM_TextureServer.cpp | 26 +- OTM_GUI/OTM_GUI.cpp | 193 ++++++++-- OTM_GUI/OTM_GUI.h | 16 +- OTM_GUI/OTM_GameInfo.cpp | 239 +++++++++++- OTM_GUI/OTM_GameInfo.h | 39 +- OTM_GUI/OTM_GamePage.cpp | 632 ++++++++++++------------------- OTM_GUI/OTM_GamePage.h | 49 ++- OTM_GUI/OTM_Language.cpp | 144 ++++++- OTM_GUI/OTM_Language.h | 17 +- OTM_GUI/OTM_Main.h | 15 +- OTM_GUI/OTM_Sender.cpp | 360 ++++++++++++++++-- OTM_GUI/OTM_Sender.h | 14 +- OTM_GUI/bin/README.txt | 71 ++++ OTM_GlobalDefines.h | 4 + 22 files changed, 1385 insertions(+), 576 deletions(-) create mode 100644 OTM_GUI/bin/README.txt diff --git a/.gitattributes b/.gitattributes index 60a9940..f794256 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/OTM_DX9/OTM_ArrayHandler.cpp b/OTM_DX9/OTM_ArrayHandler.cpp index 5e74963..73cfbe9 100644 --- a/OTM_DX9/OTM_ArrayHandler.cpp +++ b/OTM_DX9/OTM_ArrayHandler.cpp @@ -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); } +*/ diff --git a/OTM_DX9/OTM_ArrayHandler.h b/OTM_DX9/OTM_ArrayHandler.h index f685e07..7be2fa9 100644 --- a/OTM_DX9/OTM_ArrayHandler.h +++ b/OTM_DX9/OTM_ArrayHandler.h @@ -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]);} diff --git a/OTM_DX9/OTM_DX9_dll.cpp b/OTM_DX9/OTM_DX9_dll.cpp index 5a4b3f2..c8c4dd8 100644 --- a/OTM_DX9/OTM_DX9_dll.cpp +++ b/OTM_DX9/OTM_DX9_dll.cpp @@ -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]; diff --git a/OTM_DX9/OTM_IDirect3DDevice9.cpp b/OTM_DX9/OTM_IDirect3DDevice9.cpp index e787085..5ef0438 100644 --- a/OTM_DX9/OTM_IDirect3DDevice9.cpp +++ b/OTM_DX9/OTM_IDirect3DDevice9.cpp @@ -21,12 +21,14 @@ along with FooOpenTexMod. If not, see . #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()); } diff --git a/OTM_DX9/OTM_IDirect3DDevice9.h b/OTM_DX9/OTM_IDirect3DDevice9.h index c5077dd..9881965 100644 --- a/OTM_DX9/OTM_IDirect3DDevice9.h +++ b/OTM_DX9/OTM_IDirect3DDevice9.h @@ -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; diff --git a/OTM_DX9/OTM_TextureClient.cpp b/OTM_DX9/OTM_TextureClient.cpp index 461479c..aa38e9e 100644 --- a/OTM_DX9/OTM_TextureClient.cpp +++ b/OTM_DX9/OTM_TextureClient.cpp @@ -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; iRelease(); } else diff --git a/OTM_DX9/OTM_TextureClient.h b/OTM_DX9/OTM_TextureClient.h index 95ad421..eb62c53 100644 --- a/OTM_DX9/OTM_TextureClient.h +++ b/OTM_DX9/OTM_TextureClient.h @@ -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]; diff --git a/OTM_DX9/OTM_TextureServer.cpp b/OTM_DX9/OTM_TextureServer.cpp index 5288365..8d6e743 100644 --- a/OTM_DX9/OTM_TextureServer.cpp +++ b/OTM_DX9/OTM_TextureServer.cpp @@ -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; diff --git a/OTM_GUI/OTM_GUI.cpp b/OTM_GUI/OTM_GUI.cpp index ec7b3cb..df16473 100644 --- a/OTM_GUI/OTM_GUI.cpp +++ b/OTM_GUI/OTM_GUI.cpp @@ -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; iDeletePage(i); - //Games[i]->Wait(); Clients[i]->Delete(); delete Clients[i]; - delete Games[i]; NumberOfGames--; - for (int j=i; j0) { - 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. 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=LengthOfChecked) + { + bool *t_bool; + try {t_bool = new bool [LengthOfChecked+100];} + catch (...) {return -1;} + for (int i=0; iNumberOfChecked) + { + if (Checked!=NULL) delete [] Checked; + try {Checked = new bool [num+100];} + catch (...) {Checked=NULL; return -1;} + LengthOfChecked = num+100; + } + for (int i=0; i. */ - - - #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; iSetValue( 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; iSetValue( 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; iGetValue(), 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; iGetValue(); + 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; iGetValue(); + 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; iSetSize(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; iTextures[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; iSetLabel(array[i]); - if (ZR_OK!=UnzipItem( hz,index, def, len)) {delete [] def; return -1;} - def[len]=0; - - int count = 0; - for (int i=0; iSetSize(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; iHash[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; } diff --git a/OTM_GUI/OTM_GamePage.h b/OTM_GUI/OTM_GamePage.h index fbb0077..f8d7c08 100644 --- a/OTM_GUI/OTM_GamePage.h +++ b/OTM_GUI/OTM_GamePage.h @@ -22,43 +22,68 @@ along with FooOpenTexMod. If not, see . #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_ */ diff --git a/OTM_GUI/OTM_Language.cpp b/OTM_GUI/OTM_Language.cpp index 2870745..b705031 100644 --- a/OTM_GUI/OTM_Language.cpp +++ b/OTM_GUI/OTM_Language.cpp @@ -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; } diff --git a/OTM_GUI/OTM_Language.h b/OTM_GUI/OTM_Language.h index d84a31f..b2b1859 100644 --- a/OTM_GUI/OTM_Language.h +++ b/OTM_GUI/OTM_Language.h @@ -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); diff --git a/OTM_GUI/OTM_Main.h b/OTM_GUI/OTM_Main.h index 27afa73..7cfe89b 100644 --- a/OTM_GUI/OTM_Main.h +++ b/OTM_GUI/OTM_Main.h @@ -38,12 +38,16 @@ along with FooOpenTexMod. If not, see . #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 +#include +#include //#include //#include "wx/checkbox.h" //#include @@ -51,6 +55,8 @@ along with FooOpenTexMod. If not, see . //#include //#include //#include +//#include +//#include #include @@ -60,17 +66,22 @@ along with FooOpenTexMod. If not, see . 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" diff --git a/OTM_GUI/OTM_Sender.cpp b/OTM_GUI/OTM_Sender.cpp index 6d7a162..7440d70 100644 --- a/OTM_GUI/OTM_Sender.cpp +++ b/OTM_GUI/OTM_Sender.cpp @@ -20,6 +20,7 @@ along with FooOpenTexMod. If not, see . #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; iNum; + 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; iBIG_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=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; iTextures[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; +} diff --git a/OTM_GUI/OTM_Sender.h b/OTM_GUI/OTM_Sender.h index 99ff4e0..7e759e2 100644 --- a/OTM_GUI/OTM_Sender.h +++ b/OTM_GUI/OTM_Sender.h @@ -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; }; diff --git a/OTM_GUI/bin/README.txt b/OTM_GUI/bin/README.txt new file mode 100644 index 0000000..b6aed0f --- /dev/null +++ b/OTM_GUI/bin/README.txt @@ -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. diff --git a/OTM_GlobalDefines.h b/OTM_GlobalDefines.h index 69a7f56..b502cc5 100644 --- a/OTM_GlobalDefines.h +++ b/OTM_GlobalDefines.h @@ -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"