seperate AI and sprite drawing/animation routines per object

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

seperate AI and sprite drawing/animation routines per object

Post by psycopathicteen »

I came up with a solution to scheduling animation without compromising sprite flexibility. Instead of just having 1 routine per object slot, it would have 2 routines per object slot. An individual AI routine, and an individual sprite drawing routine. This would be done so that if an object with dynamic animation got delayed, it would be able to run it's sprite drawing routine first without changing the order of the AI. It would also have the flexibility to use whatever types of sprite animation it wants, including the same character holding different weapons interchangeably, or a rocking chandelier made out of moving candle sprites.

Lets say you have 10 objects, and objects #2 and #5 had their animation delayed because of DMA limits. First it would run the AI routines of each object in numeric order, {0,1,2,3,4,5,6,7,8,9} and then run the sprite drawing routines in a different order with #2 and #5 processed first, {2,5,0,1,3,4,6,7,8,9}. Lets say in this frame #2 and #5 are updated now, but now #6 and #9 are delayed. Next frame it runs the AI routines in numeric order, {0,1,2,3,4,5,6,7,8,9}, but it now runs the object drawing routines for objects #6 and #9 first, {6,9,2,5,0,1,3,4,7,8}.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: seperate AI and sprite drawing/animation routines per ob

Post by Drew Sebastino »

psycopathicteen wrote:This would be done so that if an object with dynamic animation got delayed
To be honest, I think I'll just force blank the screen long enough to get all the tile data updated in one frame. I'm not sure how jarring that would be, but I'd rather not go through the extra programming for something that your game should be designed to not let happen.
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: seperate AI and sprite drawing/animation routines per ob

Post by calima »

Coffee used a similar way, separated draw and AI, though no circular buffer to give the missed frames priority. Prio wasn't needed, as nothing animated at 60 fps, so the next frame had enough room in most cases.

As for designing to avoid it, there's only so much DMA time, and you might want more enemies/etc than a fixed max value would allow.
User avatar
HihiDanni
Posts: 186
Joined: Tue Apr 05, 2016 5:25 pm

Re: seperate AI and sprite drawing/animation routines per ob

Post by HihiDanni »

You don't necessarily need separate think and draw functions. Separate states, maybe, but not functions.

My engine used to call separate think and draw functions for each object, but then I realized that this wasn't necessary, so I went with just a think function that may optionally do its own drawing, and as a result I saw a performance boost.
SNES NTSC 2/1/3 1CHIP | serial number UN318588627
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: seperate AI and sprite drawing/animation routines per ob

Post by psycopathicteen »

What do you do to prevent DMA overflow?
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: seperate AI and sprite drawing/animation routines per ob

Post by Oziphantom »

I think that is the wrong layer of abstraction, to solve the DMA issue.

You want to have a DMA system that cues and dispatches DMA requests.

This way you have one function that does the work for what is needed, then adds it to the queue. The DMA system then worries about what it can get done, anything left over gets put at the front of the list. You would probably want to make a priority system, so player always gets DMA'd. Enemies that are close the player get DMA's, but bird flapping wings in background, enemy at the side of the screen, HUD score update etc get pushed down the list, and in some cases just discarded when new data comes in. Thus giving you a LOD system so you can have more onscreen and keep it smooth where the player is looking. You don't want to slow the animation system down in those cases as then the entities state will also lag behind.

Your system is better for managing CPU bound problems to do with Animation rather than DMA bound issues.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: seperate AI and sprite drawing/animation routines per ob

Post by psycopathicteen »

How do you make sure that the OAM matches VRAM so you don't show garbage tiles? I don't understand how this has to do with CPU bound problems.
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: seperate AI and sprite drawing/animation routines per ob

Post by calima »

In Coffee's case, the mapping was fixed. Otherwise you just have to keep state and compare.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: seperate AI and sprite drawing/animation routines per ob

Post by tepples »

Make two frame variables: one for the cel number as seen by the game logic and another for the cel number as seen by the display code. If the engine can't fit the new cel's tiles into this vblank, hold the display cel back for one frame.

I guess the tradeoffs for this sort of thing differ from the NES to the Super NES, though the net effect is the same: an object occasionally has its cel held back for a frame.
  • An NES PPU connected to an 8K RAM on the Game Pak has twice as much VRAM devoted to sprites (4096 bytes) as the sprite system can display at once (64 8x16x2bpp sprites at 32 bytes each total 2048 bytes). But the CPU can transfer only about 128 bytes (four 8x16 sprites) per frame. Loading the next 32x32-pixel cel thus takes two frames. So on the NES, you'd want to double buffer and try to predict each sprite's next cel in order to have it ready in VRAM when needed, with a delay of one or two frames in case the prediction is wrong. Haunted: Halloween '85 does exactly this.
  • The S-PPU reserves 16384 bytes of VRAM for sprite tiles. It can display exactly as much sprite data as VRAM holds (128 16x16x4bpp sprites at 128 bytes each total 16384 bytes), meaning double buffering is less effective. But it can send roughly 5K (40 16x16 sprites) of sprite cel data to VRAM per frame, meaning ten different objects can have an entire 32x32 pixel cel changed at once. So instead of a frame of lag on misprediction, you get lag on too much stuff animating, at which point your collision logic may be running into slowdown anyway.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: seperate AI and sprite drawing/animation routines per ob

Post by psycopathicteen »

I got ninja'ed. So I haven't read what tepples wrote yet.

Okay. I never heard of the game "coffee" before, so I don't know what genre it is. I'm guessing the sprites don't change size too often if they can stay in the same place in VRAM.

I forgot to mention this in my OP, but I still had the idea of making a fake OAM with larger CHR numbers in mind when I made this thread.
viewtopic.php?f=12&t=10957&start=285
Since this code doesn't care about DMA overflow, and has no way of knowing what the "previous frame" was, any "DMA queuing" would have to be done by the objects themselves, even if the objects are taking simplified shortcuts at it.

@Tepples, plus if you're using 32x32 sprites, you can actually have more sprites onscreen than you can fit in VRAM if you have duplicates onscreen.
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: seperate AI and sprite drawing/animation routines per ob

Post by 93143 »

You can also simply change where the OBJ tables are in VRAM between frames, so you can double buffer in blocks of 8 KB, unless you need all 48 KB for BGs and maps.

You can even change where they are during a frame (as long as you do it outside HBlank). This would probably be difficult to deal with in the general case, but it could be useful if you're doing something that results in large quantities of sprite data being in predictable vertical positions, such as faking a second BG layer in Mode 7.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: seperate AI and sprite drawing/animation routines per ob

Post by Oziphantom »

psycopathicteen wrote:How do you make sure that the OAM matches VRAM so you don't show garbage tiles? I don't understand how this has to do with CPU bound problems.
Well if you need to update OAM and Tiles then you would need to make a system that only does the OAM when it does the tiles. If you have a Mirror that gets DMA'd to update all of OAM then you would probably make it update the mirror then do OAM at the end. Since OAM DMA would be a fixed costs it would be easy to budget for.

Basically doing this kind of VRAM updating is like doing a Sprite Multiplexer ;) so you would probably have a sort and time phase out of VBlank so you then have everything sitting ready to go once you hit VBlank.

I'm assuming from your terms that the Animation Update runs code and said code looks at game state, previous state and either starts the tweeining animation, or updates the current animation state. Then works out which sprites need to change and which tiles need to be updated. Thus this is a CPU task. So skipping the animation step would save you CPU rather than just VBlank. At the cost of letting your animation system fall behind the object system. I.e you can have an object that looks to be on the ground by the internal state logic things its in the air. While the VBlank transfer manager I muse upon above just worries about and saves VBlank time. With each entity getting their logic and animation states updated, which gives a Dropped Frame rather than the Lag Frame.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: seperate AI and sprite drawing/animation routines per ob

Post by psycopathicteen »

I'm not talking about delaying the entire animation, just a frame.
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: seperate AI and sprite drawing/animation routines per ob

Post by calima »

Coffee Crisis is a beat'emup for the Genesis. Enemies are indeed fixed size, with bosses and semibosses taking two VRAM slots and normal enemies taking one.
Post Reply