You are not logged in.
Привет, народ! Сколько лет тут не был, но как симэн взялся за санник, решил заглянуть снова .
К делу. Пытаюсь своими силами через c++ вывести текстуру на экран из определённого TXD файла.
За основу взял небезызвестный gta_dll, к процессу игры подключаюсь путём подмены vorbisFile. Всё стандартно, вобщем.
Чудеса начинаются, когда я пытаюсь загрузить текстуру и попытаться отрисовать её по нажатию кнопки.
В самом верху:
CTexture* achievementGetTexture;
Далее, три процедуры отвечающие за загрузку, освобождение и отрисовку текстуры:
void LoadTextures() { int slot = txdStore.AddTxdSlot("achiv"); txdStore.LoadTxd(slot, "MODELS\\ACHIEV.TXD"); txdStore.AddRef(slot); txdStore.PushCurrentTxd(); txdStore.SetCurrentTxd(slot); achievementGetTexture->Load("ac_box", NULL); txdStore.PopCurrentTxd(); debug("TEXTURE: %x", achievementGetTexture); debug("Textures loaded"); } void ReleaseTextures() { if ( achievementGetTexture ) { achievementGetTexture->Clean(); achievementGetTexture = NULL; } int achievementGetTextureSlotIndex = CTxdStore::FindTxdSlot("achiv"); txdStore.RemoveTxdSlot(achievementGetTextureSlotIndex); debug("Textures released"); } void Update_Hook() { // Draw texture on demand. while ( GetAsyncKeyState(0x09) ) achievementGetTexture->DrawTexturedRect(&RwRect2D(_width(0), _height(448), _width(280), _height(188)), &RwRGBA(255, 255, 255, 255)); }
Где-то в DllMain:
call(0x5BD765, &LoadTextures, PATCH_CALL); call(0x53BBCB, &ReleaseTextures, PATCH_CALL); call(0x53BFAE, &Update_Hook, PATCH_CALL);
Собственно, проблема: при нажатии 0x09 (Tab) игра вылетает. Вылетает из-за того, что почему-то текстура не грузится в мой achievementGetTexture. Вот лог:
20:27:17.680 CTXDSTORE::ADDTXDSLOT([achiv])
20:27:17.681 CTXDSTORE::LOADTXD([4], [MODELS\ACHIEV.TXD])
20:27:17.697 CTXDSTORE::ADDREF([4])
20:27:17.697 CTXDSTORE::PUSHCURRENTTXD
20:27:17.697 CTXDSTORE::SETCURRENTTXD([4])
20:27:17.697 CTEXTURE::LOAD([ac_box], [(null)])
20:27:17.697 CTXDSTORE::POPCURRENTTXD
20:27:17.697 TEXTURE: 0 <-- sic!
20:27:17.697 Textures loaded
20:27:25.692 CTXDSTORE::FINDTXDSLOT([achiv])
20:27:25.692 CTXDSTORE::REMOVETXDSLOT([4])
20:27:25.692 Textures released
20:27:26.092 Log closed
Теперь самое главное: CTexture.h/.cpp, CTxdStore.h.cpp и RW.h/.cpp с определениями текстур и TxdStore.
#define FUNC_CTexture__DrawTexturedRect 0x728350 #define FUNC_CTexture__Load 0x7272B0 #define FUNC_CTexture__Reload 0x727270 #define FUNC_CTexture__Clean 0x727240 class CTexture { private: RwTexture* texture; public: CTexture() : texture(NULL) { }; void DrawTexturedRect(RwRect2D* pos, RwRGBA* color); void Load(const char* name, const char* maskName); void Clean(); void Reload(const char* name); void Reload(const char* name, const char* maskName); RwTexture* GetTexture() { return texture; }; };
#include "StdAfx.h" void CTexture::DrawTexturedRect(RwRect2D* pos, RwRGBA* color) { debug("CTEXTURE::DRAWTEXTUREDRECT([%.3f %.3f %.3f %.3f], [%i %i %i %i])", pos->x1, pos->y1, pos->x2, pos->y2, color->r, color->g, color->b, color->a); DWORD dwFunc = FUNC_CTexture__DrawTexturedRect; RwTexture* tex = GetTexture(); _asm { push color push pos mov ecx, tex call dwFunc } } void CTexture::Load(const char* name, const char* maskName) { debug("CTEXTURE::LOAD([%s], [%s])", name, maskName); DWORD dwFunc = FUNC_CTexture__Load; _asm { push maskName push name mov ecx, this call dwFunc mov [this], eax add esp, 8 } } void CTexture::Clean() { debug("CTEXTURE::CLEAN()"); DWORD dwFunc = FUNC_CTexture__Clean; _asm { mov ecx, this call dwFunc } } void CTexture::Reload(const char* name) { debug("CTEXTURE::RELOAD([%s])", name); if ( name ) { if ( texture ) { RwTexture::Destroy(texture); texture = NULL; } texture = RwTexture::Read(name, NULL); } } void CTexture::Reload(const char* name, const char* maskName) { debug("CTEXTURE::RELOAD([%s], [%s])", name, maskName); if ( name && maskName ) { if ( texture ) { RwTexture::Destroy(texture); texture = NULL; } texture = RwTexture::Read(name, maskName); } }
#define FUNC_CTxdStore__PushCurrentTxd 0x7316A0 #define FUNC_CTxdStore__PopCurrentTxd 0x7316B0 #define FUNC_CTxdStore__FindTxdSlot 0x731850 #define FUNC_CTxdStore__SetCurrentTxd 0x7319C0 #define FUNC_CTxdStore__AddTxdRef 0x731A00 #define FUNC_CTxdStore__AddTxdSlot 0x731C80 #define FUNC_CTxdStore__RemoveTxdSlot 0x731CD0 #define FUNC_CTxdStore__LoadTxd 0x7320B0 class CTxdStore { public: static void PushCurrentTxd(); static void PopCurrentTxd(); static int FindTxdSlot(const char *name); static void SetCurrentTxd(int slot); static void AddRef(int index); static int AddTxdSlot(const char* slotName); static void RemoveTxdSlot(int slot); static void LoadTxd(int slot, const char* fp); }; static CTxdStore txdStore;
#include "stdafx.h" void CTxdStore::PushCurrentTxd() { debug("CTXDSTORE::PUSHCURRENTTXD"); DWORD dwFunc = FUNC_CTxdStore__PushCurrentTxd; _asm call dwFunc } void CTxdStore::PopCurrentTxd() { debug("CTXDSTORE::POPCURRENTTXD"); DWORD dwFunc = FUNC_CTxdStore__PopCurrentTxd; _asm call dwFunc } int CTxdStore::FindTxdSlot(const char *name) { debug("CTXDSTORE::FINDTXDSLOT([%s])", name); DWORD dwFunc = FUNC_CTxdStore__FindTxdSlot; int result = 0; _asm { push name call dwFunc mov result, eax add esp, 4 } } void CTxdStore::SetCurrentTxd(int slot) { debug("CTXDSTORE::SETCURRENTTXD([%i])", slot); DWORD dwFunc = FUNC_CTxdStore__SetCurrentTxd; _asm { push slot call dwFunc } } void CTxdStore::AddRef(int index) { debug("CTXDSTORE::ADDREF([%i])", index); DWORD dwFunc = FUNC_CTxdStore__AddTxdRef; _asm { push index call dwFunc } } int CTxdStore::AddTxdSlot(const char* slotName) { debug("CTXDSTORE::ADDTXDSLOT([%s])", slotName); DWORD dwFunc = FUNC_CTxdStore__AddTxdSlot; int result = 0; _asm { push slotName call dwFunc mov result, eax add esp, 4 } } void CTxdStore::RemoveTxdSlot(int slot) { debug("CTXDSTORE::REMOVETXDSLOT([%i])", slot); DWORD dwFunc = FUNC_CTxdStore__RemoveTxdSlot; _asm { push slot call dwFunc } } void CTxdStore::LoadTxd(int slot, const char* fp) { debug("CTXDSTORE::LOADTXD([%i], [%s])", slot, fp); DWORD dwFunc = FUNC_CTxdStore__LoadTxd; _asm { push fp push slot call dwFunc } }
... #define FUNC_RwTexture__Destroy 0x7F3820 #define FUNC_RwTexture__Read 0x7F3AC0 struct RwTexture { RwRaster *raster; RwTexDictionary *txd; RwListEntry TXDList; char name[RW_TEXTURE_NAME_LENGTH]; char mask[RW_TEXTURE_NAME_LENGTH]; unsigned int flags; int refs; static void Destroy(RwTexture* texture); static RwTexture* Read(const char* name, const char* maskName); RwRaster* GetRaster() { return this->raster; }; }; ...
... void RwTexture::Destroy(RwTexture* texture) { DWORD dwFunc = FUNC_RwTexture__Destroy; _asm { push texture call dwFunc add esp, 4 } } RwTexture* RwTexture::Read(const char* name, const char* maskName) { DWORD dwFunc = FUNC_RwTexture__Read; RwTexture* result; _asm { push maskName push name call dwFunc add esp, 8 mov result, eax } return result; } ...
Offline
Может стоит попробовать это:
http://ru-script.3dn.ru/publ/sozdanie_d … 18-1-0-206
http://ru-script.3dn.ru/forum/30-105-1
Просто предложение)
Вообще, жаль, что не так много времени нахожу на эту разработку. Но работа с текстурами - это святое, и было сделано в первую очередь.
Last edited by DK22Pac (20-11-2013 00:44)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
http://ru-script.3dn.ru/publ/sozdanie_d … 18-1-0-206
А у меня как-то по-другому это сделано? Где у меня ошибка подскажите.
Last edited by Sw[ee]t (20-11-2013 15:13)
Offline
ну это, например:
while ( GetAsyncKeyState(0x09) )
Так нельзя писать. Замени на
if ( GetAsyncKeyState(0x09) )
К предыдущему посту: я просто привел альтернативный вариант gta_dll. Это некая платформа для создания собственных плагинов для игры, которая позволяет абстрагироваться от хуков и замен вызовов дефолтных функций. Представь, что тебе понадобиться ещё в каком-то плагине делать те же хуки (инициализация, отрисовка, удаление), а потом ещё в каком-то. Будешь искать новые адреса для патчинга? Эта платформа позволяет не думать создателю плагина о таких проблемах.
Last edited by DK22Pac (20-11-2013 20:47)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Заменил. Вылет остался. В чём у меня проблема, кто-нибудь может ответить?
Место вылета:
Last edited by Sw[ee]t (21-11-2013 14:45)
Offline