Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi DirectX-Hook: Wireframe funktioniert aber nicht DrawTextA (https://www.delphipraxis.net/121782-directx-hook-wireframe-funktioniert-aber-nicht-drawtexta.html)

napsterxx 4. Okt 2008 14:10


DirectX-Hook: Wireframe funktioniert aber nicht DrawTextA
 
Hallo liebe DPler,
also ich bastel an einer DLL welche in einem Spiel Text anzeigt. Das Spiel ist recht alt und verwendet DirectX8.
Ich habe die madCollection genommen, da dort Beispiele dabei sind für DirectX Hooks.
Wenn ich die DLL nun systemweit injiziere und mein Spiel starte sehe ich alle "vertices" einzeln, also so ein Drahtgitter.
Nun dachte ich wenn das geht muss ich doch auch einen Text zeichnen können.

Lange rede, kurzer Quelltext :D

Delphi-Quellcode:
var
  font: ID3DXFont;
  fonttype: WIndows.HFONT;
  D3DXDev8: IDirect3DDevice8;
  Direct3DCreate8Next : function (sdkVersion                                        : dword ) : dword; stdcall = nil;
  CreateDevice8Next  : function (self, adapter, devType, wnd, flags, params, device : pointer) : dword; stdcall = nil;
  SetRenderState8Next : function (self: pointer; stateType, state                   : dword ) : dword; stdcall = nil;


function SetRenderState8Callback(self: pointer; stateType, state: dword) : dword; stdcall;
begin
  if stateType = D3DRS_FILLMODE then
    if state = D3DFILL_WIREFRAME then
         state := D3DFILL_SOLID
    else state := D3DFILL_WIREFRAME;
  result := SetRenderState8Next(self, stateType, state);

end;


procedure ShowText;
var
  rect : TRect;
begin
  rect.Top := 1; rect.Left := 1;
  rect.Bottom := 1+200; rect.Right := 1+200;

  font.DrawTextA( 'Hello World',Length('Hello World'),rect,DT_TOP,$aa00ff00);
end;

function CreateDevice8Callback(self, adapter, devType, wnd, flags, params, device: pointer) : dword; stdcall;
begin
  result := CreateDevice8Next(self, adapter, devType, wnd, flags, params, device);
  D3DXDev8 := IDirect3DDevice8(device^);
  if font = nil then
  begin
    fonttype := CreateFont(14,0,0,0,FW_BOLD,1,0,0,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
                         CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH,'Arial' );
    D3DXCreateFont(D3DXDev8, fonttype, font );
  end;
  if result = 0 then begin
    if @SetRenderState8Next = nil then
      HookCode(GetInterfaceMethod(device^, 50), @SetRenderState8Callback, @SetRenderState8Next);
    if (device <> nil) and (pointer(device^) <> nil) then
      SetRenderState8Next(pointer(device^), D3DRS_FILLMODE, D3DFILL_WIREFRAME);
  end;
end;

function Direct3DCreate8Callback(sdkVersion: dword) : dword; stdcall;
begin
  result := Direct3DCreate8Next(sdkVersion);

  ShowText; // Lasse ich es weg sehe ich ein Drahtgitter, mit dieser Zeile crasht alles

  if result <> 0 then
    if @CreateDevice8Next = nil then
      HookCode(GetInterfaceMethod(result, 15), @CreateDevice8Callback, @CreateDevice8Next);
end;


function HookDirect3D8 : boolean;
begin
  result := HookApiIAT('d3d8.dll', 'Direct3DCreate8', @Direct3DCreate8Callback, @Direct3DCreate8Next);
end;
Die Methode mit dem DrawTextA habe ich aus einem DirectX9 Buch für Delphi. Da ich die madCollection nicht besitze habe ich alles auf die uAllHook.pas umgeschrieben.

Das Problem. Ich starte das game, es stürtzt ab :D Ich kann nur Schließen klicken.

napsterxx 5. Okt 2008 09:21

Re: DirectX-Hook: Wireframe funktioniert aber nicht DrawText
 
*push*
Irgendjemand muss doch wissen was falsch ist :D

Medium 5. Okt 2008 12:54

Re: DirectX-Hook: Wireframe funktioniert aber nicht DrawText
 
Ganz blöde Vermutung: Du hookst erst das Create, rufst darin bereits das Zeichnen des Textes auf, hookst danach aber erst das Device, in dem der Font initialisiert wird. So lange der Font also nicht bereits vom Host erstellt wird, was ich erstmal nicht glaube, läufst du da einfach gesagt auf eine AV wenn ich die Reihenfolge der Ereignisse jetzt richtig bewerte.

Edit: Um selbst etwas zeichnen zu können, müsstest du imho auch eher den PageFilp (oder wie auch immer das Umschalten des Backbuffers zum Frontbuffer bei DX nun heisst :)) hooken, da du ja ohnehin jeden Frame zeichnen musst. Da langt es natürlich nicht mehr wie beim Ändern des Renderstates es einfach einmalig zu machen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz