I've been trying to speed up my GDI library - I have no problem adding more than one to the bitmap x/y position to make it appear to move faster - yet there is a jerkiness as it moves across the screen.

I know windows doesn't want you to vsync with anything.. so I'm going down my options available:

1) Totally remove multithreading.. how so, get rid of my WndProc() and make a simple loop - manually check for input and the like?

2) Can I invoke a DOS screen under windows, have access to things like bitblt and be able to use vsync?

3) Change my HeapAlloc to VirtAlloc or GlobalAlloc - something that is not threaded but rather contiguous..

Thanks fer yer support.
Posted on 2004-09-23 09:40:18 by drarem
I had a response from the gamedev.net forum on how to better organize my render loop, which sounds promising.. render everything once instead of calling the render function for every layer.


Pseudocode:
for y=0 to mapheight
for x=0 to mapheight
drawlayer layer0,x,y,c
drawlayer layer1,x,y,c
if SpritesInTile(x,y)
drawsprite player,x,y,c
endif
drawlayer roof,x,y,c
next
next

To interpolate the sprite, do 9 tiles at a time and see if sprite is in boundary.. that is where the collision codes can come from too, to see what all tiles it is colliding with.

Any thoughts on this method, would it be any faster? To me it would seem so, we are cutting 3 render loops down to 1. I also think it would eliminate the tearing, the tiles aren't moving only the sprites are.

Does anyone want to help me with this, I want to make a few simple games.
Posted on 2004-09-24 13:14:18 by drarem
Ok here it is, with the sprite rendered in with the same rendering loop, on this pc however it seems to not be so smooth - on this same pc under dx7 using C++ (ewwww), this sprite would go bye-bye - in other words, i would wet my pants due to it's smoothness, hope i'm not too crude.

My question is, is this the right idea? And how does it look on your PC, moving 8 pixels at a time and does it look not so smooth?

I have it in a 5ms loop, should be same on different machines.

http://drarem.ms11.net/sq_prealpha.zip


Size (including two bitmaps): 204k

The cursor keys move my bouncing hovercar around and space makes it come to a stop. Basic collision detection.

here is my render loop (which uses PtInRect, very handy :)



DrawMap5 proc sprno:DWORD, nmapptr:DWORD
LOCAL e:DWORD,f:DWORD
LOCAL lpRect:RECT
LOCAL lPT:POINT

mov e,0
mov f,0

LT600:
mov e,0
LT800:
mov eax, [nmapptr]
mov ecx, DWORD PTR [eax]
cmp ecx,0
je @F
invoke Sprite,sprno,e,f,ecx ;draw floor tile
@@:
mov ebx,e
sub ebx,64
mov lpRect.left,ebx
mov ebx,f
sub ebx,64
mov lpRect.top,ebx
mov ebx,e
add ebx,64
mov lpRect.right,ebx
mov ebx,f
add ebx,64
mov lpRect.bottom,ebx

invoke PtInRect, addr lpRect, px,py
cmp eax,0
jz @F
invoke Sprite2,2,px,py,0 ;draw sprite if in bounds
@@:
add nmapptr,dword
mov eax,WND.tilex
add e,eax
mov ebx,WND.mapx
cmp e,ebx
jl LT800
mov eax,WND.tiley
add f,eax
mov ebx,WND.mapy
cmp f,ebx
jl LT600
ret

DrawMap5 endp
Posted on 2004-09-24 15:40:30 by drarem
It looks OK on my system (2GHz P4 512MB Ram).
Moves look smooth. Good work !
Posted on 2004-09-24 21:44:17 by anon
Thanks for checking it out, I have a P4 3.0Ghz with hyperthreading, and the object seems to jitter as it moves back and forth across the screen, it isn't smooth for me.. like the screen refresh and the timing isn't synced.

maybe due to my gf4 mx 440 card, or i tried downloading the latest windows update then uninstalled (too many scary changes in the update), or downloaded the latest directx 9.0c (don't know why that would affect it)..
Posted on 2004-09-25 07:19:34 by drarem
Which OS are you running? If not XP, disable HT in your BIOS...
Posted on 2004-09-25 07:22:56 by f0dder
I am running XP home, oops I tried disabling HT anyway, no change.. I dropped resolution down to 1024x768x32 then x16 and monitor refresh to 85Hz, still when the object moves from left to right to left and i follow it with my eyes, i notice the movement isn't smooth to me. Hope I am explaining it right.

I tried it on another XP machine that did the SP2 updates already, still doesn't look smooth - when I follow with my eyes I notice it jitters moving at 8 pixel increments - two years ago when I was playing with DX7 and dev-c++, the same object although moving that fast would appear very smooth and kind of leaving a 'trail' on a black screen.

Not sure if I am doing something wrong or GDI has issues.
Posted on 2004-09-25 13:16:38 by drarem
Tested on Win98 SE.

I'm not sure this is what was supposed to be shown... at least I can't see most of the tiles in MCHIP3.BMP :? I'm attaching a screen capture just in case. Also, the size of the window seems to be wrong.

What's probably more relevant :) is that the animation was running smoothly, but the program uses 100% of the CPU so the GUI becomes unresponsive (I had to shut it down using Ctrl-Alt-Del). The "player" sprite seems to move by itself, or at least keyboard input seems to have no effect at all. :(

Another strange thing: when I hit the "Print Screen" key, the sprite was bouncing against a wall; but in the picture it's shown way far from it! This is probably explained too by the 100% CPU usage, but I though you'd want to know.
Posted on 2004-09-27 19:31:29 by QvasiModo
Afternoon, drarem.

What are you using for timing?

Cheers,
Scronty
Posted on 2004-09-27 20:28:50 by Scronty
QvasiModo: for Win98SE, the messaging must not work in the same way, I have a peekmessage in a loop as such (should answer your question too, Scronty).. the screen looks ok, maybe that is what happened with the PrintScreen key too, some sort of lag in the messaging.




.while !( bQuit )
invoke PeekMessage, addr msg, NULL, 0, 0, PM_REMOVE
.if ( eax )
mov eax, msg.message
.if ( msg.message == WM_QUIT )
mov bQuit, TRUE
.endif
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endif

invoke main ;main game loop
invoke GetTickCount ;get count
mov start_tick,eax ;store it
timeita:
invoke GetTickCount ;get next count
sub eax,start_tick ;subtract from first count
cmp eax,GAME_SPEED ;compare to EQU 5
jl timeita ;if less than that then loop
invoke flip ;copy backbuffer to front
Posted on 2004-09-28 14:02:55 by drarem
Maybe you could lower the priority for the main thread under Win9X? That might help... :)
Posted on 2004-09-28 16:36:12 by QvasiModo
You could add a very small Sleep to the message pump - and it's a good idea to check if you app has lost focus, and do a larger Sleep if it has.
Posted on 2004-09-28 16:41:50 by f0dder
I'd rather use a timer and MsgWaitForMultipleObjects.
Posted on 2004-09-29 01:12:37 by Sephiroth3
Good idea, Sephiroth. It's still "polite" to check for focus and Sleep if you've lost it, though :)
Posted on 2004-09-29 02:25:59 by f0dder
How about a thread as in this example:

http://www.gamedev.net/reference/articles/article1249.asp
Posted on 2004-09-30 07:00:59 by drarem
I did away with the timer and it runs blazingly fast on my super home machine, so fast it's almost impractical :)

Ok I reduced the pixel movement from 8 to 2 and now there is no lag and moving as fast as with timer - prognosis: the timer itself was introducing the lag by counting/looping. This is confusing.
Posted on 2004-09-30 07:12:06 by drarem
Afternoon, drarem.

This is confusing.


Not so confusing...

Movement is based on time. An object moves a certain distance over a certain time.

This means that, if you want an object to move across the screen at 700 pixels/second (i.e. you want the ball-thingy to move across the width of the map in one second), then you set your Velocity at 700.
Next you get the actual elapsed time and multiply the Velocity by that time.
Use the calculated value for updating the objects' movement.

You can use QueryPerformanceCounter to get the current count from the High-Resolution Timer and divide it by QueryPerformanceFrequency to get the Elapsed Time in seconds.

Cheers,
Scronty
Posted on 2004-09-30 08:07:15 by Scronty
I hate to drag this out, but I have to know.

Scronty, so you're saying it's pixel movement values may change then?
Instead of adding 4, it would depend on the velocity and the actual time? Sorry I'm no good at 'math' questions lol how does it look:

v=700
deltaTime=n <=== time elapse between when, when I check for messages and then flip the screen, or call the main game loop and then flip, or before and after flip?

increment sprite x = v*deltaTime
increment sprite y = v*deltaTime

Wouldn't the call to QueryPerformanceCounter and the division process be slower than what is returned from the actual time and cause lag? Your explanation does make senses to me however.

And one last time, when I say lag, I mean the object is 48 x 48 pixels, it moves 3/4s of it's width (or height, or both) across the screen smoothly, then looks like it jumps a few pixels. Kind of like a bad horror movie where they speed up the zombies so you can't really get a good look at them (but not that bad) :) This jump is there when I call my timer or using sleep 1ms+.. when I remove it, it runs smooth and fast. Another thing, I think ms is too slow?

So much to do, so little time.
Posted on 2004-10-01 17:10:24 by drarem
attached is an updated .exe ( you will need the same bitmaps) - no timer and ball moves 2 pixels per frame.
Posted on 2004-10-01 17:15:33 by drarem