It is currently Tue Aug 22, 2017 3:38 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Sat Aug 15, 2009 4:56 am 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 957
Location: Pennsylvania, USA
A technique I have been using to determine how many cycles I have "left" in my main game loop is to program a nested loop with x and y, and make it long enough that it slows down my frame rate, then decreasing it gradually until the framerate is normal again. Here is my loop with some hardcoded values:

Code:
;the following loops are used to measure how much time we have left in the main loop.
  ldy #17      ;2
:
  ldx #$ff      ;2
:
  dex           ;2 * 255
  bne :-         ;3 * 254 (taken) + 2 (not taken)
 
  dey           ;2 * 17
  bne :--        ;3 * 16 (taken) + 2 (not taken)


Then the actual # of cycles this would take would be:

xLoopCycles = 2 + 2*255 + 3*254 + 2 = 1276
y loop cycles = 17 * xLoopCycles + 2 + 2*17 + 3*16 + 2

total: 21778

Does this look right? I guess there's a possibility my branches are crossing a page boundary---how would I determine if this is the case? I suppose looking at a listing of my code?


Last edited by GradualGames on Sat Oct 17, 2009 2:59 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 15, 2009 7:14 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3913
You could use an .org directive to force your delay loop to start at a page aligned boundary. I know in TASM, the syntax is " .org ($ + $FF) & $FF00" to move the origin ahead to the next 256 byte page. Or you could put it at the beginning.

Of course, there's also the alternative: Turn on Monochrome or Color Emphasis and count the number of remaining scanlines.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 15, 2009 5:13 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9910
Location: Rio de Janeiro - Brazil
Dwedit wrote:
Turn on Monochrome or Color Emphasis and count the number of remaining scanlines.

That's what I usually do. I Print Screen, paste it in MS Paint, use the selection tool to count the scanlines and multiply by 341 then divide by 3 in order to know how many cycles I have left.

I'm hardly interested in an exact number though, I mostly use the monochrome bit to time individual tasks and optimize them as much as possible.


Top
 Profile  
 
PostPosted: Sat Oct 17, 2009 3:01 pm 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 957
Location: Pennsylvania, USA
tokumaru wrote:
Dwedit wrote:
Turn on Monochrome or Color Emphasis and count the number of remaining scanlines.

That's what I usually do. I Print Screen, paste it in MS Paint, use the selection tool to count the scanlines and multiply by 341 then divide by 3 in order to know how many cycles I have left.

I'm hardly interested in an exact number though, I mostly use the monochrome bit to time individual tasks and optimize them as much as possible.


I finally got around to using the monochrome bit trick to measure my CPU usage during a frame. It works great on Nestopia, Nintendulator, and FCEUXDSP. But it seems to choke JNes a little bit and cause it to stutter. This doesn't worry me too much since I know JNes to be a bit inaccurate compared to others, but I wondered if anyone else has experienced that. The trick reveals I'm using about a third of my available time during a frame, so I don't think it would be a difference in execution time between emulators.


Top
 Profile  
 
PostPosted: Thu Jun 29, 2017 1:08 am 
Offline
User avatar

Joined: Wed Jun 21, 2017 1:51 pm
Posts: 19
I have to try this out tonight! I miss the CPU meter that I relied upon in BGB for Gameboy Development so any way to visualise it is great!


Top
 Profile  
 
PostPosted: Mon Jul 03, 2017 5:49 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 339
I use the grayscale bit, it gives me an idea. It's also good for noticing that there's a rogue over-busy frame (my scrollers in C are "multiplexed" across several frames and this helps me balance the load better).

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Tue Jul 04, 2017 8:42 pm 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 181
FCEUX's debugger shows the cycles elapsed between breakpoints. This is what I used to make my constant-cycle music engine.

The greyscale trick is useful, too.


Top
 Profile  
 
PostPosted: Fri Jul 07, 2017 12:47 pm 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 957
Location: Pennsylvania, USA
Not every day one finds a post from 8 years ago bumped, lol. I'm still using the monochrome bit trick even today ;)


Top
 Profile  
 
PostPosted: Fri Jul 07, 2017 12:49 pm 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 957
Location: Pennsylvania, USA
na_th_an wrote:
I use the grayscale bit, it gives me an idea. It's also good for noticing that there's a rogue over-busy frame (my scrollers in C are "multiplexed" across several frames and this helps me balance the load better).


Do you mean you update entities/objects on one frame and update the scrolling on another frame or something else? So far I do everything every frame...I still code in 6502 though...I can't believe you and others are making games in C. I tried it for a few months and...it's really not for me, holy cow. Lol. I think it takes me more time to work through issues from C than just coding in 6502. That's not in any way a slam on C, I'm just impressed anybody does it is all!


Top
 Profile  
 
PostPosted: Mon Jul 10, 2017 2:07 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 339
It's more splitting the scrolling routine across several frames.

For example, I have a side scrolling game which uses 32x32 metatiles. The scrolling area is 6 metatiles high. The scrolling routine is the split accross four frames: first frame I decode the map data to a buffer, extracting the 6 metatile indexes, reading the attribute bytes from a LUT indexed by metatile index, and putting them into VRAM. frames 2, 3 and 4 I draw two metatiles each. This means that once a new backdround column is needed, the engine takes 4 frames to draw it.

Doing it that way, the routine is so light that I can place it before the sprite 0 hit I use for the screen split. As scrolling speed is never > 8 (not even > 4) pixels per frame, and I'm using vertical mirroring, by the time the new column enters the screen and is visible it is 100% drawn.

Depending on the game, the scrolling direction(s), the metatile size, etc. I use several approaches but, in the end, I always split the action accross several frames. Time is tight. I could do all the scrolling in 1 frame, but that frame would have a sudden CPU peak.

As for developing in C, I guess it has to do with your mindset or maybe with what you are used to. You can get pretty low level in C, which is also a plus, and you can always rewrite a couple of routines in assembly if you need :) My games are not very complex. At the end of the day, it is whatever floats your boat, or whatever makes the experience more enjoyable for you :)

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Mon Jul 10, 2017 11:40 am 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 957
Location: Pennsylvania, USA
na_th_an wrote:
It's more splitting the scrolling routine across several frames.

For example, I have a side scrolling game which uses 32x32 metatiles. The scrolling area is 6 metatiles high. The scrolling routine is the split accross four frames: first frame I decode the map data to a buffer, extracting the 6 metatile indexes, reading the attribute bytes from a LUT indexed by metatile index, and putting them into VRAM. frames 2, 3 and 4 I draw two metatiles each. This means that once a new backdround column is needed, the engine takes 4 frames to draw it.

Doing it that way, the routine is so light that I can place it before the sprite 0 hit I use for the screen split. As scrolling speed is never > 8 (not even > 4) pixels per frame, and I'm using vertical mirroring, by the time the new column enters the screen and is visible it is 100% drawn.

Depending on the game, the scrolling direction(s), the metatile size, etc. I use several approaches but, in the end, I always split the action accross several frames. Time is tight. I could do all the scrolling in 1 frame, but that frame would have a sudden CPU peak.

As for developing in C, I guess it has to do with your mindset or maybe with what you are used to. You can get pretty low level in C, which is also a plus, and you can always rewrite a couple of routines in assembly if you need :) My games are not very complex. At the end of the day, it is whatever floats your boat, or whatever makes the experience more enjoyable for you :)


That's actually a really neat idea of spreading out the processing, since you'd only need it every 8 pixels or so. I suppose if one allows the scrolling speed to increase beyond a certain amount suddenly you'd have to do all the calculations once per frame anyway though.

What if you reverse directions suddenly though? Does your engine "hurry up" and do all the calculation needed for a column all in one frame, if required?

Funny thing about me and C on NES is, I love high level languages, love coding in them. But on NES, C just feels way too bloated and slow. I'm sure I'm ultimately wrong though, I mean there are plenty of great games being made in it! I just don't have the desire to get used to it I guess. I have a set of macros that get me past the most repetitive/confusing aspects of daily 6502 coding.


Top
 Profile  
 
PostPosted: Wed Jul 12, 2017 2:32 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 339
For two way horizontal scrollers, I take advantage in the fact that the "virtual" screen, when using vertical mirroring, is so wide (twice as big as the visible area). On initialization, I draw well past the boundaries of the viewport, at least two extra columns left and two extra columns right.

My game "Cheril the Goddess" draws 32 pixel wide columns, split across several frames. It draws new data to the left or right of the viewport depending on the direction of the scrolling. When the player switches direction, the column being currently updated is abandoned as it is, and the scroller begins rendering the new column. As the drawing happens well far ahead the viewport boundaries, there's no visible glitches. By the time a column has to enter the visible screen, it is always completely rendered.

If you watch the nametables in fceux you can see this in action.

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Wed Jul 12, 2017 10:27 am 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 957
Location: Pennsylvania, USA
na_th_an wrote:
For two way horizontal scrollers, I take advantage in the fact that the "virtual" screen, when using vertical mirroring, is so wide (twice as big as the visible area). On initialization, I draw well past the boundaries of the viewport, at least two extra columns left and two extra columns right.

My game "Cheril the Goddess" draws 32 pixel wide columns, split across several frames. It draws new data to the left or right of the viewport depending on the direction of the scrolling. When the player switches direction, the column being currently updated is abandoned as it is, and the scroller begins rendering the new column. As the drawing happens well far ahead the viewport boundaries, there's no visible glitches. By the time a column has to enter the visible screen, it is always completely rendered.

If you watch the nametables in fceux you can see this in action.


Neat idea...are all of your column decode routines still in C? Man, this is such a cool idea to draw far past the edge of the screen, that way you could maybe even turn a column decoder into a coroutine and arbitrarily pause the operation when it's *just* fast enough to beat the scrolling speed, or something. Not sure if I'm going to bother adding that complexity to my own engine but its fun to think about.


Top
 Profile  
 
PostPosted: Wed Jul 12, 2017 10:45 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9910
Location: Rio de Janeiro - Brazil
Doesn't sound so different from the technique discussed here, which is very similar to how many Capcom NES games handled scrolling.


Top
 Profile  
 
PostPosted: Wed Jul 12, 2017 11:28 pm 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 339
Gosh, it seems that I reinvented the wheel once again :D :lol: :lol:

_________________
http://www.mojontwins.com


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group