Rendering enabled after the end of VBlank x Sprites

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Rendering enabled after the end of VBlank x Sprites
by on (#30075)
As you guy may or may not know, my current project needs more Vblank time than what's normally avaliable, so I decided to keep rendering disabled for a few extra scanlines in order to get a some extra cycles for PPU updates.

Everything is working fine, all the code used in the NMI routine is carefully timed so that all combinations of tasks take the exact same amount of time to complete, so rendering is enabled always at the same point.

However, I noticed that sprites are not displayed on the first rendered scanline. This makes sense, because the PPU needs a whole scanline for sprite evaluation, and since rendering was disabled during the previous scanline, there was no sprite evaluation. When seen on a TV, this effect is barely noticeable, but on emulators it looks a bit weird.

I don't even think I should be worried about such a small glitch, but I kinda am. First, I'd like to ask you guys what would the correct way to fix this be. I'd probably have to enable sprite rendering a whole scanline before enabling background rendering... Would that result in a clean effect?

Now, I'm not even sure I'll try to fix this, because I'm already using 16 scanlines (guys, I have a lot of PPU updates), which is a nice, round number. That is already quite a big chunk of the screen to give up on, so wasting another scanline just to fix that glitch does not seem worth it. I'd do it if I could squeeze my code to finish 15 scanlines in, but it has already been squeezed pretty much all it could be (it originally used 20 extra scanlines), so I doubt I could take another 113 or so cycles out of there.

But just so that I don't miss an opportunity to learn, I'm asking the experts (who know much more about the inner workings of the PPU than I do) if it would be OK to enable sprite rendering one scanline before enabling background rendering to create a clean looking "border" at the top of the screen. Would it?

by on (#30076)
Not to derail your question, but have you already ruled out turning rendering off early instead, near the bottom of the screen?

by on (#30080)
blargg wrote:
Not to derail your question, but have you already ruled out turning rendering off early instead, near the bottom of the screen?

That would involve sprite 0 and setting one background tile to always be opaque, with a visible glitch. Sprite 0 is easy in games that scroll only horizontally, but the worlds in tokumaru's game are much bigger than that.

by on (#30083)
blargg wrote:
Not to derail your question, but have you already ruled out turning rendering off early instead, near the bottom of the screen?

Yes I have. I think that would be the best option too, but this is far too complicated to achive in my situation, as tepples said.

My type of scrolling prevents me from cleanly setting up a sprite 0 hit at the bottom of the screen. Also, I'd probably have to set up a DMC IRQ (as we talked a while ago, remember?) to make sure the hit would be detected in time.

I considered using the MMC3, because it is a very common mapper, but it's scanline IRQ would not work properly because I use sprites from both sides of the pattern table.

So, blanking scanlines at the top of the screen instead seemed like a good choice, I just wasn't counting on the fact that sprites have that one scanline delay (should have seen it, dumb me). Then again, this is not such a big glitch, and I doubt the player will pay attention to the top of the screen while the action is right in the middle of it.

EDIT: Oh, I don't think I mind the different dot crawl pattern either... With all the action, this doesn't seem really important. And this different pattern is not really worse, IMO.

by on (#30088)
I don't think having 17 scanlines blanked instead of 16 makes ANY differences in fact. Also, if there is no sprites on the first scanline this really won't be noticeable. In fact this is always the case in normal games when rendering is always enabled, and with a PAL TV you should see this but I never really noticed this. However, the glitches that appear on the top and bottom on 99% of games using vertical mirroring when scrolling vertically are really noticeable on a PAL TV.

by on (#30089)
Well, by considerating my experience with debugging... it DOES matter, and still more if you consider his project. ^_^;; What it needs is a smart tweak for the timing.

by on (#30090)
Fx3 wrote:
Well, by considerating my experience with debugging... it DOES matter

Care to explain why? :?

From a technical point of view, I could easily blank another background line, it's just that I have a big problem with a number as unfriendly as 17... I just can't have that. Plus, I'd feel bad about spending a whole scanline doing nothing when I could already be working on the next frame.

Quote:
What it needs is a smart tweak for the timing.

I don't think I can reduce the time taken by the VBlank routines anymore... I did everything to have it all run faster, from pre-calculating every needed value to unrolling every loop!

Seriously, a single scanline without sprites is not such a big deal. I was just curious.

by on (#30091)
tokumaru wrote:
Plus, I'd feel bad about spending a whole scanline doing nothing when I could already be working on the next frame.

That extra scanline need not be wasted. You could use that line for a repetitive task (reading controller input, incrementing counters, etc.) that doesn't involve the PPU. Keep the task within 100 cycles (or break it up if it takes longer), and you're set.

Also, if you turn on sprite rendering only for the first line, the status of the PPU scroll regs is not important until you turn on the BG, so you could delay $2005/2006 writes to the following line (as long as the final write to $2006 comes after the start of H-Blank, it doesn't matter when the other writes occur - they could even occur on an earlier scanline and everything will work).

by on (#30092)
tokumaru wrote:
Care to explain why? :?


*bump* Well, sort of... You're developing a game, so you know about its timing and related stuff. It's different than analysing the timing of PPU emulation. Needless to mention examples.

Quote:
I don't think I can reduce the time taken by the VBlank routines anymore... I did everything to have it all run faster, from pre-calculating every needed value to unrolling every loop!


Great. My guess was random after all... >_<;;

Quote:
Seriously, a single scanline without sprites is not such a big deal. I was just curious.


This is what Ershin says.

by on (#30096)
Quote:
From a technical point of view, I could easily blank another background line, it's just that I have a big problem with a number as unfriendly as 17... I just can't have that. Plus, I'd feel bad about spending a whole scanline doing nothing when I could already be working on the next frame.

Then you answered your own question and you don't need anyone else agreement on this, this is your game.

by on (#30653)
Sooo..... I ended up getting rid of the sprite delay. I don't know why, but that kind of glitch messes with my head, and I couldn't live with it.

By using some dirty tricks I was able to squeeze another scanline worth of time so that I could enable sprite rendering on scanline 15, and then enable background rendering on scanline 16, which results in a clean, 16 pixels tall border, masking out sprites and background evenly. Well, almost. This is what happens in Nestopia, Nintendulator and on the real console.

However, I often use FCEUXD because of it's strong debugging capabilites. In fact I found out a pretty nasty bug with it. There is no way that I'll modify my code to fix a glitch that shows up in an old emulator, but I thought I'd bring it up here so that people are aware of the problem, in case they aren't already. Here's a screenshot of the glitch:

Image

Right after the blue border at the top, you can see part of the sprite that is in fact at the bottom of the screen. What seems to be happening is that this emulator will display, in the first scanline where sprites are enabled, the sprites that were evaluated for the scanline that came after the last visible one in the last frame. Almost like the programmer quickly modified the code to implement the sprite delay present in the console, and because of that the last scanline wrapped around to the top.

And this is not just in my case, this seems to always happen to the first scanline where sprites are enabled, regardless of which one it is. You just don't usually see it, because this emulator crops the screen in NTSC mode by default, but if you set it to display all scanlines, many games end up with a glitchy first scanline.

It's a shame actually. A shame that accurate emulation hasn't been coupled with good debug tools. There are a bunch of FCEU modifications that improve debugging, but if it's not such an accurate emulator, what's the point?

by on (#30654)
Quote:
By using some dirty tricks I was able to squeeze another scanline worth of time so that I could enable sprite rendering on scanline 15, and then enable background rendering on scanline 16, which results in a clean, 16 pixels tall border, masking out sprites and background evenly.

You really are awesome on this point.

Well, it's good to know which emulators have which inacuracies. Even through I use VirtuaNES a lot, I know that it's timing is off one scanline and that it allows writing to $2007 outside of VBlank, so I know what can go and what cannot go on an emulator. Does the same happens in regular FCEU ?

by on (#30663)
tokumaru wrote:
It's a shame actually. A shame that accurate emulation hasn't been coupled with good debug tools. There are a bunch of FCEU modifications that improve debugging, but if it's not such an accurate emulator, what's the point?

Well, on Romhacking.net, someone released a mod of Nintendulator with better debugging features, see here. I downloaded it myself and it's much better than the original Nintendulator's debugging features. The FCEUD series still have better debugging features IMO, but it may be worth it for you.

by on (#30665)
Thanks, I'll check it out!

Bregalad, I haven't tried the original FCEU, but it still happens in FCEUXD SP 1.07...

by on (#30710)
Hey, your screenshot makes me wondering something. It looks like there is room for a whole block on the "blank" top side, and a block is 16 pixel. Since you say FCEU hides the to 8 pixels, that means that you have 24 pixels blanked, not 16, what am I missing ?

by on (#30711)
FCEU hides them by *default*. I'm pretty sure he enabled them for that shot.

by on (#30712)
Bregalad wrote:
It looks like there is room for a whole block on the "blank" top side, and a block is 16 pixel. Since you say FCEU hides the to 8 pixels, that means that you have 24 pixels blanked, not 16, what am I missing ?

For one thing, the number of hidden scanlines is a user option.

by on (#30721)
Yeah, while testing I like to see the whole image. I just enable cropping when playing.

by on (#30887)
Hi guys. Sorry to get back to this, but after some more testing on my NES I got to verify that I have not achieved the perfect 16-pixel top border that I expect.

In the last blank scanline (that is scanline 15), it's possible to see what looks like 8 pixels of junk. It must have to do with sprites, because the background is not yet enabled then.

I'd like to ask you guys that know a lot about PPU timing to help me out with this. So please think with me for a bit: When VBlank starts, there are 20 scanlines of it. Then comes the pre-render scanline, and then rendering starts. Since I want to eat 16 scanlines of the rendering time, that's 37 scanlines for all my PPU updating madness.

But since I have to enable sprite rendering 1 scanline earlier, so that they do show up on scanline 16, I have in fact 36 scanlines before I have to enable them. 36 scanlines translate to 4092 CPU cycles.

However, if I do use that many cycles (including the time it takes to write the value that enables rendering to $2001), I end up enabling sprites too late. I know it takes 7 cycles for the NMI to be called, and that it will wait for the current instruction to finish before that, but even if my code takes 4082 it's still too much. I'm getting what seems the correct results with 4076 cycles, but that seems wrong... am I missing something?

Note that I'm using the grayscale bit to know when exactly I'm enabling the sprites, since Nintendulator seems to give a damn about where exactly I enable them, because even when changing the timing a lot they never seem to change. In fact, I was afraid that some sprites would be displayed while others would not bocause of the order in which they are evaluated, so I made the program put the test sprite in different locations of the OAM every frame, so that I could see if some of them were dropped, but that never happened.

Also, what would be the best time inside a scanline to enable sprites? Since I want them to be visible on scanline 16, would it be OK to enable them at the very end of scanline 14? Or could that be the reason I'm getting junk at the start of scanline 15? Maybe it has something to do with the way the sprites are evaluated...

Anyway, any help is appreciated. I would hate having to guess the correct amount of cycles based on trial and error (specially if the results don't match what I think would be right).

by on (#30888)
Quote:
I would hate having to guess the correct amount of cycles based on trial and error (specially if the results don't match what I think would be right).

Personally I always do trial and error when I do timed code/midframe changes. I don't know when exactly you should enable your sprites for them to be evaluated correctly, I'm pretty sure Quietust knew all this thing by heart but he's gone now...

by on (#30949)
Know what? Fuck the MMC1. I'm spending so much time worrying about this timing shit that I never get to work on the actual game, for which I already have a lot of code but can't test until the basics have been finished.

Enabling rendering late is a pain in the ass. Disabling it earlier is not that much better, because of crappy scanline counters (MMC3) and glitchy-looking, unreliable sprite 0 hits.

I'm looking into using CHR-ROM, but I really really need to work with 8 1KB banks, and the (crappy) MMC3 won't allow this. But even if I get rid of the task of writing the tiles to CHR-RAM, not blanking part of the rendered frame will expose vertical scrolling glitches. Unless I use 4-screen mirroring, but not many carts have that.

Fuck that. I'll pick whatever mapper suits the game better, even if it's not that common or easy to reproduce. The FME-7 seems just perfect for this. Will think a bit more.

by on (#30951)
I don't see any reason to not go with the FME7, yeah it's not a common NES mapper but there's the PowerPak now.. Also the M2 counter just works unlike the scanline counters and it's more versatile. It's not even too hard to use it for scanline counting, I think the best way is to make a scanline lookup table with M2 values. Unless you're trying to interrupt on every scanline it shouldn't be too difficult to time correctly.

by on (#30952)
In addition, a CPU cycle counter would allow your code to turn off the screen early and take advantage of the post-render scanline.

If you make a fan game that uses the original game's copyrighted characters, you probably won't be able to sell it. But the good news is that you don't need to worry about selling it. So you can go ahead and put in FME-7 or a similarly powerful mapper, as most players will experience it through an emulator anyway.

by on (#30953)
Yeah, I agree with you both. I was kinda thinking along those lines. I just wanna get the basic "kernel" (as the Atari 2600 programmers say) out of the way so that I can concentrate on the real stuff (object programming, animation and so on).

If I do use the FME-7, I might want to get myself one of those Batman carts, otherwise I'd feel bad about trying it on the NES with just the PowerPak. Does the PP even support this mapper? I *think* it does, because I kinda remember playing the Batman game with it.

I'm still considering the MMC3 though (only bankswitching, no scanline counting), I'll probably have decided by tomorrow.

by on (#30956)
Well, do as you wish, but I really don't see why the beef with the MMC1. Also you shouldn't get even if there is 3 glitchy pixels on the screen or something, because this happens often on the NES. It's possible to have sprite-zero hit without any glitches, but this sometimes makes restrictions in the level.


By the way, to answer your previous question, Battletoads seems to enable sprites one scanline before BG, and do both $2001 writes during HBlank if that helps you. I haven't heary anything about sprites glitch because of this, but I don't own the real thing. Seeing how many Battletoads fans are arround, if there were a glitch it'd probably be known by now.

If you don't blank any scanline, and only use NTSC systems where top and bottom lines are hidden, it's possible to do multidirectionnal scrolling (without a status bar) without any glitches at all.

You definitely couldn't be a programmer at Rare, where they did awesome things with the worst mapper to code for, mapper 7. MMC1 is way more powerfull than this mapper, and MMC3 is even more powerfull in some respects (altrough it lacks the flexibility of MMC1 when it comes to bankswitching and mirroring). Personally I like the spirit of doing the most thing possible on a basic mapper. You'll see, when my mapper 3 game will be released (if this ever happens) everyone won't belive it, you'll all be saying "hey that's impossible it looke like MMC3 !". No I'm just kidding here.

by on (#30958)
tokumaru wrote:
Yeah, I agree with you both. I was kinda thinking along those lines. I just wanna get the basic "kernel" (as the Atari 2600 programmers say) out of the way so that I can concentrate on the real stuff (object programming, animation and so on).

Or you can prototype some of the game logic on a PC using a PC-native graphics library, and then port it to the NES once you feel you have the kernel working. I've used that technique for each of my major GBA productions. (Granted, it's easier on the GBA because the GBA has a reasonable C compiler.)

Quote:
I'm still considering the MMC3 though (only bankswitching, no scanline counting), I'll probably have decided by tomorrow.

Are you going to do it SMB2/SMB3 style (2 KiB BG banks, 1 KiB sprite banks) or Kirby style (1 KiB BG banks, 2 KiB sprite banks)?

by on (#30964)
Quote:
Or you can prototype some of the game logic on a PC using a PC-native graphics library, and then port it to the NES once you feel you have the kernel working. I've used that technique for each of my major GBA productions.

Interesting technique, but isn't writing + conveting more work than just writing ?

by on (#30969)
Bregalad wrote:
Quote:
Or you can prototype some of the game logic on a PC using a PC-native graphics library, and then port it to the NES

Interesting technique, but isn't writing + conveting more work than just writing ?

Not if the productivity gains from writing in a more forgiving environment first outweigh the costs of porting. There's a reason that Midway's Klax was prototyped in Amiga Basic and then ported to NES.

by on (#30972)
To elaborate on tepples' point, when coding on the PC, you have essentially infinite memory and processing power for implementing NES-class games. You have high-level languages, good debuggers, ability to profile design in many ways, easy setup of graphics, etc. This allows easy experimentation with alternate designs and design changes. Once the design is finalized, then you can pay the cost of carefully coding that in 6502 asm for the NES. You can be more confident that the design won't change drastically, allowing more work on optimization.

It would be neat to prototype the design on a PC using a NES emulator for the graphics, having your high-level code do PPU and MMC3 writes. The timing constraints wouldn't be there, but everything else would. You could try different ideas for when to write things, even things impossible on the NES (which, like imaginary numbers, might be part of the mental path to a real solution that works on the NES).

by on (#30974)
tepples wrote:
Are you going to do it SMB2/SMB3 style (2 KiB BG banks, 1 KiB sprite banks) or Kirby style (1 KiB BG banks, 2 KiB sprite banks)?

At first I considered going SMB style. But then I figured it would work better the other way around, like Kirby.

The main reason for that is that I will be animating the background through bankswitching. Monitors and rings (constant objects) have a common animation rate and number of frames, and as long as there are 3 other background "slots", other (level-specific) things could be animated differently.

Sprites usually don't need that sort of cycled animation (the few ones that do could be placed in the background area because I'm using 8x16 sprites), instead they need to use a specific CHR bank depending on what they are doing. That is specially true for the main character.

The bad thing is that I sure couldn't set aside a full 128-tile chunk just for the main character, leaving only 128 for the HUD, enemies, explosions, and so on. So this is where a lot of redundance is necessary. Since I have a sort of 16-tile limit for each main character frame, I could fit 4 of it's frames in 1KB of CHR-ROM, while the other half of the bank (the other 1KB) would hold all the HUD stuff (which can vary depending on the selected character: the life icon, for example), explosions, a few items... Thismeans that this 1KB would have to be repeated for every 4 frames of the main character.

So if I have 96 frames for the main character (though I don't think it'll be that many), that 1KB of constant sprites would have to be repeated 24 times. Quite a waste, but it's the best I could think of. The other half of the sprite side would hold level-specific sprites, and since Sonic enemies are not that complex, I doubt I'd have to animate that part at all.

There is also the issue of the ending sign, bosses, animal containers, things that should only be loaded by the end of the levels. The bosses could very well have their graphics loaded in place of the level enemies, and since bosses are level-specific, they may even keep some of the tiles used along the level if they need too.

The animal container is drawn with background tiles, so at least one of the 1KB slots should be replaceable. Bosses may also need background tiles, so this is even more necessary. And there will be this replaceable 1KB, the ending sign could use this as well.

So, in the end, it goes something like this:

SPRITE SLOTS:
0: Main character, HUD, explosions, etc;
1: Level-specific, replaced by boss;

BACKGROUND SLOTS:
0: Constant objects (monitor, lamp post, ring, etc);
1: Level-specific;
2: Level-specific;
3: Level-specific, replaced at the end (by bosses, end sign or animal container);

Does anyone have a better idea? With full 1KB bankswitching (FME-7, for example) it would be posible to make the sprite side a bit more versatile, but I don't think this is such an issue right now. With 256KB of CHR-ROM, that redundance problem isn't really a problem (even with 96 frames of animation for both characters, there'd still be 160KB for everything else).

by on (#30978)
Under an MMC3 bank layout, would the blue guy ever be on the same scanline as the HUD?

Another tip: The area after the last raster split can probably use sprites from both banks.

by on (#30982)
Bregalad wrote:
Well, do as you wish, but I really don't see why the beef with the MMC1.

I hate writing to it's registers. If one of those writes is interrupted by an NMI, you are pretty much screwed. It's CHR banking scheme is pretty poor, so using CHR-ROM with it is out of the question. Also, since I was using a SUROM board, having to constantly switch between the two 256KB sections of the ROM was pretty annoying, even though I came up with a decent way to do that, it would be so much better if I didn't have to.

Quote:
Also you shouldn't get even if there is 3 glitchy pixels on the screen or something, because this happens often on the NES.

I know. But I want to be like the programmers that found ways to get rid of the glitches rather than the ones that just learned to live with them. I've been going through so many commercial games the last few days, and I've seen many creative ways people got rid of scrolling glitches (while still using only 2 name tables) that it's a bit inspiring actually.

There are 2 games that really cought my attention: Alfred Chicken and Jurassic Park. Alfred Chicken uses horizontal mirroring to get avoid vertical scroliing glitches, masks the leftmost 8 pixels of the screen and goes as far as sacrificing a large number of sprites to mask the right side of the screen. I'd never waste that many sprites, and reduce the scanline limit to just 7, but it's still a nice solution, that works for this game and it's small sprites. Jurassic Park keeps the CHR banks mapped to blank tiles, and at a certain point switches the actual graphics in. I find this pretty clever, and am considering something similar to hide glitches.

Quote:
It's possible to have sprite-zero hit without any glitches, but this sometimes makes restrictions in the level.

I admit that my biggest problem with sprite 0 hits at the bottom of the screen isn't a possible visible glitch, but the fact that you must be sure that the frame calculations will be done before the hit, or else it'll look like Micro Machines, with it's flashing border, and that sucks. I know you could set up APU IRQ's to make sure you don't miss the sprite 0 hit, but since the timing of the IRQ's vary so much, you end up loosing valuable processing time and will probably miss more frames.

I don't expect to miss a lot of frames, but even the originalsonic games slowed down quite often when many objects were present. I can't expect to make something much better than that with a slower CPU, no matter how efficient my code is, so I must be prepared for a few slowdowns.

Most NES games that use sprite 0 hits to hide part of the bottom of the screen do not have slowdown problems, as the processing ends long before the sprite hit. Or they'd be like Micro Machines.

Quote:
By the way, to answer your previous question, Battletoads seems to enable sprites one scanline before BG, and do both $2001 writes during HBlank if that helps you. I haven't heary anything about sprites glitch because of this, but I don't own the real thing. Seeing how many Battletoads fans are arround, if there were a glitch it'd probably be known by now.

Yeah, but Battletoads has a huge black section at the top that could very well hide any glitches. It takes some time to jump into the action part of the frame, while my game doesn't. Anyway, even in my game the glitch is pretty small, not such a big thing. It doesn't even flicker, it's static, so it doesn't stand out much. I'm now much more worried about how complex and fragile the kernel can be than with small glitches, actually. I'd rather move to a more stable setup, even if that means a couple of glitches.

Quote:
If you don't blank any scanline, and only use NTSC systems where top and bottom lines are hidden, it's possible to do multidirectionnal scrolling (without a status bar) without any glitches at all.

I know. As I said, I've been looking at tons of comercial games loking for interesting solutions.

Quote:
You definitely couldn't be a programmer at Rare, where they did awesome things with the worst mapper to code for, mapper 7.

I'm sure I could, I just wouldn't be able to code Sonic there! =)

Quote:
Personally I like the spirit of doing the most thing possible on a basic mapper.

I'm all for that too! It's just a bit harder in my case, because this is not a fully original game. There is a set of rules I must follow if I want the game to feel like a real Sonic game, rules that were created for a system more capable than the NES, so it gets really hard to mimic those features with so little resources. It's just this special case.

Quote:
You'll see, when my mapper 3 game will be released (if this ever happens) everyone won't belive it, you'll all be saying "hey that's impossible it looke like MMC3 !". No I'm just kidding here.

Looking forward to that! =)

Please note that everything I said about the MMC1, sprite 0 hits, etc, applies to the type of game I'm coding. Please don't think that I'm saying "everything sucks", it's just that these common solutions don't seem to fit my game very well, that's all. But I'm sure there is a way out for everything. If in the end I can't avoid all glitches, so be it, I'll have to live with some.

by on (#30984)
tepples wrote:
Under an MMC3 bank layout, would the blue guy ever be on the same scanline as the HUD?

I think that regardless of the mapper, Sonic can move faster than the camera at times, so it is possible for him to be anywhere on the screen, and even out of it. BTW, there is another playable character besides the "blue guy"! =)

Quote:
Another tip: The area after the last raster split can probably use sprites from both banks.


It would be pretty hard to control which sprites are where... rings are fetched from the background side, so you can imagine that you can't really control that.

I am however taking what you said into consideration. I made that other topic about changing the sprite height exactly for that reason. The idea is to keep PPU updates all inside VBlank, and having rendering enabled by the start of the frame (no different dot crawl). All 4 background banks would be mapped in, the sprite banks pointing to empty tiles. Sprites would be set to 8x8, and both sprites and background set to fetch patterns from the transparent tiles. I'd set up and IRQ for a few scanlines in (enough to hide scrolling glitches). When the NMI fires, I switch in the 2 sprite banks, set sprites to 8x16 and set the background to fetch tiles from the correct side (this is possible with less than 28 cycles, more or less the length of HBlank). It would also be more compatible with PAL systems.

That would allow for a very clean border at the top, with almost no wasted time (the IRQ would interrupt the processing of the frame that would have already started). I believe I'd have again that 1 scanline without sprites I tried to get rid of a when using the MMC1, because during the scanline the sprites were evaluated, all sprite patterns were transparent. But I don't think I care about that anymore, that can't even be considered a glitch I guess, because it's very consistent behavior. Also, not wasting time just waiting or copying an insane amount of bytes to the PPU is a relief, and might even result in less dropped frames, resulting in a more efficient engine.

I'm starting to think the MMC3 is a reasonable choice now. It's PRG-ROM bankswitching scheme is pretty useful too, allowing for better separation of code and data than I had with the MMC1.

EDIT: There is a small problem with the idea above... can't use the scanline counter if sprites and background use the same pattern table area. Oh well. This wouldn't be an isue with the FME-7, and there'd be no need for so much tile redundancy. The MMC5 would handle it well too, but that's a bit overkill.

by on (#30990)
Wow... as I keep looking at commercial games I see some strange stuff... I just know checked this game, "Super Cars", which seems to hide a few scanlines at the top.

I don't know what it does yet, but it must be something very funky, because Nestopia seems to be the only one to emulate it correctly... In FCEUXD the bar flickers a lot, and Nintendulator goes completely crazy. I wouldn't expect Nintendulator to act so crazy over something that works on the NES (it probably does, since it seems to be a commercial game).

I'll try and figure out what the hell this game is doing that confuses emulators so much.

by on (#30991)
tokumaru wrote:
Wow... as I keep looking at commercial games I see some strange stuff... I just know checked this game, "Super Cars", which seems to hide a few scanlines at the top.

I don't know what it does yet, but it must be something very funky, because Nestopia seems to be the only one to emulate it correctly... In FCEUXD the bar flickers a lot, and Nintendulator goes completely crazy. I wouldn't expect Nintendulator to act so crazy over something that works on the NES (it probably does, since it seems to be a commercial game).

I'll try and figure out what the hell this game is doing that confuses emulators so much.

I tried the game myself on the official latest version of Nintendulator (0.965 beta) and it works fine. However, it does NOT work fine on the special debugger version of Nintendulator I recommended to you before. The flickering bar glitch in FCEUxD also occurs during certain cutscenes of Metal Slader Glory, when it needs to turn off rendering early at the bottom.

by on (#30993)
strangenesfreak wrote:
I tried the game myself on the official latest version of Nintendulator (0.965 beta) and it works fine.

Oh yeah, I forgot this one was out!

Quote:
However, it does NOT work fine on the special debugger version of Nintendulator I recommended to you before.

Yeah, I tried it too.

Quote:
The flickering bar glitch in FCEUxD also occurs during certain cutscenes of Metal Slader Glory, when it needs to turn off rendering early at the bottom.

Well, it's normal for this to happen at the bottom of the screen, but at the top it's a bit weird...

I was just wondering what could confuse the previous version of Nintendulator so much... I'll debug this a bit know and see if I can figure it out.

EDIT: Are you sure you got it working with Nintendulator 0.965? It's not working for me. The screen just stays white. The game seems to be running though, because when I switch to PAL mode I can see something, and the game runs for a while before glitching up.

by on (#31001)
Well, what to say ? You may be just worrying too much. Note that if the Sonic game on the NES looks slightly different than their megadrive counterpart and if a few details are lacking, I guess noone will blame you, because after all, while we all love the NES, it's still technically an inferior system.

If you want to use MMC3 why not change between 4 BG banks/2 SPR banks and 2 BG banks/4 SPR banks ? Levels that needs heavy BG graphics with animation would use the 4 BG banks, and manage to not bankswitch sprites (if you're using bankswitching for Sonic himself at $1000 say, this will need sacrifice at $1400-$1800 with garbage tiles since they'd be unpredictable). Then for most levels, you'd just go with the 2 BG banks / 4 SPR banks, where more customisation is allowed for sprites.

Also as long as you don't use the scanline counter, you're free to use BG and sprites from any pattern tables with no problem, so if you're going to use any raster effect, you can design your level according to this pattern table limitation, but don't care about it for other levels where there is no raster effects.

I guess the better way to hide glitches is to place them where the user will be less likely looking... If you're scrolling right, the user will LOGICALLY watch on the right of the screen... where new enemy and stuff will come. The player will be completely pissed to what happens on the left of the screen.
So if there is color glitches on the very left of the screen, noone will ever see them... Most games with attributes glitches always set them on the same side of the screen, and that's just not clever. Knowing that, use Horizontal mirroring will allow you to have "no" glitches on both NTSC and PAL.

Quote:
I admit that my biggest problem with sprite 0 hits at the bottom of the screen isn't a possible visible glitch, but the fact that you must be sure that the frame calculations will be done before the hit, or else it'll look like Micro Machines, with it's flashing border, and that sucks. I know you could set up APU IRQ's to make sure you don't miss the sprite 0 hit, but since the timing of the IRQ's vary so much, you end up loosing valuable processing time and will probably miss more frames.

Yeah, I have also wondering about this for a while. Many games, like Gradius, Life Fore, Wizard and Warriors series, Solar Jetman, etc... handle this somehow (and without using APU IRQ nor DMC IRQs). I've tried to log Gradius when it slows down... It's rather amazing, I guess somehow the game engine is KNOWING it will lag before actually lagging, and so it perform less calculations for one frame, check for sprite zero hit in time, and repeat next frame, so while the game is technically lagging, the CPU still doesn't run at 100%. I guess other Konami games use similar techniques.
However, Double Dragon handles this badly, and when there is too much CPU process to be completed in a frame, the status bar shakes.

For MMC1 writes, the MMC3 won't help much because there is the same problem, an NMI can occur between a write to $8000 and a write to $8001, screwing things up.
To fix the problem of the MMC1, you would of course disable NMIs when you're writing to registers, and enable NMI back after this, but this may delay the NMI a little and screw your timing up. Another trick is to simply avoid writing to any MMC1 registers in the NMI routine when a flag is set (and set this flag when the main programm writes to the registers). A third, more sophisticated method, is to disable NMI when the main programm does its MMC1 writes, and after the fifth write read $2002.7 instead before re-enabling NMIs. If the bit was set, then you just missed an NMI but you can call a routine that does exacly the same, and that with a fixed timing that won't screw up (typically the time wasted on the end of the MMC1 write can be saved back by not saving the registers). You may also use the BRK instruction to have an "IRQ" routine that would be a NMI clone that just start differently, and jump to the normal NMI routine, assuming you don't use any other type of IRQs.

For the MMC3, it's simple enough, after write to $8000 simply write a copy of it to a memory location, before writing to $2001. At the end of NMI just read that memory location and write it to $8000, that should do the trick. The above methods will work as well, but it's probably better to "waste" a single byte of RAM. In fact now that I think about it it you can do more elvolved method to handle the MMC1 case, for exemple each time the main programm writes something to the MMC1, set a flag during this time, and the NMI code check this flag (once everything time-critical has been done). If set, it will change the return adress so that it doesn't do the rest of the write, but directly return, and instead write "latched" values in RAM before returning. That would seem the most perfect method to me, at the price of a few RAM bytes, once for a flag and other to mirror MMC1 writes.

EDIT : If you're really worried about graphical glitches.... I have a method that will completely remove them, both horizontal and vertical, and with any mirroring mode... However this introduce a limitation to the graphics themselves. Are you ready ?
Just make all 4 BG palettes identical. You don't have to worry about any attribute updates, you don't have to worry about attributes glitches. Since you don't use attribute tables, you're free to set PPU adress to $3c0 during rendering and have nametable data instead, effectively making the screen 32x32 instead of the usual 32x30. The bad news is that you'll have to do it manually, and without IRQs that could be a pain. Wizard and Warriors II doesn't do exactly that, but have all its graphics using a single BG palette for some reason, so that is possible.

by on (#31011)
Bregalad wrote:
Well, what to say ? You may be just worrying too much.

Yup.

Quote:
Note that if the Sonic game on the NES looks slightly different than their megadrive counterpart and if a few details are lacking, I guess noone will blame you, because after all, while we all love the NES, it's still technically an inferior system.

Heh, I'm sure I will not be able to fool anyone into thinking "hey, is this for the NES or MD again?", but I want it to feel similar enough, inspite of the obvious graphical inferities. It's not my intention to mimic everything from a MD game anyway, because I'm sure it will look better if I intentionally simplify a few things rather than forcing the NES to do what it obviously can't and fail miserably.

My goal is actually to surpass the SMS titles, getting closer to the MD titles than they ever did. And the NES does have a few advantages over the SMS: there are more tiles available (although they have less colors), which may result in less repetitive graphics, specially when combined with CHR-ROM bankswitching, for example. The SMS games look kinds dull, and whenever a larger amount of tiles needs to be loaded the game lags.

Quote:
If you want to use MMC3 why not change between 4 BG banks/2 SPR banks and 2 BG banks/4 SPR banks ?

Iguess you are right, this would be possible. But I don't think I would "scrifice" anything, meaning that I'd still have a 1KB of common sprites following every 1KB of player graphics, in case sprites use the 2KB switching. And if the background used 2KB switching, I'd make it responsible for animating the common objects stored there (rings, monitors, etc).

Quote:
Also as long as you don't use the scanline counter, you're free to use BG and sprites from any pattern tables with no problem, so if you're going to use any raster effect, you can design your level according to this pattern table limitation, but don't care about it for other levels where there is no raster effects.

There is simply no way for me to act according to it's scanline counter limitations. Except for the border at the top, but as soon as the IRQ fires, I'll do everything that's not allowed. So yeah, I won't be using raster effects during the rest of the frame, not even for the water levels, I have another idea for them already.

Quote:
I guess the better way to hide glitches is to place them where the user will be less likely looking...

The only serious problem with me using that approach is that most NES games only update rows/columns that are a single tile tall/wide when scrolling, while I update full metatiles (2 tiles tall/wide) at a time, because of the fast scrolling. That means more visible glitches than the average game. Unless I'm able to hide exactly 16 pixels in the direction of the mirroring, which is harder to do horizontally (like Alfred Chicken) than vertically.

Quote:
It's rather amazing, I guess somehow the game engine is KNOWING it will lag before actually lagging, and so it perform less calculations for one frame, check for sprite zero hit in time, and repeat next frame, so while the game is technically lagging, the CPU still doesn't run at 100%. I guess other Konami games use similar techniques.

Hum... it may be possible to predict when the calculations are going to take too long. The things that have more impact over the time spent are the need to render a new background row/column and the number of loaded objects. But even then, the complexity of each loaded object can make the actual amount meaningless. But if you think about it, even if a game can predict this, it still must sacrifice a great deal of otherwise usable time just to make sure it doesn't get too close to the hit (risking missing it), even when the sacrificed time might had been enough to finish the calculations, which causes more frame drops.

Quote:
However, Double Dragon handles this badly, and when there is too much CPU process to be completed in a frame, the status bar shakes.

This is just terrible, specially if it happens all the time.

Quote:
For MMC1 writes, the MMC3 won't help much because there is the same problem, an NMI can occur between a write to $8000 and a write to $8001, screwing things up.

I see your point, but I don't think this is as bad. I can think of a simple solution for the MMC3 case, while it's not so easy for the MMC1. Like, setting a flag before mapper writes that might be interrupted, using different registers for each write (say, X for $8000 and A for $8001). Before returning from the interrupting code, it checks this flag and clears it if it's set, then performs the two writes (X to $8000 and A to $8001). This should work well no matter where the code was interrupted. There should be no problem if after returning, both writes occur again, only the second write occurs again, or no write at all. The correct bank will be loaded. Not as simple with the MMC1, because of the larger number of writes to perform a switch and because it's harder to reset it's bit counter in order for the writes to reamain aligned.

Quote:
To fix the problem of the MMC1, you would of course disable NMIs when you're writing to registers, and enable NMI back after this, but this may delay the NMI a little and screw your timing up. Another trick is to simply avoid writing to any MMC1 registers in the NMI routine when a flag is set (and set this flag when the main programm writes to the registers). A third, more sophisticated method, is to disable NMI when the main programm does its MMC1 writes, and after the fifth write read $2002.7 instead before re-enabling NMIs. If the bit was set, then you just missed an NMI but you can call a routine that does exacly the same, and that with a fixed timing that won't screw up (typically the time wasted on the end of the MMC1 write can be saved back by not saving the registers). You may also use the BRK instruction to have an "IRQ" routine that would be a NMI clone that just start differently, and jump to the normal NMI routine, assuming you don't use any other type of IRQs.

Your solutions are interesting, but I'd rather interrupt a MMC3 write than having to worry about the MMC1 ever again! =)

Quote:
For the MMC3, it's simple enough, after write to $8000 simply write a copy of it to a memory location, before writing to $2001. At the end of NMI just read that memory location and write it to $8000, that should do the trick. The above methods will work as well, but it's probably better to "waste" a single byte of RAM.

Oh, I didn't read this before! Yeah, this solution is almost what I said above, but yours is simpler. You are right, there is no need for a flag, and there is no need to write to $8001 as well at the end of the NMI/IRQ. See? It's much better! =)

EDIT: Hey, if do want to have the correct bank loaded after returning from the NMI/IRQ, you do have to write to $8001 as well. Say that I was switching in a bank with metatile definitions when the NMI fired. Inside the NMI, I'll see that the frame isn't ready, and will want to call the sound engine, which switches in a bank with music data in place of the metatile definitions. Before I return, I must write to $8000 and $8001 the value that I was trying to write earlier, if I want the metatile definitions to be there, not the music data.

Quote:
EDIT : If you're really worried about graphical glitches.... I have a method that will completely remove them, both horizontal and vertical, and with any mirroring mode... However this introduce a limitation to the graphics themselves. Are you ready ?

That's nasty... But having a 4-color background would be pretty dull. Not even considering this for a Sonic game!

by on (#31014)
Quote:
Heh, I'm sure I will not be able to fool anyone into thinking "hey, is this for the NES or MD again?", but I want it to feel similar enough, inspite of the obvious graphical inferities. It's not my intention to mimic everything from a MD game anyway, because I'm sure it will look better if I intentionally simplify a few things rather than forcing the NES to do what it obviously can't and fail miserably.

Yeah, but compare the SNES Final Fight and the NES Mighty Final Fight and you'll see what I mean... Personally I like Mighty Final Fight better. Capcom got it all, instead of trying to do the same on the NES port, they just designed another NES Final Fight game that had nothing to do with the original SNES version, and that was intended for the NES from the start : Smaller sprites, samller levels, and the gameplay is much funier. I guess you could do smaller sprites than MD games, and maybe make smaller background elements too, that would probably help by using less tiles and still look very good, as long as everything keeps more or less in proportion.
Quote:
The only serious problem with me using that approach is that most NES games only update rows/columns that are a single tile tall/wide when scrolling, while I update full metatiles (2 tiles tall/wide) at a time, because of the fast scrolling. That means more visible glitches than the average game. Unless I'm able to hide exactly 16 pixels in the direction of the mirroring, which is harder to do horizontally (like Alfred Chicken) than vertically.

I guess I see what you mean here. I guess upload metatiles simplifies things a lot. Unless you use single-palette BG I see no way to completely fix it, but you can just put those glitches on the side the player is not looking and it should be allright... Too much glitches can be annoying, tough.
Quote:
Hum... it may be possible to predict when the calculations are going to take too long. The things that have more impact over the time spent are the need to render a new background row/column and the number of loaded objects. But even then, the complexity of each loaded object can make the actual amount meaningless. But if you think about it, even if a game can predict this, it still must sacrifice a great deal of otherwise usable time just to make sure it doesn't get too close to the hit (risking missing it), even when the sacrificed time might had been enough to finish the calculations, which causes more frame drops.

Well, Gradius can have a lot at objects at once in Level 1 without lagging. In level 5 when there is those flowers attacking, the game lags A LOT, but the status bar doesn't move a single bit, even tough it's made entierly on sprite zero hit. And there is only 2 flowers attacking, as opposed to dozen of projectiles from stage 1. I guess it's mazing them to sprites who takes so long... Life Force is pretty much the same, it lags, but still manage to never miss a single sprite zero hit.
EDIT : Also instead of making a programm that would lag proprely when so many objects are on screen, I'd rather limit the number of object and design the game with that in mind.

So in the end you'll end up using MMC3+CHR ROM, have vertical mirroring to hide horizontal glitches, and use a all-black CHRROM blank to hide the top border of the screen to hide vertical glitches (without having to worry about setting the scroll midframe a complete way) ? That souds like a good sheme.
Also by the way about the method to use sprites to clip the right part of the screen, I gess it may waste a lot of sprites, but if you use 8x16 sprites you can do it with 14/15 sprites only (NTSC/PAL). I guess Zelda II and Lagrange Point does this. The very good side, however, is that you have a 100% symetrical screen and have really nothing to worry about horizontal glitches. I guess having a screen with even number of tiles horizontally is a bit annoying (but I've never actually used the left clipping yet).

by on (#31025)
Bregalad wrote:
Well, Gradius can have a lot at objects at once in Level 1 without lagging. In level 5 when there is those flowers attacking, the game lags A LOT, but the status bar doesn't move a single bit, even tough it's made entierly on sprite zero hit.

If the game had a way to get even a vague idea of where in the frame it was, it could wait for the next frame before executing a potentially large task.

Some games might alternate tasks (for example, process less enemies if there is background to draw or something like that) to make sure they ramain within the limit of cycles. However, they might choose to introduce slowdown in case a large task needs to be performed, but it's only performed during the next frame, so that the sprite hit is not affected.

Quote:
Life Force is pretty much the same, it lags, but still manage to never miss a single sprite zero hit.

I think this one relies on IRQ's firing a few scanlines before the hit. Someone in here said this a while ago.

Quote:
EDIT : Also instead of making a programm that would lag proprely when so many objects are on screen, I'd rather limit the number of object and design the game with that in mind.

Once again, this depends on the type of game you are making. Sonic Team went with the lagging option (they had to, with that insane amount of rings flying around when Sonic looses them), so that might be the best option for me too. The Sonic engine can get pretty busy at times. A little slowdown does not bother me, but visual glitches do.

Quote:
So in the end you'll end up using MMC3+CHR ROM, have vertical mirroring to hide horizontal glitches, and use a all-black CHRROM blank to hide the top border of the screen to hide vertical glitches (without having to worry about setting the scroll midframe a complete way) ? That souds like a good sheme.

That's the idea. I'll use transparent tiles though, so that the "border" uses color 0. While loading the actual patterns through $8000 and $8001, I might have to disable background rendering for a while and re-enable it during HBlank (this shouldn't do anything bad with the scroll, as long as I re-enable rendering before the start of the next scanline), because it takes a while to switch all 6 CHR banks, and with the background enabled there would be glitches. The good news is that this will produce a very clean border, without messing with the dot crawl pattern, without wasting CPU cycles, and with minimal timed code (from when the NMI fires, going through resizing the sprites, disabling the background, switching in the 6 banks, ending by enabling the background during HBlank). All of that might even get close to using the full scanline, so I'd really be wasting almost nothing.

The good thing about this scheme is that it's really easy to implement, I con do it right now without wasting much time timing things. My old VBlank code used about 18 scanlines worth of time (another 18 were needed to update 256 bytes of CHR data, but I don't have to worry about this anymore), so they'll fit inside the normal 20 of VBlank easily.

Now, why do people usually prefer to clip scanlines at the bottom of the screen rather than at the top? In all TV's I tested, many more scanlines are cropped from the top than from the bottom. This may be an issue with my TV's though. Anyway, people sem to think that a blank bar at the bottom is less noticeable. Is this true?

In a game like mine, where most of the background uses color 0 (which allows for some layering effects through the priority bit of the sprites), the border may be harder to notice at the top, because at the bottom you are likely to have the floor where the player is standing, which doesn't use color 0. This is not always the case, but most of the time you have only sky at the top, and sky mixes well with color 0.

EDIT: Another clear advantage of blanking the top instead of the bottom (specially when using 8x16 sprites), is that sprites can can move smoothly at the top, something that leaves only the left side of the screen with sprite issues, and if that really bothers you, just hide the leftmost 8 pixels as the PPU allows it, and you get perfect sprite movement.

Quote:
Also by the way about the method to use sprites to clip the right part of the screen, I gess it may waste a lot of sprites, but if you use 8x16 sprites you can do it with 14/15 sprites only (NTSC/PAL).

I know, this is a great idea. I'd worry more about reducing the sprites per scanline limit to 7 than about using 14 of 15 out of the 64, though.

by on (#31026)
If your game is faced with big tasks, I think you could reduce the framerate of the game when the tasks need to be executed instead of slowing it down. If your game segregates the main tasks to the main thread, you could also reduce the framerate of the main thread instead of the whole game. You could even do multi-threading within the main thread and just reduce the framerate of the offending thread within the main thread.

by on (#31027)
strangenesfreak wrote:
If your game is faced with big tasks, I think you could reduce the framerate of the game when the tasks need to be executed instead of slowing it down. If your game segregates the main tasks to the main thread, you could also reduce the framerate of the main thread instead of the whole game. You could even do multi-threading within the main thread and just reduce the framerate of the offending thread within the main thread.

Really, the ones to blame for slowdown are always the objects/enemies. It'd be tough to not process them every frame though, because if they are not rendered, the action will look very weird with objects missing or not moving. Collisions with the player might go undetected, because it can move very fast. Objects that are drawn to the background are even worse, because those are drawn at the same time as columns and rows of metatiles are, so if a row or a column is updated but the object isn't processed, entire parts of it will be missing!

I'm betting on coding things as efficiently as possible in order to have very few parts slowing down. In previous tests, with the engine running normally, it wasn't until I had 16 objects loaded at a time that I started to loose frames, but even then I was scrolling and updating rows and columns every frame. Sure, the objects were really simple and did nothing but constantly move in a single direction, but all of them were composed by 8 sprites (very few objects will actually have that many), and rendering their sprite definitions does take a lot of time. So I think I'm not that bad on the timing department. Of course I'll try to optmize everything as much as I can.

by on (#31029)
tokumaru wrote:
Really, the ones to blame for slowdown are always the objects/enemies. It'd be tough to not process them every frame though, because if they are not rendered, the action will look very weird with objects missing or not moving. Collisions with the player might go undetected, because it can move very fast. Objects that are drawn to the background are even worse, because those are drawn at the same time as columns and rows of metatiles are, so if a row or a column is updated but the object isn't processed, entire parts of it will be missing!

In that case, would reducing the framerate of the whole game be better during situations with too many objects? That way, even though other processes are burdened with the choppiness, everything would stay "proportional" in framerate.

by on (#31035)
tokumaru wrote:
Some games might alternate tasks (for example, process less enemies if there is background to draw or something like that) to make sure they ramain within the limit of cycles. However, they might choose to introduce slowdown in case a large task needs to be performed, but it's only performed during the next frame, so that the sprite hit is not affected.

Or given that the enemies tend appear in groups of a half-dozen or so, perhaps only give one enemy of the group "think time" in any given frame and use dead reckoning for the rest.

tokumaru wrote:
Now, why do people usually prefer to clip scanlines at the bottom of the screen rather than at the top?

For one thing, it's often easier to mess with the post-render scanline than with the pre-render scanline. The pre-render scanline is responsible for v=t, which allows easy setting of the camera position with PPUSCROLL.

tokumaru wrote:
Another clear advantage of blanking the top instead of the bottom (specially when using 8x16 sprites), is that sprites can can move smoothly at the top, something that leaves only the left side of the screen with sprite issues, and if that really bothers you, just hide the leftmost 8 pixels as the PPU allows it, and you get perfect sprite movement.

The NES picture is drawn about two pixels too far to the right, making the choice to clip on the left even more noticeable.

by on (#31037)
tepples wrote:
For one thing, it's often easier to mess with the post-render scanline than with the pre-render scanline. The pre-render scanline is responsible for v=t, which allows easy setting of the camera position with PPUSCROLL.

Not that it is any hard to prepare the values you write to $2006/$2005 in order to set the position of the camera. I don't remember exactly how I was doing it, but a few commands to shift bits around did the trick. I won't be doing this anymore, though. Besides, the few games I found that clip the top do keep rendering enabled at least at the very start of the frame, so they can set the scroll the usual way.

Quote:
The NES picture is drawn about two pixels too far to the right, making the choice to clip on the left even more noticeable.

I can clearly see this on my TV's, while the rightmost column of tiles is usually cut in half.

by on (#31049)
Quote:
EDIT: Another clear advantage of blanking the top instead of the bottom (specially when using 8x16 sprites), is that sprites can can move smoothly at the top, something that leaves only the left side of the screen with sprite issues, and if that really bothers you, just hide the leftmost 8 pixels as the PPU allows it, and you get perfect sprite movement.

You can also clip sprites proprely by setting 8 transparent highest priority sprites where you want sprites to clip. In fact I guess you have time to switch all sprite banks in, and then all BG banks in next scanlines (since fetches are done one scanline eariler) without getting much glitches. Disabling the screen and hoping for it to scroll correctly when you enable it back is dangerous. You have to make sure you enable it before HBlank if you do this. Also, I have no idea how the scrolling counters behave if BG is off but sprites on. I guess they incrase only if BG is on, but all docs only mention the case where everything is off, or if everything is on.

The screen is right-adjusted on my PAL TV, all lines are visible, but there is no extra border either. I guess maybe the leftmost one or two pixels are hidden, because the 'S' of the 'SCORE' word in Castlevania III, which is in the first column, seems a bit deformed/weird and is almost clipped.

by on (#31174)
Bregalad wrote:
You can also clip sprites proprely by setting 8 transparent highest priority sprites where you want sprites to clip.

Yeah, but wasting sprites seems wrong...

Quote:
In fact I guess you have time to switch all sprite banks in, and then all BG banks in next scanlines (since fetches are done one scanline eariler) without getting much glitches.

This works better when the BG uses 2 2KB banks, because there is time in HBlank to switch in 2 banks, but not 4. In my case anyway, there is no such thing as "sprite banks", because sprites also use tiles from the background side, meaning that some sprites would be visible during that scanline while others wouldn't, and that's just weird.

Quote:
Disabling the screen and hoping for it to scroll correctly when you enable it back is dangerous. You have to make sure you enable it before HBlank if you do this. Also, I have no idea how the scrolling counters behave if BG is off but sprites on. I guess they incrase only if BG is on, but all docs only mention the case where everything is off, or if everything is on.

You are right. I decided to keep it simple and have all rendering enabled from the start and never disable it again. It's all working pretty nicely now:

Everything uses transparent patterns until scanline 14, when the IRQ fires. Then I have both sprites (which are still 8 pixels tall at this time) and background fetch tiles from $1000 (which is divided in 2 2KB banks). This gives enough time to load the 4 1KB banks to $0000 during scanline 15, because no one is using those tiles.

Then I wait until HBlank, where I change the height of the sprites to 16 pixels (so that they are properly evaluated during the next scanline) and have the background tile be fetched from $0000, so the background is already displayed on scanline 16. During scanline 16, the 2 2KB banks are loaded, so sprites are only displayed on scanline 17.

I guess I'm not bothered by the fact that there is a full scanline after the border with no sprites at all, because everything is much more solid now, the time while the border is being displayed is already being used to process the next frame and it works just as fine in PAL mode, because timing is not so critical now. I'm glad with this solution.