Jump to content
IGNORED

Smooth scrolling


Asmusr

Recommended Posts

Thank you for all the positive feedback. I see lots of potential for using this technique for games (platform, driving, pinball to name a few ideas), and I hope that some of you will be inspired to make your own projects so we can share ideas and techniques. For now I'm focused on the vertically scrolling, half-bitmap project, which is beginning to look like a game, but I'm still not 100% sure what the objectives of the game are...

Don't worry about the objectives. Simply make a SHMUP ;)

Link to comment
Share on other sites

Aaarrghh! I've discovered that the sprite collision flag is not working at all in half-bitmap mode (with 1 color table and 1 or 3 pattern tables). At least not on my European console. Can anyone confirm this?

 

I begin to understand why so few games are using this mode, attractive as it seems on first glance...

Link to comment
Share on other sites

You might wish to implement a version of The Dreadnaught Factor. DF is a game with a beautiful balance of objectives that must be considered to be successful: nukes, engines, vents, command structures, deck guns, etc. Each one is important to take out to kill each Dreadnaught but in a critical decision path sort of way. Not too many sprites needed: only the gun shots and launched attack ships.

 

Good luck with any game you may end up creating!

Link to comment
Share on other sites

Seems to me to look a lot like Uridium. I thought it look familiar... But couldn't place it, then I saw this: http://futuridium.com/ (which is freaking hard) and then it led me back around:

https://www.google.com/search?q=uridium&client=firefox-a&hs=lIM&rls=org.mozilla:en-US:official&tbm=isch&tbo=u&source=univ&sa=X&ei=5J_oUdrJEKf-iQKNzIHQCA&ved=0CEEQsAQ&biw=1553&bih=794

Link to comment
Share on other sites

Aaarrghh! I've discovered that the sprite collision flag is not working at all in half-bitmap mode (with 1 color table and 1 or 3 pattern tables). At least not on my European console. Can anyone confirm this?

 

I begin to understand why so few games are using this mode, attractive as it seems on first glance...

The collision flag is not to be trusted. In real hardware sometimes it works and sometimes it doesn't.

 

Also it behaves in strange ways in emulators.

Link to comment
Share on other sites

Aaarrghh! I've discovered that the sprite collision flag is not working at all in half-bitmap mode (with 1 color table and 1 or 3 pattern tables). At least not on my European console. Can anyone confirm this?

 

Hmm, that does not make sense. The sprite collision is detected in the output pixel mux, and only sprites being disabled due to the mode should prevent the flag from being set. If you can see the sprites, the collision bit should be set accordingly. Unless the masking bits that come in to play with the half-bitmap mode somehow interfere with the setting of the collision flip-flop. Text mode inhibits sprites, but it is unclear at what "level". We know the reading of sprite data does not happen, but I wonder if the sprite shift registers are still active?

 

The collision flag is not to be trusted. In real hardware sometimes it works and sometimes it doesn't.

 

Also it behaves in strange ways in emulators.

 

That is a pretty vague statement. Can you provide a reproducible example of why the hardware collision flag should not be trusted and acts unpredictably? I have found that it works as documented, and software is usually to blame for any problems in the reliability.

 

As for emulators, sure, they will have a hard time with it because they run on a multitasking OS that controls most of the timing in a system, but most of them get it pretty close.

 

Link to comment
Share on other sites

That is a pretty vague statement. Can you provide a reproducible example of why the hardware collision flag should not be trusted and acts unpredictably? I have found that it works as documented, and software is usually to blame for any problems in the reliability.

I'm thinking that you're right, maybe it was my software as I was using the flag in polling mode... anyway I ceased to use it since a long time.

Link to comment
Share on other sites

Polling the VDP status to get the collision flag is fine, as long as you disabled the system ISR. Otherwise *sometimes* the ISR will trigger before your polling loop, and the ISR will also read the VDP status registers and subsequently clear the collision flag. That would make it *very* unpredictable for your code.

Edited by matthew180
  • Like 2
Link to comment
Share on other sites

Also, what maybe everyone had to learn sooner or later is that sprite auto-motion and collision detection don't really go together. The reason is that sprite auto-motion is triggered 50 or 60 times a second, so this means if you want your sprite to visit every column on a 256 column screen it would need 4-5 seconds to go from one side to the other. That means a faster sprite will have to skip over screen locations.

 

As I said, only if you use auto-motion.

Edited by mizapf
Link to comment
Share on other sites

As for emulators, sure, they will have a hard time with it because they run on a multitasking OS that controls most of the timing in a system, but most of them get it pretty close.

 

There's no reason for emulators to find the collision flag any harder just because of the operating system behind it... that would imply some sort of real time restriction that doesn't happen inside an emulator - it draws the pixel when it draws the pixel, and no other operations have happened in the meantime, even in Classic99 where the timing is detached. ;)

 

The OS really only should affect the interaction between emulator time and real time. For example, Classic99 handles real time synchronization by bursting - it sleeps for a fixed amount of time (which due to the OS is only an approximation). When it wakes up, it runs the system at full speed to "catch up" emulator time with real time, then goes back to sleep. (Classic99 pulls the due-date all-nighter. ;) ) By keeping the sleep periods short (Classic99 aims for 16ms to get a 60hz frame rate, the real OS will vary some as to how possible this is), the illusion of real time is obtained. But if you tried to execute real world real time events during that burst (such as cassette interaction, for instance), it wouldn't work, because the emulator events will be all bunched together. (In retrospect.. 16ms is a really dumb time and I will look at that. Windows normally runs on either a 15ms or 10ms tick (depends on the version), so 16ms will usually fire as 20 or 30ms, which is a lot less accurate than I liked. Mind you.. that's all changing soon anyway, but it may explain the visible jerkiness some systems have reported...)

 

The best way to get real time performance on a non-real time OS is polling continuously at a high priority - the OS will give you most of the CPU and you can hit events with a fairly high degree of accuracy (usually microseconds) as long as nothing more important is running, but this runs the CPU at 100% and people don't like that. ;)

 

Curious what timing systems other emulators have used?

Link to comment
Share on other sites

Hmm, that does not make sense. The sprite collision is detected in the output pixel mux, and only sprites being disabled due to the mode should prevent the flag from being set. If you can see the sprites, the collision bit should be set accordingly. Unless the masking bits that come in to play with the half-bitmap mode somehow interfere with the setting of the collision flip-flop. Text mode inhibits sprites, but it is unclear at what "level". We know the reading of sprite data does not happen, but I wonder if the sprite shift registers are still active?

 

What I found was that the same code that worked fine on a console with the F18A did not detect any sprite collisions on my other unmodified EU console. I have interrupts turned off. If you say it doesn't make sense I will try again.

Link to comment
Share on other sites

Curious what timing systems other emulators have used?

 

This is similar to how MESS is doing it. We don't just use one timer but any timer that is currently active. So we get varying periods of time between any two timer firings. The CPU speed is then translated into a number of cycles that can be performed until the next timer event (which is also done for any executing device, i.e. devices with own activity, so you can easily handle co-processors). Creating a wait state means to decrease the number of available cycles without doing anything, so you have less activity in a time period.

Link to comment
Share on other sites

What I found was that the same code that worked fine on a console with the F18A did not detect any sprite collisions on my other unmodified EU console. I have interrupts turned off. If you say it doesn't make sense I will try again.

 

Note1: The F18A has a sprite collision bug in the 1.3V of the firmware. It will detect collisions of off-screen sprites when it should not. The proper functionality is that only sprites with pixels (of any color, including transparent) that would appear on the screen will cause the collision flag to be set. The bug is corrected in the V1.4 which you may have depending on when you purchased your F18A, or if you have a JTAG cable and did an update. I'm (slowly) working on the software-only update.

 

Note2: The F18A may not exhibit some obscure and undocumented functionality. For example, the sprite shadowing problem does not exist on the F18A.

 

The real VDP detects the collision in the output color mux where any pixels from the sprite shift registers determine the collision. I suppose there could be some strange side affect of the mode bits in the color mux, but until the 9918A is decapped I don't know.

 

 

Link to comment
Share on other sites

Also, what maybe everyone had to learn sooner or later is that sprite auto-motion and collision detection don't really go together. The reason is that sprite auto-motion is triggered 50 or 60 times a second, so this means if you want your sprite to visit every column on a 256 column screen it would need 4-5 seconds to go from one side to the other. That means a faster sprite will have to skip over screen locations.

 

As I said, only if you use auto-motion.

 

Even XB suffers a huge HIT for using Automotion in Sprites. We have all seen the missed hits when the speeds are very high.

Link to comment
Share on other sites

Note1: The F18A has a sprite collision bug in the 1.3V of the firmware. It will detect collisions of off-screen sprites when it should not. The proper functionality is that only sprites with pixels (of any color, including transparent) that would appear on the screen will cause the collision flag to be set. The bug is corrected in the V1.4 which you may have depending on when you purchased your F18A, or if you have a JTAG cable and did an update. I'm (slowly) working on the software-only update.

 

It looks like I was fooled by this bug and the coincidence flag is working after all. My code was polling the status too infrequently, while on the F18A the flag was on most of the time (because of off-screen sprites, I guess). However, based on the tests of my current project, it seems that the reliability of this flag depends heavily on the environment: Classic99, MESS, F18A, TMS9929A. In Classic99 the coincidence always works while on my EU console it hardly ever works. MESS/F18A are in between. It has probably something to do with my code, but there's still a huge difference to explain.

 

If if don't rely on the flag, my collision detection works perfectly, but it takes valuable clock cycles to execute for every frame, and it seems a shame not to use this hardware provided feature. Are there any tricks to reliably reading the coincidence flag, except of course to read it after every vsync? Should you, for instance, sample the flag over longer periods?

Link to comment
Share on other sites

The collision flip-flop in the VDP, used to indicate the collision flag in the status byte, is latched in the color mux when the collision happens. This is how some software detects a certain scan line for mode changes and other effects. If you sample the VDP status in a very tight loop, i.e. not during VSYNC, then you can possibly detect multiple collisions in a single frame.

 

Like all the other bits that make up the status byte, their respective internal flip-flops are only cleared when you read the status byte. If you wait for VSYNC to read the status, then the collision flag will represent any collision of any two sprites during that frame.

 

However, until the 9918A is decapped we really won't know for sure the total impact of the mask-bits when using undocumented modes such as half-bitmap. I can't explain why your EU consoles would not set the collision flag correctly.

 

 

Link to comment
Share on other sites

 

 

It looks like I was fooled by this bug and the coincidence flag is working after all. My code was polling the status too infrequently, while on the F18A the flag was on most of the time (because of off-screen sprites, I guess). However, based on the tests of my current project, it seems that the reliability of this flag depends heavily on the environment: Classic99, MESS, F18A, TMS9929A. In Classic99 the coincidence always works while on my EU console it hardly ever works. MESS/F18A are in between. It has probably something to do with my code, but there's still a huge difference to explain.

 

If if don't rely on the flag, my collision detection works perfectly, but it takes valuable clock cycles to execute for every frame, and it seems a shame not to use this hardware provided feature. Are there any tricks to reliably reading the coincidence flag, except of course to read it after every vsync? Should you, for instance, sample the flag over longer periods?

Link to comment
Share on other sites

Perfect checking has several factors involved.

First, as has been mentioned, turn off the console Isr with a limi 0 and poll the status register yourself.

 

Make sure you update your sprite info all at once and as soon as the vtrace has concluded.

 

Keep sprites away from the very top of the screen as an added safety.

 

Be careful on the vdp polling that you do not read the register over and over in quick succession. Read it and if the coincidence bit is set then save it. If the interrup Bit is not set then kill some time before you check it again. Otherwise you will miss interrupt hits.

Link to comment
Share on other sites

Almost I forget it.

 

Over each sprite not used put the Y-coordinate equal to $D1, this way the VDP will not take it in account.

 

I believe the value is D0h, not D1h. Also, you only need that value as the Y-coordinate of the lowest-numbered, undefined sprite. This will cause all higher-numbered sprites to be undefined, as well.

 

...lee

  • Like 2
Link to comment
Share on other sites

"Undefined" might not be the best way to describe this. When the VDP encounters a sprite with a Y value of >D0, it stops processing sprites for display, i.e. the sprite with the Y value of >D0 and any higher numbered sprites will not be processed or displayed and can not cause any collisions. However, the sprite data in the Sprite Attribute Table can still be valid and defined, but it will simply be unused.

Link to comment
Share on other sites

"Undefined" might not be the best way to describe this. When the VDP encounters a sprite with a Y value of >D0, it stops processing sprites for display, i.e. the sprite with the Y value of >D0 and any higher numbered sprites will not be processed or displayed and can not cause any collisions. However, the sprite data in the Sprite Attribute Table can still be valid and defined, but it will simply be unused.

 

Yeah, I understand that. I was just quoting the E/A manual to avoid confusion; but, your explanation is decidedly better! This, of course, is not the first time TI's choice of words was not the best.

 

...lee

Link to comment
Share on other sites

There's no reason for emulators to find the collision flag any harder just because of the operating system behind it... that would imply some sort of real time restriction that doesn't happen inside an emulator - it draws the pixel when it draws the pixel, and no other operations have happened in the meantime, even in Classic99 where the timing is detached. ;)

 

I found there's a significant different between how the collision flag works on Classic99 and MESS. When you poll the status register on Classic99 you don't have to save the collision flag unless the interrupt flag is also set. On MESS you must save the flag or you will fail to detect most collisions. Looks like Classic99 is caching the flag for the following vsync period and MESS doesn't. I guess MESS works more like the real hardware?

Link to comment
Share on other sites

I do have a >D0 at the end of my SAT, but I use a y value of >C0 to place sprites temporarily outside the visible screen. Will coincidence be detected between these sprites?

 

Yes—for sprites with lower numbers than the first "undefined" sprite, i.e., the first sprite with D0h for its Y-location. See E/A manual, p. 269.

 

...lee

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...