1

Ive been working on a project to fix an old game and eventually came accross new ideas for it, adding some cool extra information about the game world and real-time tracking of some important information that the game itself hides from the user (for no actual reason) and came across this problem:

When i try to draw over the game, to show the information i wanted to, the game updates its own windows and draws over.

My first approach was to use a window with HWND_TOPMOST to be on top of the game's window, but it doesnt work as expected, the window just wont get over the game window and wont show the information.

The second approach was to use GDI functions such as TextOut, the text is there but will flicker a lot and forcing it to draw in a short ammount of time will use too much memory.

I wanted some ideas on how to do this without actually hooking DX functions nor anything like that (since i know very few of DX). Is there any way to actually draw over this window to show the information without flickering?

Johan
  • 74,508
  • 24
  • 191
  • 319
  • To draw over the window game without flickering ,i suggest you to draw your text on a temporary bitmap , then draw this bitmap over the window game . – S.MAHDI Oct 07 '13 at 16:54
  • You want us to give you advice on hacking a program whose implementation details we know nothing about? – David Heffernan Oct 07 '13 at 16:57
  • Backbuffering is not the problem here i guess, since i only call one TextOut and still, its flickering. David, im sorry but its not about actually hacking the game, its more about drawing over a directdraw window i guess but if needed i can provide some information about the game itself if you believe it will help. – Carlos Cortez Oct 07 '13 at 17:12
  • Well, it's certainly hacking in some sense. Anyway, it's hard to know what to suggest if we don't know what the game is actually doing. – David Heffernan Oct 07 '13 at 17:32
  • Rising lands, 1997. The game runs only in fullscreen and since its old i guess there are a lot of problems running it on a win 7 (From memory management to drawing, everything is different). Could be done with a detour right after the game draw the scene, but im writing game fixes in ASM, and doing all this work with asm would be a pain... The other part is delphi, wich sucks to actually write hooks and stuff like that. I did this before but in newer games, HWND_TOPMOST should place my window over the game's but in this case it doesnt. – Carlos Cortez Oct 07 '13 at 17:40
  • There's a library for DirectX, have a look at http://www.micrel.cz/Dx/ it has all the stuff for 2D in directX that you should need. And it uses Delphi components to abstract most of the DirectX complications away. It's really very cool. – Johan Oct 08 '13 at 17:17

1 Answers1

0

You can use unDelphiX to get a Delphi package that does DirectX.
You can download the package here: http://www.micrel.cz/Dx/

It is fully up to date and makes DirectX work almost like the standard GDI.

Drawing without flicker
The trick to eliminating flicker is to draw to an off-screen surface and "flip" the offscreen surface in view when you're done.
The flip can be synchronized with the VerticalSync, so there's no tearing as well.

Demo
There's a demo that displays the current time in milliseconds without any blinking.

unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, Menus, DXClass, DXDraws;

type
  TMainForm = class(TDXForm)
    DXDraw: TDXDraw;
    DXTimer: TDXTimer;  //Precision timer. 
    procedure DXDrawFinalize(Sender: TObject);
    procedure DXDrawInitialize(Sender: TObject);
    procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
  end;

var
  MainForm: TMainForm;

implementation

uses MMSystem;

{$R *.DFM}

procedure TMainForm.DXDrawInitialize(Sender: TObject);
begin
  DXTimer.Enabled := True;
end;

procedure TMainForm.DXDrawFinalize(Sender: TObject);
begin
  DXTimer.Enabled := False;
end;

procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
var
  formattedDateTime: string;
begin
  if not DXDraw.CanDraw then exit;

  DXDraw.Surface.Fill(0);

  with DXDraw.Surface.Canvas do  //Draw to offscreen surface.
  begin
    Brush.Style := bsClear;
    Font.Color := clWhite;
    Font.Size := 30;
    DateTimeToString(formattedDateTime, 'hh:nn:ss.zzz', Now);
    Textout(30, 30, formattedDateTime);

    Release; {  Indispensability  }
  end;

  DXDraw.Flip;  //Flip the offscreen surface to screen, no flicker :=)
end;

end.

Installing unDelphiX in XE2
In order to get the package installed in Delphi XE2 I had to add DesignIDE to the requires clause of the dpk. like so:

enter image description here

This will fix the DesignIntf.dcu not found error.

Displaying full screen
If you want to do fullscreen you enable it in the settings of DXDraw, but note:

enter image description here

If you enable doFullScreen without enabling doSelectDriver you'll get an interface not supported error. Enable them both and everything will be fine.
See: http://www.micrel.cz/Dx/history.rtf

Don't forget to listen for keypresses and exit the app on ESC or something, or you'll be stuck in full screen mode.

Johan
  • 74,508
  • 24
  • 191
  • 319
  • Testing it right now, i even started a weapper in C++ to use the game's DD object to show the information but this seems far easier (and simple), will give it a try, thanks for the suggestion. As soon as i finish testing, if works, i accept the answer. – Carlos Cortez Oct 08 '13 at 22:29
  • 1
    Im sorry @Johan but this only draws on the form itself, not over other windows as expected :( – Carlos Cortez Oct 08 '13 at 22:37
  • Have you seen this question, it seems to address your issue. http://stackoverflow.com/questions/148275/how-do-i-draw-transparent-directx-content-in-a-transparent-window – Johan Oct 08 '13 at 22:49
  • Indeed, will take a look at it for sure, only issue is the C# part but nothing i cant work around to code in delphi/c++ i guess – Carlos Cortez Oct 08 '13 at 22:52
  • See also: http://stackoverflow.com/questions/18279272/how-do-i-draw-transparent-rectangles-using-directx-in-c and http://code.google.com/p/transparent-canvas/ and I remember there being a demo in Delphi that displayed bugs on top of the current screen that then needed to be clicked in order to go away (cannot remember what it was called though). – Johan Oct 08 '13 at 23:07