It is currently Mon Dec 18, 2017 3:34 pm

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Sat Aug 06, 2016 3:49 pm 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2433
I have both the animation and metasprite information together, and I wonder if I'm doing it in an unorthodox way.


Top
 Profile  
 
PostPosted: Sat Aug 06, 2016 3:59 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1870
Location: DIGDUG
Lately, I've been working on animated sprites as a series of...
1.relative x position
2.relative y position
3.tile
4.attributes

4 bytes per tile per animation. I would first decide which animation to load, then set a pointer to that group of data.

This may be a bit slow, and uses larger ROM space, but I find it especially flexible for strangely shaped things. (And layered sprites).

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Sat Aug 06, 2016 4:11 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19357
Location: NE Indiana, USA (NTSC)
The sprite engine in The Curse of Possum Hollow stores a metasprite as a list of horizontal strips: relative Y position, relative X position, attributes (palette ID and number of tiles in the strip), and a list of tile numbers. (The sprite engine in Haunted: Halloween '85 is similar, except it stores only the first tile number, with the rest assumed to automatically increment.) Each tile number consists of 1 bit for vertical flip, 1 bit for horizontal flip, 5 bits for the actual tile number, and 1 bit for whether to use the same or the next tile number when the sprite is flipped to face left.

A sprite sheet has a list of pointers to strip lists. A frame can be reused in multiple animations by making multiple pointers point to the same strip list.


Top
 Profile  
 
PostPosted: Sat Aug 06, 2016 6:22 pm 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3166
Location: Nacogdoches, Texas
psycopathicteen wrote:
I have both the animation and metasprite information together, and I wonder if I'm doing it in an unorthodox way.

I don't quite get what you mean. I thought by very nature, they'd be together, although maybe to varying degrees. I'd have it to where the animation table points to the address of a metasprite so that the animation table can be incremented by the same amount every time, regardless of how large the metasprite table is. Plus, this way, the animation routine and the metasprite routine can be separate in that the animation routine finds the metasprite table's address, and then stores it to be loaded later by the metasprite routine.

Although I have my routines that deal with the video hardware for objects (like a vram finder and metasprite routine as they kind of work together, hopefully cg ram finder and a couple others later) I think I'll just about hardcode anything to the object that isn't dealing with video hardware, like collision detection, physics, and animation. I can think of way too many scenarios I want to have that would completely break most peoples routines for the former, and if I wanted to make the routine complicated enough to include all the different scenarios, it would be a slow, complicated mess. For example, I wanted the feature to play an object's animation table at different speeds and even backwards for something like tank tracks, but this is phenomenally more complicated than something like a bullet or explotion would need in terms of animation and, as I said, all these fancy features come at a cost of performance, even if they aren't being used. (you still have to check if they are, which begins to really get slow if you have a bunch of features in the routine and a bunch of objects.)


Top
 Profile  
 
PostPosted: Sat Aug 06, 2016 9:21 pm 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2433
What I do is keep the same metasprite table address for the entire animation, but only change the DMA address. The only exception is flip kicks, where each frame's size varied too much, so I programmed an alternate mode where there was a table of pointers instead of the metasprite data.

It sounds like my original idea is somewhat unconventional. What I'm wondering about, is wouldn't you have to make a gazillion metasprite tables, for sprites that are the same size anyway?


Top
 Profile  
 
PostPosted: Sat Aug 06, 2016 10:12 pm 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3166
Location: Nacogdoches, Texas
psycopathicteen wrote:
wouldn't you have to make a gazillion metasprite tables, for sprites that are the same size anyway?

By same size, do you mean exact same arrangement of sprites? In that case, no, you can reuse the metasprite data as long as the tile numbers aren't actually tied directly to it and are instead from a table or list elsewhere.


Top
 Profile  
 
PostPosted: Sun Aug 07, 2016 9:54 am 
Offline

Joined: Wed May 19, 2010 6:12 pm
Posts: 2433
So you do use a separate register holding the dma address. I wonder if it is possible to only use one registers defining a the animation frame without having to repeat tables. I guess if you want you can organize a table like the following:

word 0: metasprite data address
word 1: DMA address
word 2: DMA bank
word 3: super-long list index

...but that still would be pretty long and repetitive, especially for rotating sprites. I wonder if there is a way to make a repeating macro.


Top
 Profile  
 
PostPosted: Sun Aug 07, 2016 11:12 am 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3166
Location: Nacogdoches, Texas
Well, because I don't actually have an animation engine made (and might not even make one), I'll show you what I do have under each object slot:

Code:
CurrentTiles      .byte 2
RequestedTiles      .byte 2
VramOffset      .byte 2
MetaspriteTableAddress   .byte 2

"CurrentTiles" and "RequestedTiles" don't actually hold the address of the first tile (otherwise, it would be more than two bytes for sure), they hold an offset for these tables:

Code:
TilesInFrameTable:
  .word $0002,$0002

VramLoWordOfFrameTable:
  .word .LOWORD(Test1Tiles),.LOWORD(Test2Tiles)

VramBankByteOfFrameTable:
  .word .BANKBYTE(Test1Tiles),.BANKBYTE(Test2Tiles)

"VramOffset" is generated by the vram engine after looking comparing "RequestedTiles" to "CurrentTiles" and seeing if it's different (and after it actually finds an empty spots in vram to create the linked list) and "MetaspriteTableAddress" is exactly what the name implies. (It's only the loword of an address, but if I need to make it bigger, I will.)

Anyway, each entry in an animation table I'd build would hold a value for "RequestedTiles" and for "MetaspriteTableAddress". That's about it, aside from I might add an extra word for what to do when that part of the list gets reached, like loop back at the beginning, or stop, or whatever. Each entry in the list would be one frame, so there would be many, many entries that are exactly the same. I'm not sure if this is the best option, as I guess you could create a timer for each frame in how long the object should stay on it.


Top
 Profile  
 
PostPosted: Sun Aug 07, 2016 3:26 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10177
Location: Rio de Janeiro - Brazil
I have been experimenting with keeping animation and metasprite data together, mainly to avoid an extra level of indirection, which saves a little bit of time and RAM. I might go back to separating them if I realize I'm wasting too much ROM with repeated metasprite data.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 9 guests


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

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