Author Topic: TinyPTC and FPS  (Read 10907 times)

0 Members and 1 Guest are viewing this topic.

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
TinyPTC and FPS
« on: February 08, 2012 »
So I've been messing with some more code using TinyPTC++, and with much thanks to Raizor, the variable width scroller is now working as intended.

When blitting my scroller to screen and vsync on, its a constant 60fps. But since I've added in a 800x600 res background graphic that blits to screen in replacement of 'ERASE BUFFER', the fps slows to ~50fps.

My question is...

Is there a way to blit a full screen image using a faster technique in order to keep the screen synced to the refresh rate of the monitor?

Fullscreen mode is 800x600, my background image is also this size. Scroller only at 60fps, nice and smooth, add in the background image and its 50fps and not smooth. :/

Attached is a couple of screen shots 'so far'

*note.. 100% of the graphics I drew from scratch.

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: TinyPTC and FPS
« Reply #1 on: February 08, 2012 »
You could use memcpy, it's part of crt.bi I think so you'd just need to include crt.bi and then use memcpy to copy from one buffer to another.  That's going to be one of the quickest and simplest ways of doing it.

Also if you're not drawing over the whole screen you could just erase and update the parts that are moving.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: TinyPTC and FPS
« Reply #2 on: February 08, 2012 »
@Shockwave, ok thanks, I'll google around and have a read.

For every two steps forward I seem to take one step backwards. I'm slowly learning though, and I'ts a lot more involved than I thought.

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: TinyPTC and FPS
« Reply #3 on: February 08, 2012 »
You should be able to find at least half a dozen examples of memcpy on this forum if you use the search box.  I'd post the links but I'm using my phone to post sorry.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: TinyPTC and FPS
« Reply #4 on: February 09, 2012 »
Yeh, I did search on here and did find a few examples... but yet again I'm stuck. I'll figure it out in time I guess. Not real sure how to set it all up just yet. Feeling absolute 'meh' too due to illness doesn't help my cause either.

I think I really need to sit down and study tiny_ptc.bi, windows.bi, crt.bi etc to actually get to grips with understanding what they all do first and the functions, as all these pointers and memory swapping tends to get me lost very quick at the moment.

Although in the hunt for things, I noticed that I can use
Code: [Select]
MEMSET(@BUFFER(0),0,XRES*YRES*4)to clear the screen from crt.bi, so I will be able to use screen coordinates to only clear the part of the screen which is moving if needed.

Thanks again guys.

*EDIT...

So I've messed around with memset (haven't touched memcpy yet), and I've 'sorta got' a solution, it's not entirely what I wanted, but it did speed up the fps from ~41fps to ~180fps (fullscreen mode was vsynced to 60fps).

What I did was put my...
Code: [Select]
BGDRAWIMAGEDATA(0,0)outside of the loop (before the "do"), then inside the loop, I changed...
Code: [Select]
ERASE BUFFERto
Code: [Select]
MEMSET(@BUFFER(800*390),&h808080,800*840)which works, but again, not entirely what I wanted, as it chops out the bottom part of the background, and just replaces it with the colour RGB(80,80,80).

A screen shot is attached to show the overall screen after the memset changes.

More learning to follow..... :)
« Last Edit: February 09, 2012 by ttemper »

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: TinyPTC and FPS
« Reply #5 on: February 10, 2012 »
Quote
which works, but again, not entirely what I wanted, as it chops out the bottom part of the background, and just replaces it with the colour RGB(80,80,80).

Yep, you need to take that chunk of the screen, keep it stored somewhere and use memcpy to put it back each frame and thereby clearing that part, you're making good progress though.  If you get really stuck, post your code and we'll take a look at it :)
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: TinyPTC and FPS
« Reply #6 on: February 11, 2012 »
Something like

do this once
Code: [Select]
store = MALLOC(XRES*YRES*4)
Then you can put anything in there, including a copy of the screen
Code: [Select]
MEMCPY(store,@BUFFER(0),XRES*YRES*4)
or you could plot rgb pixels or load a bmp

Then you can copy it back whenever you like
Code: [Select]
MEMCPY(@BUFFER(0),store,XRES*YRES*4)

That will work for the whole screen.  For rectangles you need to do a for loop over each scanline and memcpy in just the bits you want.

Jim

Challenge Trophies Won:

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: TinyPTC and FPS
« Reply #7 on: February 11, 2012 »
Thanks for the input guys, I'll test out the code soon and see how I go. Weekend and all here.. ;P

I think once I understand how to read the memory (memcpy) and how to store it via a pointer/variable, then copy it back when I need it, it will make things a fair lot easier on me.

As for the partial screen refreshing via a scanline loop for memcpy, it seems simple enough I guess. But knowing me, I will have problems :P hehe.

Something like this?...

Code: [Select]
Dim SCANLINEX as UINTEGER

For SCANLINEX=400 to YRES-100
     'some memcpy command in here to re-blit whats stored in memory?
     memcpy....? etc etc
Next

So if my screen res is 800x600, then it would only refresh scanlines 400-500 of the screen right?

More learning :P

*EDIT.

Well I had a quick play with memcpy as you suggested Jim... and again much thanks...

I removed the line...
Code: [Select]
MEMSET(@BUFFER(800*390),&h808080,800*840)and replaced it with...
Code: [Select]
MEMCPY(@BUFFER(0),STORE,XRES*YRES*4)
I then added before my loop, just after the drawing of the background to this...

Code: [Select]
BGDRAWIMAGEDATA(0,0)
STORE = MALLOC(XRES*YRES*4)
MEMCPY(STORE,@BUFFER(0),XRES*YRES*4)

And well..... thats exactly what my intentions were. Much thanks guys. It now has the proper background at full 800x600 res and the scroller is nice and smooth.

Windowed screen is now ~120fps, which is a big difference from the ~41fps I was originally getting.

Fullscreen mode is now nice and vsync'ed to 60fps and without vsync is... ~160fps, but its all jerky/split screen updates, so I'll stick to have it fullscreen and vsync'ed.

I'm slowly understanding how to throw things into memory and then retrieve them when needed. Lots more to read + learn.

I wouldn't mind attempting this with a bitmap font also... e.g before the loop starts, cut the font up into the required X by Y chunks for each character, and store each letter as itself into memory as such, then instead of re reading from the loop each time, just pull it from memory.... I'll attempt that later I think. :)

*EDIT..

a question....

If I were to turn off vsync and use delta timing... is there a command that I can use to read in the current refresh rate of the users screen? so I can use that number against my delta timing, so not just the scroller is smooth, but the entire demo (If I were to add in other effects, etc)

eg.. if my delta timing is at...
Code: [Select]
DV=(TIMER-OLDTIME)*250What I'd like to do is get the current refresh rate of the screen... lets say its 60hz..... so that'd be 60/250 = .24, so I could then infact set my scroller to that speed with...
Code: [Select]
DOSCROLLER(.24)I just tested my theory... and it works, but vsync is much much nicer tho... again, just a thought :)

« Last Edit: February 11, 2012 by ttemper »

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: TinyPTC and FPS
« Reply #8 on: February 11, 2012 »
You could do something like this to get the fps

Code: [Select]


function get_framerate()as double
    dim as double average,test_count=30
    screensync
    average=timer
    for i as integer=1 to test_count
        screensync
    next
    average=timer-average
    return test_count/average
end function


sub main
    screenres 640,480,32,2
    dim as double fps=get_framerate()
   
    print fps
   
end sub

main
sleep

It works but maybe there's other ways too.

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: TinyPTC and FPS
« Reply #9 on: February 12, 2012 »
@Stonemonkey, thanks, I did try that code... and well it gives me some huge numbers that I'm not sure what to do with....

Using TinyPTC_EXT++, if I enable...
Code: [Select]
PTC_SETFLIP(1)and push it to fullscreen, then it runs vsync'ed. But if I push it to windowed mode, vsync isn't enabled, it runs at ~100fps, and the scroller looks jerky.

Not sure how you guys vsync fullscreen and windowed mode if there's a screen choice upon executing the demo.

Attached is a screen shot of that fps function and the huge numbers.

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: TinyPTC and FPS
« Reply #10 on: February 12, 2012 »
Ah ok, sorry.  I meant it only to be run once at the start of code to get the framerate. Also you'd need to change the screensync calls to whatever the equivalent is in tinyptc or use screenflipping with vsync on to measure it.

Other than that I'm not sure what you mean, using the time difference between frames the way you described will give the rate that your program is updating the display. Although I think the accuracy of the FB timer might be slightly off, there might be something in windows that's better.

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: TinyPTC and FPS
« Reply #11 on: February 13, 2012 »
No need to be sorry dude, I appreciate the help.

Since messing with TinyPTC and vsync... I can't seem to get vsync to work in windowed mode... fullscreen sure, by the use of PTC_SetFlip(1), but I also want to use delta timing, so it's the same speed no matter what PC it runs on. So the delta timer will NULL the vsync then right?

Meh... bit lost again, I tried for a while to get it all to work, idk what I'm doing wrong. Ive seen some of the RetroRemakes, and those vsync in fullscreen and windowed... I also noticed that even if I turn of vsync, the FPS still adjusts to my screen refresh rate anyway...? not sure if that's suppose to be like that or not. I'm sure there's a routine to enforce the FPS to match the refresh rate of the screen.

On another note, I did redo that code you posted Stonemonkey. It works well, but it calculates the FPS before anything it blitted to screen, so the FPS was a whopping ~340FPS, yet, when the screen started moving and refreshing, it dropped to ~90fps. Not sure if I should still base my FPS upon the initial FPS calculation or not...

for example... if my calculation of FPS = 340
Code: [Select]
DV=(TIMER-OLDTIME)*FPSbut that would change the delta time on every PC it ran on right?

I just want to be able to get the refresh rate of the PC, whether it was set to 60hz, 75hz, 59hz, whatever, and be able to sync my refreshes to that, so it's nice and smooth ( although using tinyptc_ext I did notice tearing  :vangry: ).

Can't win at the moment.  :telloff:

Using delta timing and vsync together is what I'm trying to achieve... so I get a nice flowing/speed demo with a nice refresh rate to match. I don't want to see tearing... it's ugly (like my congratz demo).

1. Set static (or variable) delta timing
2. Set vsync to match refresh rate of monitor.
3. Display the screen and run.

Again, any insight/help is much appreciated.

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: TinyPTC and FPS
« Reply #12 on: February 13, 2012 »
The function I posted will give the current refresh rate to use for a static delta value but that's only of use with vsync on and if you know for sure that you can draw everything fast enough that it can be drawn within 1 frame.

If you can't be sure of drawing everything fast enough then you'll have to work out the delta for each frame whether you have vsync on or off.

I usually use a very simple form of delta timing and it's not always all that smooth but it does have it's advantages.
Code: [Select]
sub main

 'demo setup code

 dim as double t=timer
'demo loop
 while inkey$=""

  while t<timer
   t+=1.0/120.0  'increments of 120th sec (can be changed to suit purpose)

   'do update of movement variables for 1/120th sec framerate

   'do as little as you can get away with inside this loop
   'do not draw inside this loop
   'anything that takes too long (as in >1/120th sec) will mean t will
   'never catch up with timer and the program will freeze

  wend

  'clear screen
  'do drawing stuff
  'flip

 wend
end sub

While the drawing and updating of the display can be at any rate, the control loop is always repeated at 120X per sec.

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: TinyPTC and FPS
« Reply #13 on: February 14, 2012 »
Thanks Stonemonkey. :)

We'll after some more looking around... I found that I can simply use...

Code: [Select]
Dim w As Integer, h As Integer
Dim depth As INTEGER
Dim REFRESHRATE As INTEGER
Dim driver_name As String
SCREENINFO w, h, depth,,,REFRESHRATE,driver_name

So, variable REFRESHRATE holds the screen hz, which is what the first step that I wanted to do. Simple enough...

Now I have implemented another loop...

Code: [Select]
QueryPerformanceCounter(@cTimer2)
IF(cTimer2.QuadPart >= cTimer1.QuadPart + Interval) THEN
QueryPerformanceCounter(@cTimer1)
FPS_COUNT()
CLS
PRINT "CURRENT FPS: " & iFPS
ENDIF

That throws to a subroutine...
Code: [Select]
Sub FPS_Count()
         If bSettime = 1 then
          iSecStart = Timer() * 1000.0
          iFrameStart = iFrameCount
          bSettime = 0
     EndIf 
     If (Timer()*1000.0) >= iSecStart + 1000 then
          iFPS = iFrameCount - iFrameStart
          bSettime = 1
     EndIf
     iFrameCount = iFrameCount + 1     
End SUB

Which is getting close to my vsync for windowed mode... yet it differs  ::) . My refresh rate is currently 75Hz, and upon running the demo as it is at the moment, the FPS starts off faster, then once it gets moving... it fluctuates from 74-78FPS, which isn't what I'm wanting, as it tears like crazy and looks so damn horrible...  :telloff: Once it hits 75FPS, its smooth as, but then it fluctuates again and tears... *sigh*

At least I'm getting closer to what I want to achieve, yet I feel I'm so far away still.. Not quite sure how to force the FPS to match the Hz refresh rate just yet... at a solid 75FPS, not fluctuating like it is. Damn timers!

I'll try again tomorrow sometime and hope I get progress.

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: TinyPTC and FPS
« Reply #14 on: February 14, 2012 »
Cool, never noticed you could get the refresh rate from screeninfo before.

Have to admit I don't really know what it is you're trying to do though.

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: TinyPTC and FPS
« Reply #15 on: February 15, 2012 »
Sorry...

What I'm trying to do is get vsync working in windowed mode. That's it. Whether it be using delta timing, vsync or a fps lock to match the screen Hz. Or all 3 together.

When using delta timing, Its all smooth in fullscreen mode with PTC_FLIP(1) enabled, it vsync's perfectly. No tearing at all.

When using windowed mode, the vsync doesn't work at all. No idea why, as PTC_FLIP(1) is still enabled for that window. So what I want to do is make sure (either by a FPS limiter/locker or vsync) that it 100% matches the refresh rate on each and every refresh (else it tears the hell out of the refreshes and looks yuck).

Some of the RetroRemakes that I've checked out have a vsync switch, although whether its on or off, it still seems to lock refreshes to my screen hz (that being 75hz at the moment) which makes it nice and smooth.

The way I have it at the moment, windowed mode is close to what I want to achieve (the 75fps to match my 75Hz refresh), yet each loop seems to differ in timing, causing the FPS lock move between 74 and 78fps, which when it is not on 75fps, it tears like crazy and looks crap.

Hope I made more sense of it all.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: TinyPTC and FPS
« Reply #16 on: February 15, 2012 »
To all intents and purposes you cannot do that with timers, they are not accurate enough, and even if you had a really accurate one Windows is multithreaded and something else could eat a large timeslice (download completing, for instance) and you will miss.  If vsync isn't working for windowed mode the best you can do is double buffer (make sure you are rendering off-screen somewhere) and blit the whole frame in one go.  Sometimes it will tear, depending when Windows actually does the blit.

Jim
Challenge Trophies Won:

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: TinyPTC and FPS
« Reply #17 on: February 15, 2012 »
@Jim... ok thanks. Good to know. I've got the timing 'close' in windowed mode, but like I said, it differs slightly which causes the tearing.

Is there a way to lock the FPS to match the Refresh Rate (Hz) of the screen in windowed mode? Eg. My screen is setup to 75Hz, so I want to bind it to 75fps max.

Fullscreen mode is not a problem as PTC_SETFLIP(1) works as intended to vsync.

Is this even possible with TINYPTC in windowed mode?


*EDIT..

I just swapped out the tinyptc routines for the ones that you did in OpenGL Jim (found them on here)... and well that solves my problem with the vsync for windowed mode right there! Ran the demo, it went fullscreen, I then pressed ALT+ENTER to drop it back to windowed mode.... and its vsync'ed!

Really confused on what base/framework I should be using now to set up demo's.

To be completely honest, I think there's an issue with my DirectDraw layer, as it tears really bad, not just in demos, but when using DirectDraw for video editing/playback also. I have no idea how to 'fix' it.
« Last Edit: February 15, 2012 by ttemper »

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: TinyPTC and FPS
« Reply #18 on: February 15, 2012 »
All the different frameworks have different pluses and minuses.  I prefer an OpenGL based one as immediate mode OpenGL commands add a lot of flexibility to move in to 3D, but the majority wanted the DirectX version of TinyPTC.  The good thing about either of these is that they allow a very thin veneer between a pixel buffer and the visible screen.  That's really useful for pixel pushing demos but not too much else.
Having said  that I'm surprised DX is not vsyncing in a window, it's like it's blitting on the frontbuffer by mistake.  Really, forget trying to sync using a timer.
All my demos are OpenGL based, but that framework has gone way beyond being just frameworky any more :)

Jim
Challenge Trophies Won:

Offline ttemper

  • Amiga 1200
  • ****
  • Posts: 267
  • Karma: 7
    • View Profile
Re: TinyPTC and FPS
« Reply #19 on: February 15, 2012 »
All my demos are OpenGL based, but that framework has gone way beyond being just frameworky any more :)

I bet they have. I'm still in the learning phase... I mean newbie learning phase, as you never stop learning I guess. I think I'm doing 'ok' i guess, with much thanks to everyone here that has helped me.

Since TINPTC_EXT does not work with vsync in windowed mode (no idea why), I think I might use your OpenGL TINYPTC equivilent for the moment. I put it into its own function script and just call it with...
Code: [Select]
#INCLUDE ONCE "tinyptc_jim.bas". Then I setup my screen etc as per normal in my main .bas file. Works nice. I also put all my Delta Timing into a function in another .bas script and call it the same way. I'm slowly learning. :)

Now since I will use the OpenGL base, I want to now incorporate the choice of window or fullscreen on like the original tinyptc. More challenges ;P The 'vsync' on/off switch will be the easy part.

*EDIT...

So I've googled around some more, checked out freebasic.net etc etc... and have managed to get my screens the way I want them.

For fullscreen mode (alt+enter disabled), I did...
Code: [Select]
SCREENRES w,h,32,0,7
For windowed mode (alt+enter disabled), no title bar, no borders, I used...
Code: [Select]
SCREENRES w,h,32,0,6 OR GFX_NO_FRAME Or GFX_ALWAYS_ON_TOP
So both methods work a treat  :updance:

Now for my next step is to mimic the TinyPTC popup menu for fullscreen mode or windowed mode choice. In my thinking, I might trick it up a lil' like the Retro Remakes initial screens, and have a nice setup window pop up, play some small looped music, nice small font, etc etc, turn on/off vsync etc. I'm slowly making progress though.

Thanks again to all!
« Last Edit: February 16, 2012 by ttemper »