You are not logged in.
Вот код из IDA.
.text:004C3C80 ; int __cdecl createMarker(int type, float x, float y, float z, int flag1, int flag2) .text:004C3C80 _createMarker proc near ; CODE XREF: CScriptThread__opcodeHandler_03+A08p .text:004C3C80 ; CScriptThread__opcodeHandler_03+1566p .text:004C3C80 ; CScriptThread__opcodeHandler_03+1634p .text:004C3C80 ; CScriptThread__opcodeHandler_06+408p ... .text:004C3C80 .text:004C3C80 type = dword ptr 4 .text:004C3C80 x = dword ptr 8 .text:004C3C80 y = dword ptr 0Ch .text:004C3C80 z = dword ptr 10h .text:004C3C80 flag1 = dword ptr 14h .text:004C3C80 flag2 = dword ptr 18h .text:004C3C80 .text:004C3C80 000 xor edx, edx .text:004C3C82 000 xor eax, eax .text:004C3C84 000 fld [esp+z] .text:004C3C88 000 fld [esp+y] .text:004C3C8C 000 jmp short loc_4C3C94 .text:004C3C8C ; --------------------------------------------------------------------------- .text:004C3C8E 000 align 10h .text:004C3C90 .text:004C3C90 loc_4C3C90: ; CODE XREF: _createMarker+20j .text:004C3C90 000 add eax, 38h .text:004C3C93 000 inc edx .text:004C3C94 .text:004C3C94 loc_4C3C94: ; CODE XREF: _createMarker+Cj .text:004C3C94 000 cmp ds:_radarBlips.inUse[eax], 0 .text:004C3C9B 000 jz short loc_4C3CA2 .text:004C3C9D 000 cmp edx, 75 .text:004C3CA0 000 jb short loc_4C3C90 .text:004C3CA2 .text:004C3CA2 loc_4C3CA2: ; CODE XREF: _createMarker+1Bj .text:004C3CA2 000 cmp edx, 75 .text:004C3CA5 000 jnb loc_4C3D70 .text:004C3CAB 000 mov ecx, edx .text:004C3CAD 000 mov eax, [esp+type] .text:004C3CB1 000 imul ecx, 38h .text:004C3CB4 000 fld [esp+x] .text:004C3CB8 000 mov ds:_radarBlips.type[ecx], eax .text:004C3CBE 000 mov dword ptr ds:_radarBlips.id_color[ecx], 5 .text:004C3CC8 000 mov ds:_radarBlips.field_26[ecx], 1 .text:004C3CCF 000 mov ds:_radarBlips.inUse[ecx], 1 .text:004C3CD6 000 mov ds:_radarBlips.field_28[ecx], 0 .text:004C3CDD 000 mov ds:_radarBlips.field_2C[ecx], 3F800000h .text:004C3CE7 000 fstp ds:_radarBlips.pos.x[ecx] .text:004C3CED 000 fst ds:_radarBlips.pos.y[ecx] .text:004C3CF3 000 fld st(1) .text:004C3CF5 000 fstp ds:_radarBlips.pos.z[ecx] .text:004C3CFB 000 fld [esp+x] .text:004C3CFF 000 mov eax, [esp+flag2] .text:004C3D03 000 fstp ds:_radarBlips.field_18.x[ecx] .text:004C3D09 000 fst ds:_radarBlips.field_18.y[ecx] .text:004C3D0F 000 fld st(1) .text:004C3D11 000 fstp ds:_radarBlips.field_18.z[ecx] .text:004C3D17 000 mov ds:_radarBlips.entityHandle[ecx], 0 .text:004C3D21 000 mov ds:_radarBlips.field_30[ecx], 1 .text:004C3D2A 000 mov ds:_radarBlips.field_32[ecx], ax .text:004C3D31 000 mov eax, edx .text:004C3D33 000 imul eax, 38h .text:004C3D36 000 mov ds:_radarBlips.iconID[ecx], 0 .text:004C3D3F 000 cmp ds:_radarBlips.field_24[eax], 0FFFEh .text:004C3D47 000 jnb short loc_4C3D52 .text:004C3D49 000 inc ds:_radarBlips.field_24[eax] .text:004C3D50 000 jmp short loc_4C3D5B .text:004C3D52 ; --------------------------------------------------------------------------- .text:004C3D52 .text:004C3D52 loc_4C3D52: ; CODE XREF: _createMarker+C7j .text:004C3D52 000 mov ds:_radarBlips.field_24[eax], 1 .text:004C3D5B .text:004C3D5B loc_4C3D5B: ; CODE XREF: _createMarker+D0j .text:004C3D5B 000 movzx eax, ds:_radarBlips.field_24[eax] .text:004C3D62 000 fcompp .text:004C3D64 000 shl eax, 10h .text:004C3D67 000 or eax, edx .text:004C3D69 000 retn .text:004C3D69 ; --------------------------------------------------------------------------- .text:004C3D6A 000 align 10h .text:004C3D70 .text:004C3D70 loc_4C3D70: ; CODE XREF: _createMarker+25j .text:004C3D70 000 or eax, 0FFFFFFFFh .text:004C3D73 000 fcompp .text:004C3D75 000 retn .text:004C3D75 _createMarker endp
А вот я ее перевел в C++:
DWORD __cdecl Create_Marker(DWORD type, float x, float y, float z, DWORD flag1, DWORD flag2) { DWORD index = 0; for (int i=0; index < 75; i++) { index = i; if ( VCRadarBlips[index].inUse == 0) { VCRadarBlips[index].typeMarker = type; VCRadarBlips[index].id_color = 5; VCRadarBlips[index].field_26 = 1; VCRadarBlips[index].inUse = 1; VCRadarBlips[index].field_28 = 0; VCRadarBlips[index].field_2C = 0x3F800000; VCRadarBlips[index].pos.x = x; VCRadarBlips[index].pos.y = y; VCRadarBlips[index].pos.z = z; VCRadarBlips[index].field_18 = VCRadarBlips[index].pos; VCRadarBlips[index].entityHandle = 0; VCRadarBlips[index].scale = 1; VCRadarBlips[index].field_32 = flag2; VCRadarBlips[index].iconID = 0; if (VCRadarBlips[index].field_24 <= 0xFFFE) { VCRadarBlips[index].field_24 = 1; return ((VCRadarBlips[index].field_24 << 16) | index); } VCRadarBlips[index].field_24 += VCRadarBlips[index].field_24; return ((VCRadarBlips[index].field_24 << 16) | index); } } return ((VCRadarBlips[index].field_24 << 16) | index); };
Верно ли я сделал?
Offline
Нет, конечно. В целом-то правильно, но есть некоторые нюансы.
Вот, например, что это?
VCRadarBlips[index].field_2C = 0x3F800000;
Хотя, это бы прокатило. Не прокатит то, что условие для wGenerationId перепутано.
Вообще, при переводе кода рекомендуется не передирать тупо подстрочник, а, хотя бы, попытаться понять, что этот код делает. Зачем нужна отдельная переменная index, если она дублирует i ?
Offline
А так:
DWORD __cdecl Create_Marker(DWORD type, float x, float y, float z, DWORD flag1, DWORD flag2) { DWORD result = -1; for (int i=0; i < 75; i++) { if ( VCRadarBlips[i].inUse == 0) { VCRadarBlips[i].typeMarker = type; VCRadarBlips[i].id_color = 5; VCRadarBlips[i].field_26 = 1; VCRadarBlips[i].inUse = 1; VCRadarBlips[i].field_28 = 0; VCRadarBlips[i].field_2C = 1.0f; VCRadarBlips[i].pos.x = x; VCRadarBlips[i].pos.y = y; VCRadarBlips[i].pos.z = z; VCRadarBlips[i].field_18 = VCRadarBlips[i].pos; VCRadarBlips[i].entityHandle = 0; VCRadarBlips[i].scale = 1; VCRadarBlips[i].field_32 = flag2; VCRadarBlips[i].iconID = 0; VCRadarBlips[i].field_24++; if ((VCRadarBlips[i].field_24 & 0xFFFF)==0) VCRadarBlips[i].field_24 = 1; result = ((VCRadarBlips[index].field_24 << 16) | i) break; } } } return result; };
Offline
Должно быть как-то так (у меня названия полей слегка отличаются):
DWORD CBlips::createBlip (DWORD dwEntityType, float fX, float fY, float fZ, WORD wFlags1, WORD wFlags2) { CBlip * pBlip = m_blips; for (DWORD i = 0; i < 75; i++, pBlip++) if (!pBlip->m_bInUse) { pBlip->m_dwColor = 5; pBlip->m_dwEntityType = dwEntityType; pBlip->m_hEntity = 0; pBlip->m_vPos.x = pBlip->_f18.x = fX; pBlip->m_vPos.y = pBlip->_f18.y = fY; pBlip->m_vPos.z = pBlip->_f18.z = fZ; pBlip->_f26 = 1; pBlip->m_bInUse = 1; pBlip->_f28 = 0; pBlip->_f2C = 1.f; pBlip->m_wScale = 1; pBlip->m_wFlag2 = wFlags2; pBlip->m_wIconId = 0; if (pBlip->m_wGenerationId < 0xFFFE) pBlip->m_wGenerationId++; else pBlip->m_wGenerationId = 1; return (pBlip->m_wGenerationId << 16)|i; } return 0xFFFFFFFF; }
Offline
Вот еще:
.text:004C3840 _showMarkerOnRadar proc near ; CODE XREF: CScriptThread__opcodeHandler_03+A4Ap .text:004C3840 ; CScriptThread__opcodeHandler_03+13C3p .text:004C3840 ; CScriptThread__opcodeHandler_03+1434p .text:004C3840 ; CScriptThread__opcodeHandler_03+14A5p ... .text:004C3840 .text:004C3840 arg_0 = dword ptr 4 .text:004C3840 arg_4 = dword ptr 8 .text:004C3840 .text:004C3840 000 mov edx, [esp+arg_0] ; 131072 .text:004C3844 000 push ebx .text:004C3845 004 mov eax, edx .text:004C3847 004 push ebp .text:004C3848 008 mov ecx, eax .text:004C384A 008 mov ebp, [esp+8+arg_4] .text:004C384E 008 and ecx, 0FFFFh .text:004C3854 008 cmp edx, 0FFFFFFFFh .text:004C3857 008 jz short loc_4C3878 .text:004C3859 008 mov ebx, ecx ; ebx = id .text:004C385B 008 and eax, 0FFFF0000h ; ; 131072 .text:004C3860 008 lea edx, ds:0[ebx*8] ; edx = 8*0 .text:004C3867 008 shr eax, 10h .text:004C386A 008 sub edx, ebx .text:004C386C 008 movzx edx, ds:_radarBlips.field_24[edx*8] .text:004C3874 008 cmp eax, edx .text:004C3876 008 jz short loc_4C387B .text:004C3878 .text:004C3878 loc_4C3878: ; CODE XREF: _showMarkerOnRadar+17j .text:004C3878 008 or ecx, 0FFFFFFFFh .text:004C387B .text:004C387B loc_4C387B: ; CODE XREF: _showMarkerOnRadar+36j .text:004C387B 008 cmp ds:_menu.field_35, 0 .text:004C3882 008 jz short loc_4C3889 .text:004C3884 008 mov ebp, 1 .text:004C3889 .text:004C3889 loc_4C3889: ; CODE XREF: _showMarkerOnRadar+42j .text:004C3889 008 cmp ecx, 0FFFFFFFFh .text:004C388C 008 jnz short loc_4C3891 .text:004C388E 008 pop ebp .text:004C388F 004 pop ebx .text:004C3890 000 retn .text:004C3891 ; --------------------------------------------------------------------------- .text:004C3891 .text:004C3891 loc_4C3891: ; CODE XREF: _showMarkerOnRadar+4Cj .text:004C3891 008 lea eax, ds:0[ecx*8] .text:004C3898 008 sub eax, ecx .text:004C389A 008 mov ds:_radarBlips.Scale[eax*8], bp .text:004C38A2 008 pop ebp .text:004C38A3 004 pop ebx .text:004C38A4 000 retn .text:004C38A4 _showMarkerOnRadar endp
Пойдет так как я перевел?
void __cdecl ScaleMarkerOnRadar(DWORD id_marker, DWORD Scale) { DWORD _menu_field_35 = 0x0869630 + 0x35; DWORD id_, s_id; WORD f24; //131072 id_ = 0x0ffff & id_marker; //ID = 0 s_id = id_marker >> 16; f24 = VCRadarBlips[0].field_24; if (id_marker == 0xFFFFFFFF) return; if (s_id == VCRadarBlips[id_].field_24) { if ( *(BYTE*)_menu_field_35 == 0 ) VCRadarBlips[id_].scale = Scale; } };
Offline
Работать должно, но код получается совершенно нечитабельным.
Для начала, я бы вынес получение маркера в отдельную функцию (эта операция используется очень часто).
__inline CMarker * getMarkerByHandle (DWORD dwHandle) { if (0xFFFFFFFF == dwHandle) return NULL; CMarker * pBlip = VCRadarMarkers+(dwHandle & 0xFFFF); return pBlip->field_24 == (dwHandle >> 16) ? pBlip : NULL; }
Дальше, получается так:
void CRadar::changeBlipScale (DWORD dwHandle, DWORD dwScale) { BYTE * _menu_f35 = reinterpret_cast<BYTE *>(0x0869630 + 0x35); CMarker * pBlip = getMarkerByHandle (dwHandle); if (pBlip && !(*_menu_f35)) pBlip->scale = dwScale; }
Несколько замечаний:
* Венгерская нотация для отреверсенного кода увеличивает читабельность в разы.
* Никогда, никогда-никогда, нельзя использовать C-шное приведение типа за пределами чистого C. Первый же опретор приведения типа или класс с множественным наследованием, приведут к появлению странных, очень трудно отлавливаемых ошибок.
Offline
vPos.x
А почему тип отсутствует, по нотации? Как же указать что это переменная структуры?
Offline
* Никогда, никогда-никогда, нельзя использовать C-шное приведение типа за пределами чистого C. Первый же опретор приведения типа или класс с множественным наследованием, приведут к появлению странных, очень трудно отлавливаемых ошибок.
А можно вот тут вопрос? Я читал где-то тут на форуме про низкоуровневую имплементацию множественного наследования в C++, но не понимаю, почему не возникает такой же неоднозначности при приведении типов для классов с множественной реализацией COM-интерфейсов? И вообще с интерфейсами, как в Java, Delphi или .NET. Ведь интерфейс тоже имеет ненулевой размер (хотя бы для хранения указателя на VMT)...
PS: Позравляю с прошедшим днем программиста. Хотел вчера создать темку с позравлением, но сайт неожиданно упал...=(
Offline
Вот эту еще надо перевести в C++
.text:004C3C00 ; int __cdecl createRadarBlip(int, float, float, float, int, int) .text:004C3C00 _createRadarBlip proc near ; CODE XREF: CScriptThread__opcodeHandler_13+1B08p .text:004C3C00 ; CScriptThread__opcodeHandler_12+9FAp .text:004C3C00 .text:004C3C00 type = dword ptr 4 .text:004C3C00 x = dword ptr 8 .text:004C3C00 y = dword ptr 0Ch .text:004C3C00 z = dword ptr 10h .text:004C3C00 flag1 = dword ptr 14h .text:004C3C00 flag2 = dword ptr 18h .text:004C3C00 .text:004C3C00 000 8B 44 24 14 mov eax, [esp+flag1] .text:004C3C04 000 8B 54 24 18 mov edx, [esp+flag2] .text:004C3C08 000 53 push ebx .text:004C3C09 004 55 push ebp .text:004C3C0A 008 52 push edx ; flag2 .text:004C3C0B 00C 50 push eax ; flag1 .text:004C3C0C 010 8B 44 24 14 mov eax, [esp+10h+type] .text:004C3C10 010 FF 74 24 20 push [esp+10h+z] ; z .text:004C3C14 014 FF 74 24 20 push [esp+14h+y] ; y .text:004C3C18 018 FF 74 24 20 push [esp+18h+x] ; x .text:004C3C1C 01C 50 push eax ; type .text:004C3C1D 020 E8 5E 00 00 00 call _createMarker .text:004C3C22 020 83 C4 18 add esp, 18h .text:004C3C25 008 83 F8 FF cmp eax, 0FFFFFFFFh .text:004C3C28 008 75 06 jnz short loc_4C3C30 ; != .text:004C3C2A 008 83 C8 FF or eax, 0FFFFFFFFh .text:004C3C2D 008 5D pop ebp .text:004C3C2E 004 5B pop ebx .text:004C3C2F 000 C3 retn .text:004C3C30 ; --------------------------------------------------------------------------- .text:004C3C30 .text:004C3C30 loc_4C3C30: ; CODE XREF: _createRadarBlip+28j .text:004C3C30 008 89 C1 mov ecx, eax .text:004C3C32 008 89 CA mov edx, ecx .text:004C3C34 008 81 E2 FF FF 00 00 and edx, 0FFFFh .text:004C3C3A 008 83 F8 FF cmp eax, 0FFFFFFFFh .text:004C3C3D 008 74 20 jz short loc_4C3C5F .text:004C3C3F 008 89 D5 mov ebp, edx .text:004C3C41 008 81 E1 00 00 FF FF and ecx, 0FFFF0000h .text:004C3C47 008 8D 1C ED 00 00 00 00 lea ebx, ds:0[ebp*8] .text:004C3C4E 008 C1 E9 10 shr ecx, 10h .text:004C3C51 008 29 EB sub ebx, ebp .text:004C3C53 008 0F B7 1C DD 5C 7D 7D 00 movzx ebx, ds:_radarBlips.field_24[ebx*8] .text:004C3C5B 008 39 D9 cmp ecx, ebx .text:004C3C5D 008 74 03 jz short loc_4C3C62 .text:004C3C5F .text:004C3C5F loc_4C3C5F: ; CODE XREF: _createRadarBlip+3Dj .text:004C3C5F 008 83 CA FF or edx, 0FFFFFFFFh .text:004C3C62 .text:004C3C62 loc_4C3C62: ; CODE XREF: _createRadarBlip+5Dj .text:004C3C62 008 8D 0C D5 00 00 00 00 lea ecx, ds:0[edx*8] .text:004C3C69 008 29 D1 sub ecx, edx .text:004C3C6B 008 C6 04 CD 60 7D 7D 00 01 mov ds:_radarBlips.field_28[ecx*8], 1 .text:004C3C73 008 5D pop ebp .text:004C3C74 004 5B pop ebx .text:004C3C75 000 C3 retn .text:004C3C75 _createRadarBlip endp
Вот начало перевода:
DWORD __cdecl CreateRadarBlip(DWORD type, float x, float y, float z, DWORD flag1, DWORD flag2) { DWORD res = Create_Marker(type, x,y,z,flag1,flag2); if(x != 0xFFFFFFFF) return ( res | 0xFFFFFFFF); };
Last edited by VintProg_Pro (20-09-2011 06:27)
Offline
хочешь написать свою ф-цию создания маркера? там ведь не только тот приведённый кусок, для "полноты ощущений" нужно ещё и свою структуру забабахать в которой хранятся эти самые блипы.
Offline
забобахана давно уже CMarker
Offline
А можно вот тут вопрос? Я читал где-то тут на форуме про низкоуровневую имплементацию множественного наследования в C++, но не понимаю, почему не возникает такой же неоднозначности при приведении типов для классов с множественной реализацией COM-интерфейсов? И вообще с интерфейсами, как в Java, Delphi или .NET. Ведь интерфейс тоже имеет ненулевой размер (хотя бы для хранения указателя на VMT)...
В случае, в .net и всем, что на нем основано - приведение типа делается с учетом типа (т.е., применительно к объектам, любой cast рассматривается, как dynamic). В delphi - нет множественного наследования. Приводить указатель на объекты COM нельзя. (вернее, можно, но результат абсолютно непредсказуем). Для них нужно делать QueryInterface (и там легко может генерироваться промежуточный объект, никак не связанный с приводимым - я с таким встречался).
Offline
Как насчет моей функции?
Offline
В случае, в .net и всем, что на нем основано - приведение типа делается с учетом типа (т.е., применительно к объектам, любой cast рассматривается, как dynamic). В delphi - нет множественного наследования. Приводить указатель на объекты COM нельзя. (вернее, можно, но результат абсолютно непредсказуем). Для них нужно делать QueryInterface (и там легко может генерироваться промежуточный объект, никак не связанный с приводимым - я с таким встречался).
Хм, понятно... Я видимо не совсем верно понял суть COM-программирования. Надо будет поэкспериментировать с этим как-нибудь.
Offline