SRL Archive - General

Crash on Result assignment :S


Brandon

2014-03-28 19:36:05

My code is as follows: [ATTACH=CONFIG]23131[/ATTACH]

Everything works (sort of).. It loads in Smart, however, just one stupid problem in the below Unit (Function Direct3DCreate9…..)

It crashes when I do: Result := Proxy; It gives: EXCEPTION_ACCESS_VIOLATION

Any possible reason it would crash on Result but not anything else?
I've been debugging it for ages! That's the only place it crashes and I have no clue why.. I tried using AllocMem instead but no cigar. Still crashes :l


unit ExportInfo;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, DynLibs, Windows, Direct3D9, D3DProxy;

type
d3d9_dll = record
dll: HMODULE;
D3DPERF_BeginEvent: Pointer;
D3DPERF_EndEvent: Pointer;
D3DPERF_GetStatus: Pointer;
D3DPERF_QueryRepeatFrame: Pointer;
D3DPERF_SetMarker: Pointer;
D3DPERF_SetOptions: Pointer;
D3DPERF_SetRegion: Pointer;
DebugSetLevel: Pointer;
DebugSetMute: Pointer;
Direct3DCreate9: Pointer;
Direct3DCreate9Ex: Pointer;
Direct3DShaderValidatorCreate9: Pointer;
PSGPError: Pointer;
PSGPSampleTexture: Pointer;
end;

var
D3D9Proxy: Direct3D9Proxy;
OriginalDX: HMODULE;
d3d9: d3d9_dll;

Function Initialize(): Boolean;
Function DeInitialize(): Boolean;
Procedure D3DPERF_BeginEvent; stdcall;
Procedure D3DPERF_EndEvent; stdcall;
Procedure D3DPERF_GetStatus; stdcall;
Procedure D3DPERF_QueryRepeatFrame; stdcall;
Procedure D3DPERF_SetMarker; stdcall;
Procedure D3DPERF_SetOptions; stdcall;
Procedure D3DPERF_SetRegion; stdcall;
Procedure DebugSetLevel; stdcall;
Procedure DebugSetMute; stdcall;
Function Direct3DCreate9(SDKVersion: LongWord): IDirect3D9; stdcall;
Procedure Direct3DCreate9Ex; stdcall;
Procedure Direct3DShaderValidatorCreate9; stdcall;
Procedure PSGPError; stdcall;
Procedure PSGPSampleTexture; stdcall;


implementation


Function Initialize(): Boolean;
var
Root: Array of TChar;
begin
SetLength(Root, MAX_PATH);
GetSystemDirectoryA(@Root[0], MAX_PATH);
StrCat(@Root[0], '\d3d9.dll');

OriginalDX := LoadLibraryA(@Root[0]);

if (OriginalDX <> NilHandle) then
begin
d3d9.D3DPERF_BeginEvent := GetProcAddress(OriginalDX, 'D3DPERF_BeginEvent');
d3d9.D3DPERF_EndEvent := GetProcAddress(OriginalDX, 'D3DPERF_EndEvent');
d3d9.D3DPERF_GetStatus := GetProcAddress(OriginalDX, 'D3DPERF_GetStatus');
d3d9.D3DPERF_QueryRepeatFrame := GetProcAddress(OriginalDX, 'D3DPERF_QueryRepeatFrame');
d3d9.D3DPERF_SetMarker := GetProcAddress(OriginalDX, 'D3DPERF_SetMarker');
d3d9.D3DPERF_SetOptions := GetProcAddress(OriginalDX, 'D3DPERF_SetOptions');
d3d9.D3DPERF_SetRegion := GetProcAddress(OriginalDX, 'D3DPERF_SetRegion');
d3d9.DebugSetLevel := GetProcAddress(OriginalDX, 'DebugSetLevel');
d3d9.DebugSetMute := GetProcAddress(OriginalDX, 'DebugSetMute');
d3d9.Direct3DCreate9 := GetProcAddress(OriginalDX, 'Direct3DCreate9');
d3d9.Direct3DShaderValidatorCreate9 := GetProcAddress(OriginalDX, 'Direct3DShaderValidatorCreate9');
d3d9.PSGPError := GetProcAddress(OriginalDX, 'PSGPError');
d3d9.PSGPSampleTexture := GetProcAddress(OriginalDX, 'PSGPSampleTexture');
d3d9.Direct3DCreate9Ex := GetProcAddress(OriginalDX, 'Direct3DCreate9Ex');
end else
Result := False;

SetLength(Root, 0);
Result := True;
end;

Function DeInitialize(): Boolean;
begin
if (OriginalDX <> NilHandle) then
begin
FreeLibrary(OriginalDX);
OriginalDX := NilHandle;
Result := True;
end else
Result := False;
end;

Procedure D3DPERF_BeginEvent; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.D3DPERF_BeginEvent]
end;

Procedure D3DPERF_EndEvent; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.D3DPERF_EndEvent]
end;

Procedure D3DPERF_GetStatus; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.D3DPERF_GetStatus]
end;

Procedure D3DPERF_QueryRepeatFrame; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.D3DPERF_QueryRepeatFrame]
end;

Procedure D3DPERF_SetMarker; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.D3DPERF_SetMarker]
end;

Procedure D3DPERF_SetOptions; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.D3DPERF_SetOptions]
end;

Procedure D3DPERF_SetRegion; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.D3DPERF_SetRegion]
end;

Procedure DebugSetLevel; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.DebugSetLevel]
end;

Procedure DebugSetMute; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.DebugSetMute]
end;

Function Direct3DCreate9(SDKVersion: LongWord): IDirect3D9; stdcall;
type
D3D9_Type = Function(SDKVersion: LongWord): IDirect3D9; stdcall;

var
pOriginal: IDirect3D9;
begin
pOriginal := D3D9_Type(d3d9.Direct3DCreate9)(SDKVersion); //NOT Nil!
D3D9Proxy := Direct3D9Proxy.Create(pOriginal); //Works fine!

MessageBoxA(0, 'Proxy is all good', '', 0); //Works fine!

Result := D3D9Proxy; //Crash.. Dammit..

MessageBoxA(0, 'Result is all good', '', 0); //Does not get called!
end;

Procedure Direct3DCreate9Ex; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.Direct3DCreate9Ex]
end;

Procedure Direct3DShaderValidatorCreate9; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.Direct3DShaderValidatorCreate9]
end;

Procedure PSGPError; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.PSGPError]
end;

Procedure PSGPSampleTexture; stdcall; Assembler; NoStackFrame;
{$ASMMODE INTEL}
asm
jmp [d3d9.PSGPSampleTexture]
end;


end.

Frement

2014-03-28 19:51:04

Shouldn't you do D3D9Proxy.Create(pOriginal); instead of D3D9Proxy := Direct3D9Proxy.Create(pOriginal); ?

Brandon

2014-03-28 21:15:05

From: Frement
Shouldn't you do D3D9Proxy.Create(pOriginal); instead of D3D9Proxy := Direct3D9Proxy.Create(pOriginal); ?


Made no difference.

Dgby714

2014-08-05 23:53:54

Maybe ask FPC?

Brandon

2014-08-06 10:39:44

From: Dgby714
Maybe ask FPC?


I'll try asking them. The commit is here: https://github.com/Brandon-T/PascalDXI if you want to try it out.

But yeah, I'll probably ask FPC and see.

Olly

2014-08-07 09:35:35

From: Brandon
I'll try asking them. The commit is here: https://github.com/Brandon-T/PascalDXI if you want to try it out.

But yeah, I'll probably ask FPC and see.


Do you do it a different way to how cynic did it @ https://github.com/MerlijnWajer/Simba/commit/4a0b5974f9df5dc94be1bcb99d9c6a5853d60b30

Or is it irrelevant since his is "screen scraping" while yours can read from a minimized app (well SMART).

Brandon

2014-08-07 10:56:48

From: Olly
Do you do it a different way to how cynic did it @ https://github.com/MerlijnWajer/Simba/commit/4a0b5974f9df5dc94be1bcb99d9c6a5853d60b30

Or is it irrelevant since his is "screen scraping" while yours can read from a minimized app (well SMART).


Detouring is different from screen scraping. We both use Clootie's DxWrapper to import all of the directx API. Other than that, it's completely different.

nielsie95

2014-08-16 18:20:34

Maybe it is because you are returning an interface. What if let Direct3D9Proxy derive from something like TInterfacedObject?


Direct3D9Proxy = class(TInterfacedObject, IDirect3D9)
..
end;

Brandon

2014-08-17 07:09:34

From: nielsie95
Maybe it is because you are returning an interface. What if let Direct3D9Proxy derive from something like TInterfacedObject?


Direct3D9Proxy = class(TInterfacedObject, IDirect3D9)
..
end;




Unfortunately that didn't help ={

However, I spent about an hour or more only trying to fix it.. I got it working now (in case anyone is interested): https://github.com/Brandon-T/Pascal-DX


The problem? Stupid reference tracking. If I AllocMem the class to the heap, as soon as I return the pointer to the allocated HEAP memory, the reference count drops to 0 and it's freed even without calling FreeMem. Either a bug or a huge boo-boo on my part.

I tried returning it directly. No pointers. Same story. Use pointers? Same story.
Eventually, I just casted the function to a function pointer that returned "pointer". Then I casted that result to an interface and returned that.

The reference count wasn't decremented, no leaks and all works.. Managed to get it working without AllocMem. Hopefully I didn't do some undefined behaviour stuff lol (pretty sure I didn't).

Then I got another stupid issue. WriteLn & WinAPI's MessageBoxA FAILS. It prints: "Dll Initialisation error". What? Lol.

So.. I ended up writing my own "WriteConsoleEx" function to print to the console. Reduced the amount of assembly used and voila. All is good and working.


TLDR:

Thanks for trying to help out. I got it working.

Olly

2014-08-17 10:38:42

From: Brandon
…


:( Any ideas?


Brandon

2014-08-17 10:40:07

From: Olly
:( Any ideas?

…




Huh? What am I looking at? That's the pascal plugin alright.. And it seems to be successfully loaded with some nice console colours lol.. Other than that, I don't see the problem :S

I recently pushed a commit to fix a couple things for the SMART interface: https://github.com/Brandon-T/Pascal-DX/commit/622b976b564cb21eff8de24f3202f08a7af031a5

It isn't "complete" in that aspect but everything else works.


EDIT: I see.. It shows black. Yeah that's because: https://github.com/Brandon-T/Pascal-DX/blob/622b976b564cb21eff8de24f3202f08a7af031a5/dxhooks.pas#L35 is commented out and blank.

Olly

2014-08-17 10:43:26

From: Brandon
Huh? What am I looking at? That's the plugin alright.. And it seems to be successfully loaded with some nice console colours lol.. Other than that, I don't see the problem :S

I recently pushed a commit to fix a couple things for the SMART interface: https://github.com/Brandon-T/Pascal-DX/commit/622b976b564cb21eff8de24f3202f08a7af031a5

It isn't "complete" in that aspect but everything else works.


Woops I kinda cropped the picture, but you can see the debug img being completely black to the right of the picture. So for it me it's not reading the colors.

Brandon

2014-08-17 10:45:39

From: Olly
Woops I kinda cropped the picture, but you can see the debug img being completely black to the right of the picture. So for it me it's not reading the colors.



Yeah. See the last reply. I had edited it. EndSceneHook is the only function that should need fixing along with the smart functions it uses. That's about all there is left to do.

Olly

2014-08-17 10:47:51

From: Brandon
Yeah. See the last reply. I had edited it. EndSceneHook is the only function that should need fixing along with the smart functions it uses. That's about all there is left to do.


Ah I will sit tight and hope that you are able to finish it one day, sadly i'm not much use (as always) with this. :P

Brandon

2014-08-17 14:55:50

Previous:

From: Olly
Ah I will sit tight and hope that you are able to finish it one day, sadly i'm not much use (as always) with this. :P

Lol.. It's pascal. We should all be able to do it. Eventually at least. I'll finish it soon. I basically just got it working only a couple hours ago and right now is breakfast time and trying to figure out some other nonsensical stuff.
After that, i'll probably finish it. It's basically just copy pasting the C code and changing it to pascal (most of the time at least.. minus the reference counting crap introduced by pascal which is all taken care of).
Hey at least almost everyone can compile it easily themselves and change stuff without the struggles.


.
.
.

@Olly; You can try it now. Should be complete and fully working. No browser support or external client support yet but that's only a couple lines of code to add and the port would be complete. Other than that, it just needs documentation lol.

Olly

2014-08-17 16:31:55

From: Brandon
Previous:


Lol.. It's pascal. We should all be able to do it. Eventually at least. I'll finish it soon. I basically just got it working only a couple hours ago and right now is breakfast time and trying to figure out some other nonsensical stuff.
After that, i'll probably finish it. It's basically just copy pasting the C code and changing it to pascal (most of the time at least.. minus the reference counting crap introduced by pascal which is all taken care of).
Hey at least almost everyone can compile it easily themselves and change stuff without the struggles.


.
.
.

@Olly; You can try it now. Should be complete and fully working. No browser support or external client support yet but that's only a couple lines of code to add and the port would be complete. Other than that, it just needs documentation lol.


/Olly is having too much fun, Tho what's the cheapest way you can think of to draw a pixel in dx? IDirect3DDevice9.ColorFill seems to be the best, as it accept a simple rect but it doesn't seem to draw on its-self, rather it wants a surface.

e: Kinda figured out and managed to make a DrawLine this should be fine. :)

Procedure DrawLine(Device: IDirect3DDevice9; X1, Y1, X2, Y2: Single; Colour: TD3DColor);
const
Resolution = 2;
VERTEX_FVF_TEX = (D3DFVF_XYZRHW or D3DFVF_DIFFUSE or D3DFVF_TEX1);
var
Vertices: Array[0 .. Resolution - 1] of D3DVertex;
begin

Vertices[0].X := X1;
Vertices[0].Y := Y1;
Vertices[0].Z := 0.0;
Vertices[0].RHW:= 1.0;
Vertices[0].Colour := Colour;

Vertices[1].X := X2;
Vertices[1].Y := Y2;
Vertices[1].Z := 0.0;
Vertices[1].RHW := 1.0;
Vertices[1].Colour := Colour;


Device.SetFVF(VERTEX_FVF_TEX);
Device.DrawPrimitiveUP(D3DPT_LINELIST, 2, Vertices, SizeOf(D3DVertex));
end;

Brandon

2014-08-17 20:16:40

From: Olly
/Olly is having too much fun, Tho what's the cheapest way you can think of to draw a pixel in dx? IDirect3DDevice9.ColorFill seems to be the best, as it accept a simple rect but it doesn't seem to draw on its-self, rather it wants a surface.

e: Kinda figured out and managed to make a DrawLine this should be fine. :)


Cheapest? As in the least overhead?

The cheapest would be to use a vertex or pixel buffer (VBO/PBO respectively). You could create a buffer directly on the graphics card and draw directly to it as you please with the lowest overhead. After all, all games do this for fps. The above stuff won't have much of an overhead. You really won't notice it at all.

Nice job on figuring out the funcs and how the drawing works.

If you're looking at optimizing, optimise the stupid BltSmartBuffer. Though it's not costly, it's annoying to look at.

Glad you're playing around with it. It's pretty neat yeah.

Olly

2014-08-17 20:23:52

From: Brandon

Cheapest you say?

The cheapest would be to use a vertex buffer. You could create a buffer directly on the graphics card and draw directly to it as you please with the lowest overhead. After all, all games do this for fps.

Nice job on figuring out the funcs and how the drawing works.


Seems way to complicated for me. :p

Does Smart.GetMousePos only give us the last targeted position? Not actually where the mouse is?

If you draw a dot of the mouse pos it comes out like below, and considering i'm in like 60 fps i would expect it to be a fine line.


Brandon

2014-08-17 20:28:34

From: Olly
Seems way to complicated for me. :p

Does Smart.GetMousePos only give us the last targeted position? Not actually where the mouse is?

If you draw a dot of the mouse pos it comes out like below, and considering i'm in like 60 fps i would expect it to be a fine line.



That's right. It returns the last place you moved the internal mouse.
It returns the exact position of where smart's internal mouse is. Not your physical/hardware mouse. Similar to calling getmousepos in Simba while smart is running.

If you want the physical mouse pos.. Call "getcursorpos" from the windows header.

Olly

2014-08-17 20:37:26

From: Brandon
That's right. It returns the last place you moved the internal mouse.
It returns the exact position of where smart's internal mouse is. Not your physical/hardware mouse. Similar to calling getmousepos in Simba while smart is running.

If you want the physical mouse pos.. Call "getcursorpos" from the windows header.


Yea, but i hoped it would update the position as smarts mouse was moving… I can't make true mouse trails!

Brandon

2014-08-17 20:56:23

From: Olly
Yea, but i hoped it would update the position as smarts mouse was moving… I can't make true mouse trails!


It can't do exactly that. That means every time smart gets the "moveMouse" function called, it'd have to notify the plugins. Atm, it doesn't work like that. The plugins REQUEST the mouse's position once per frame. I'd imagine you could make mouse trails perfectly fine like this. I can't see the problem.

Once per frame (if not MORE since its an EndSceneHook & not a PresentHook) is "extremely" accurate; if not already the exact same.

Olly

2014-08-17 21:08:54

From: Brandon
It can't do exactly that. That means every time smart gets the "moveMouse" function called, it'd have to notify the plugins. Atm, it doesn't work like that. The plugins REQUEST the mouse's position once per frame. I'd imagine you could make mouse trails perfectly fine like this. I can't see the problem.

Once per frame is "extremely" accurate; if not already the exact same.


It's not perfect if you connect the points with a line!. Anyway you have any idea why the first once flashes? :(
It's ugly but it's pretty much a base for another ones… (Press the button to loop though the two!).

http://www.speedyshare.com/djEsw/d3d9.dll

  
L := Length(Trail);
NewPos := (L > 0) and (Trail[0].x <> X) and (Trail[0].y <> Y);

case CurrTrail of
0:
begin
if ((NewPos) or (L = 0)) and (X > -1) and (Y > -1) then
begin
SetLength(Trail, L+1);
Move(Trail[0], Trail[1], L * SizeOf(TPoint));
Trail[0].x := X;
Trail[0].y := Y;

if ((L + 1) > 50) then
SetLength(Trail, 50);

h := High(Trail);
if (h > 0) then
for i := 0 to h - 1 do
if (Trail[i].x > -1) and (Trail[i].y > -1) then
DrawLine(weakRef_Direct3DDevice9, Trail[i].x, Trail[i].y, Trail[i+1].x, Trail[i+1].y);
end;
end;
1:
begin
if ((NewPos) or (L = 0)) and (X > -1) and (Y > -1) then
begin
DrawLine(weakRef_Direct3DDevice9, 0, 0 + y, SmartGlobal^.Width, 0 + y);
DrawLine(weakRef_Direct3DDevice9, 0 + x, 0, 0 + x, SmartGlobal^.Height);
end;
end;
end;

Brandon

2014-08-17 21:16:44

From: Olly
It's not perfect if you connect the points with a line!. Anyway you have any idea why the first once flashes? :(
It's ugly but it's pretty much a base for another ones… (Press the button to loop though the two!).

http://www.speedyshare.com/djEsw/d3d9.dll
…



Push it to your branch on github. I can't tell where the above code is.. I see a "MouseTrail" button on SMART that never changes state and a "snippet" of code above. Either github it or pm me it if you don't want it public. It's really really hard to tell. You got the weakReference stuff down so that's good. Other than that, I have no clue what's going on or where that snippet is from or how its used..


You could also be drawing the mouse BEFORE rendering and the rendering may be overwriting it. If all those variables are local, they'd be destroyed each frame as well and so there won't be any "mouse position history". *Need context*

Olly

2014-08-17 21:25:02

From: Brandon
Push it to your branch on github. I can't tell where the above code is.. I see a "MouseTrail" button on SMART that never changes state and a "snippet" of code above. Either github it or pm me it if you don't want it public. It's really really hard to tell. You got the weakReference stuff down so that's good. Other than that, I have no clue what's going on or where that snippet is from or how its used..


You could also be drawing the mouse BEFORE rendering and the rendering may be overwriting it. If all those variables are local, they'd be destroyed each frame as well and so there won't be any "mouse position history". *Need context*


Badly said by me, https://github.com/Olly-/Pascal-DX

{$DEFINE SMART}
{$i srl-6/srl.simba}

begin
smartPlugins := ['d3d9.dll'];
setupSRL();

repeat
Mouse(Point(random(0, 800), random(0, 600)));
wait(random(100));
until false;
end;

Run that, and the default mouse-trail (The line) should flicker for you.

Brandon

2014-08-17 22:40:14

From: Olly
..Run that, and the default mouse-trail (The line) should flicker for you.


@Olly; The TLDR is all the way at the bottom of this post.

Hmm the line doesn't flicker but the mouse trails do. There could be many reasons. OPTIMISE your code.. Try the below.. It's tested and it works.


Procedure DrawVerts(Device: IDirect3DDevice9; Colour: TD3DColor; Trails: TPointArray);
const
VERTEX_FVF_TEX = (D3DFVF_XYZRHW or D3DFVF_DIFFUSE or D3DFVF_TEX1);
var
I: Integer;
Vertices: Array of D3DVertex;
begin
SetLength(Vertices, Length(Trails));

For I := 0 To High(Vertices) Do
begin
Vertices[I].X := Trails[I].X;
Vertices[I].Y := Trails[I].Y;
Vertices[I].Z := 0.0;
Vertices[I].RHW := 1.0;
Vertices[I].Colour := Colour;
Vertices[I].U := 0.0;
Vertices[I].V := 0.0;
end;

//Draw all the vertices in a single call to the gfx.
Device.SetFVF(VERTEX_FVF_TEX);
Device.DrawPrimitiveUP(D3DPT_LINESTRIP, Length(Vertices) - 2, Vertices[0], sizeof(D3DVertex));
end;

Procedure AddPoint(var Pts: TPointArray; var Pt: TPoint; MaxTrailLength: Integer);
var
I: Integer;
begin
if (Length(Pts) < MaxTrailLength) then //Only resize the array if we are below the max trail length..
begin
SetLength(Pts, Length(Pts) + 1);
Pts[High(Pts)].X := Pt.X;
Pts[High(Pts)].Y := Pt.Y;
exit;
end;

For I := 0 To High(Pts) - 1 do
begin
Pts[I].X := Pts[I + 1].X;
Pts[I].Y := Pts[I + 1].Y;
end;
Pts[High(Pts)].X := Pt.X;
Pts[High(Pts)].Y := Pt.Y;
end;


Procedure DrawMouse(weakRef_Direct3DDevice9: IDirect3DDevice9; P: TPoint);
var
L, H, I: Integer;
NewPos: Boolean;
begin
L := Length(Trail);
NewPos := (L > 0) and (Trail[0].x <> P.X) and (Trail[0].y <> P.Y);

case CurrTrail of
0:
begin
if ((NewPos) or (L = 0)) and (P.X > -1) and (P.Y > -1) then
begin
AddPoint(Trail, P, 20);

If (Length(Trail) > 2) then //Draw lines (2+ points).. Otherwise draw a filled-circle if there are less than 2 vertices.
DrawVerts(weakRef_Direct3DDevice9, $FFFF0000, Trail)
Else
DrawCircle(weakRef_Direct3DDevice9, P.X, P.Y, 2.5);
end;
end;
1:
begin
if ((NewPos) or (L = 0)) and (P.X > -1) and (P.Y > -1) then
begin
DrawLine(weakRef_Direct3DDevice9, 0, 0 + P.y, SmartGlobal^.Width, 0 + P.y);
DrawLine(weakRef_Direct3DDevice9, 0 + P.x, 0, 0 + P.x, SmartGlobal^.Height);
end;
end;
end;
end;

Procedure EndSceneHook(ptr_Direct3DDevice9: IDirect3DDevice9);
var
weakRef_Direct3DDevice9: IDirect3DDevice9;
block: IDirect3DStateBlock9;
P: TPoint;
Minimised: Boolean;
begin
Minimised := False;
weakRef_Direct3DDevice9 := IDirect3DDevice9(ptr_Direct3DDevice9);

if (SmartGlobal^.Version >= $08010000) then
begin
dxReadPixels(weakRef_Direct3DDevice9, SmartGlobal^.img, Minimised, SmartGlobal^.width, SmartGlobal^.height);
weakRef_Direct3DDevice9.CreateStateBlock(D3DSBT_ALL, block);
block.Capture();

weakRef_Direct3DDevice9.SetRenderState(D3DRS_LIGHTING, D3DZB_FALSE);
weakRef_Direct3DDevice9.SetRenderState(D3DRS_FOGENABLE, D3DZB_FALSE);
weakRef_Direct3DDevice9.SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
weakRef_Direct3DDevice9.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
weakRef_Direct3DDevice9.SetRenderState(D3DRS_ALPHABLENDENABLE, D3DZB_FALSE); //DISABLED 2014-02-28..
weakRef_Direct3DDevice9.SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
weakRef_Direct3DDevice9.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
weakRef_Direct3DDevice9.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

if (SmartDebugEnabled and (Not Minimised)) then
BltSmartBuffer(weakRef_Direct3DDevice9);

P.X := -1; P.Y := -1;
SmartGlobal^.getMousePos(P.X, P.Y);

weakRef_Direct3DDevice9.SetTexture(0, nil);
weakRef_Direct3DDevice9.SetPixelShader(nil);
weakRef_Direct3DDevice9.SetVertexShader(nil);

DrawMouse(weakRef_Direct3DDevice9, P);

block.Apply();
block._Release();
end;
end;




It doesn't flicker using the above. Sorry for taking long to code it.. My pascal is rusty and translating from C is hard for me (takes time) ={

I had to change the const sized array to a dynamic array and that took ages to figure out why it was crashing..

Apparently I had to do:


Device.DrawPrimitiveUP(D3DPT_LINESTRIP, Length(Vertices) - 2, Vertices[0], sizeof(D3DVertex));

instead of:


Device.DrawPrimitiveUP(D3DPT_LINESTRIP, Length(Vertices) - 2, @Vertices[0], sizeof(D3DVertex));

Somehow Vertices[0] is the address of the contiguous block of memory in pascal. But in C, Ptr[0] is NOT the same shit! That's the first element. Not the address of it.

Took me ages to figure out wth was wrong with PS..

Anyway, the reason your thing was flickering was because there is an instance where the vertices overlap OR aren't drawn (your for-loop)! Graphics cards do NOT play nice with that.

To overcome such a thing, you can use a vertex buffer with an index list (already discussed in a previous post).
However, since its something simple, I decided to use DrawPrimitiveUP and specify a D3DPT_LINESTRIP. This will connect vertices in sequential order.


Example, given points: A, B, C, D, E, F.

D3DPT_LINELIST will draw it as follows:

A->B
C->D
E->F

Notice that they aren't connected. And so in order to connect them, you need to specify the same vertex twice!

However, D3DPT_LINESTRIP will draw it as follows:

A->B
B->C
C->D
E->F

in one call. Thus you have one single smooth line all the way and less vertices to draw. Even better with a const array but that's for another time.

Also, you had DrawPrimitiveUP in a loop and so it was making a call to the graphics card every single time. It is POSSIBLE that it has to sync the CPU with the GFX and thus crawl to a slow snail speed.

TLDR:


Draw all vertices in a single call to the gfx. OR use a vertex buffer stream + index buffer.

Olly

2014-08-17 23:54:19

From: Brandon
…


Mhm makes alot more sense now! (How inefficient my code was)

Thanks!